forked from Mirrors/sngrep
IPv6 Support. Initial Approach. #38
* Added --enable-ipv6 option to configure script * All IP addresses are trimmet to 15 characters until UI can handle them properly * IPv6 lookup is enabled
This commit is contained in:
parent
cdc38bd79f
commit
ff9eb99571
18
configure.ac
18
configure.ac
|
@ -144,6 +144,23 @@ AS_IF([test "x$WITH_PCRE" == "xyes"], [
|
|||
AC_DEFINE([WITH_PCRE],[],[Compile With Perl Compatible regular expressions support])
|
||||
], [])
|
||||
|
||||
####
|
||||
#### IPv6 Support
|
||||
####
|
||||
AC_ARG_ENABLE([ipv6],
|
||||
AS_HELP_STRING([--enable-ipv6], [Enable IPv6 Support]),
|
||||
[AC_SUBST(WITH_IPV6, $enableval)],
|
||||
[AC_SUBST(WITH_IPV6, no)]
|
||||
)
|
||||
|
||||
AS_IF([test "x$WITH_IPV6" == "xyes"], [
|
||||
AC_CHECK_HEADER([netinet/ip6.h], [], [
|
||||
AC_MSG_ERROR([ You dont seem to have ipv6 support (no ip6.h found).])
|
||||
])
|
||||
AC_DEFINE([WITH_IPV6],[],[Compile With IPv6 support])
|
||||
], [])
|
||||
|
||||
|
||||
# Conditional Source inclusion
|
||||
AM_CONDITIONAL([WITH_OPENSSL], [test "x$WITH_OPENSSL" == "xyes"])
|
||||
|
||||
|
@ -179,6 +196,7 @@ AC_MSG_NOTICE( ====================================================== )
|
|||
AC_MSG_NOTICE( OpenSSL Support : ${WITH_OPENSSL} )
|
||||
AC_MSG_NOTICE( Unicode Support : ${UNICODE} )
|
||||
AC_MSG_NOTICE( Perl Expressions Support : ${WITH_PCRE} )
|
||||
AC_MSG_NOTICE( IPv6 Support : ${WITH_IPV6} )
|
||||
AC_MSG_NOTICE( ====================================================== )
|
||||
AC_MSG_NOTICE
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@
|
|||
#include "sip.h"
|
||||
#include "option.h"
|
||||
#include "ui_manager.h"
|
||||
#ifdef WITH_IPV6
|
||||
#include <netinet/ip6.h>
|
||||
#endif
|
||||
|
||||
// Capture information
|
||||
capture_info_t capinfo = { 0 };
|
||||
|
@ -122,9 +125,21 @@ parse_packet(u_char *mode, const struct pcap_pkthdr *header, const u_char *packe
|
|||
// Datalink Header size
|
||||
int size_link;
|
||||
// IP header data
|
||||
struct nread_ip *ip;
|
||||
struct ip *ip4;
|
||||
#ifdef WITH_IPV6
|
||||
// IPv6 header data
|
||||
struct ip6_hdr *ip6;
|
||||
#endif
|
||||
// IP protocol
|
||||
uint8_t ip_proto;
|
||||
// IP segment length
|
||||
uint32_t ip_len;
|
||||
// IP header size
|
||||
int size_ip;
|
||||
//! Source Address
|
||||
char ip_src[50];
|
||||
//! Destination Address
|
||||
char ip_dst[50];
|
||||
// UDP header data
|
||||
struct nread_udp *udp;
|
||||
// TCP header data
|
||||
|
@ -157,11 +172,34 @@ parse_packet(u_char *mode, const struct pcap_pkthdr *header, const u_char *packe
|
|||
size_link = datalink_size(capinfo.link);
|
||||
|
||||
// Get IP header
|
||||
ip = (struct nread_ip*) (packet + size_link);
|
||||
size_ip = IP_HL(ip) * 4;
|
||||
ip4 = (struct ip*) (packet + size_link);
|
||||
|
||||
#ifdef WITH_IPV6
|
||||
// Get IPv6 header
|
||||
ip6 = (struct ip6_hdr*)(packet + size_link);
|
||||
#endif
|
||||
|
||||
switch(ip4->ip_v) {
|
||||
case 4:
|
||||
size_ip = ip4->ip_hl * 4;
|
||||
ip_proto = ip4->ip_p;
|
||||
ip_len = ntohs(ip4->ip_len);
|
||||
strncpy(ip_src, inet_ntoa(ip4->ip_src), INET_ADDRSTRLEN);
|
||||
strncpy(ip_dst, inet_ntoa(ip4->ip_dst), INET_ADDRSTRLEN);
|
||||
break;
|
||||
#ifdef WITH_IPV6
|
||||
case 6:
|
||||
size_ip = sizeof(struct ip6_hdr);
|
||||
ip_proto = ip6->ip6_nxt;
|
||||
ip_len = ntohs(ip6->ip6_plen);
|
||||
inet_ntop(AF_INET6, &ip6->ip6_src, ip_src, INET6_ADDRSTRLEN);
|
||||
inet_ntop(AF_INET6, &ip6->ip6_dst, ip_dst, INET6_ADDRSTRLEN);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Only interested in UDP packets
|
||||
if (ip->ip_p == IPPROTO_UDP) {
|
||||
if (ip_proto == IPPROTO_UDP) {
|
||||
// Set transport UDP
|
||||
transport = 0;
|
||||
|
||||
|
@ -184,7 +222,7 @@ parse_packet(u_char *mode, const struct pcap_pkthdr *header, const u_char *packe
|
|||
// Total packet size
|
||||
size_packet = size_link + size_ip + SIZE_UDP + size_payload;
|
||||
|
||||
} else if (ip->ip_p == IPPROTO_TCP) {
|
||||
} else if (ip_proto == IPPROTO_TCP) {
|
||||
// Set transport TCP
|
||||
transport = 1;
|
||||
|
||||
|
@ -194,7 +232,7 @@ parse_packet(u_char *mode, const struct pcap_pkthdr *header, const u_char *packe
|
|||
dport = tcp->th_dport;
|
||||
|
||||
// We're only interested in packets with payload
|
||||
size_payload = ntohs(ip->ip_len) - (size_ip + SIZE_TCP);
|
||||
size_payload = ip_len - (size_ip + SIZE_TCP);
|
||||
if (size_payload > 0) {
|
||||
// Get packet payload
|
||||
msg_payload = malloc(size_payload + 1);
|
||||
|
@ -233,7 +271,7 @@ parse_packet(u_char *mode, const struct pcap_pkthdr *header, const u_char *packe
|
|||
return;
|
||||
|
||||
// Parse this header and payload
|
||||
msg = sip_load_message(header->ts, ip->ip_src, sport, ip->ip_dst, dport, msg_payload);
|
||||
msg = sip_load_message(header->ts, ip_src, sport, ip_dst, dport, msg_payload);
|
||||
free(msg_payload);
|
||||
|
||||
// This is not a sip message, Bye!
|
||||
|
@ -443,16 +481,12 @@ dump_close(pcap_dumper_t *pd)
|
|||
}
|
||||
|
||||
const char *
|
||||
lookup_hostname(struct in_addr *addr)
|
||||
lookup_hostname(const char *address)
|
||||
{
|
||||
int i;
|
||||
int hostlen;
|
||||
struct hostent *host;
|
||||
char *hostname;
|
||||
char *address;
|
||||
|
||||
// Initialize values
|
||||
address = (char *) inet_ntoa(*addr);
|
||||
const char *hostname;
|
||||
|
||||
// Check if we have already tryied resolve this address
|
||||
for (i = 0; i < capinfo.dnscache.count; i++) {
|
||||
|
@ -462,7 +496,7 @@ lookup_hostname(struct in_addr *addr)
|
|||
}
|
||||
|
||||
// Lookup this addres
|
||||
host = gethostbyaddr(addr, 4, AF_INET);
|
||||
host = gethostbyaddr(address, 4, AF_INET);
|
||||
if (!host) {
|
||||
hostname = address;
|
||||
} else {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <time.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
//! Capture modes
|
||||
enum capture_status {
|
||||
|
@ -103,41 +104,6 @@ struct capture_info {
|
|||
//! TCP headers size
|
||||
#define SIZE_TCP TH_OFF(tcp)*4
|
||||
|
||||
/**
|
||||
* @brief IP data structure
|
||||
*/
|
||||
struct nread_ip {
|
||||
//! header length, version
|
||||
u_int8_t ip_vhl;
|
||||
//! type of service
|
||||
u_int8_t ip_tos;
|
||||
//! total length
|
||||
u_int16_t ip_len;
|
||||
//! identification
|
||||
u_int16_t ip_id;
|
||||
//! fragment offset field
|
||||
u_int16_t ip_off;
|
||||
//! reserved fragment flag
|
||||
#define IP_RF 0x8000
|
||||
//! dont fragment flag
|
||||
#define IP_DF 0x4000
|
||||
//! more fragments flag
|
||||
#define IP_MF 0x2000
|
||||
//! mask for fragmenting bits
|
||||
#define IP_OFFMASK 0x1fff
|
||||
//! time to live
|
||||
u_int8_t ip_ttl;
|
||||
//! protocol
|
||||
u_int8_t ip_p;
|
||||
//! checksum
|
||||
u_int16_t ip_sum;
|
||||
//! source and dest addresses
|
||||
struct in_addr ip_src, ip_dst;
|
||||
};
|
||||
|
||||
#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)
|
||||
#define IP_V(ip) (((ip)->ip_vhl) >> 4)
|
||||
|
||||
/**
|
||||
* @brief UDP data structure
|
||||
*/
|
||||
|
@ -350,6 +316,6 @@ dump_close(pcap_dumper_t *pd);
|
|||
* original address to avoid lookup again the same address.
|
||||
*/
|
||||
const char *
|
||||
lookup_hostname(struct in_addr *addr);
|
||||
lookup_hostname(const char *address);
|
||||
|
||||
#endif
|
||||
|
|
33
src/sip.c
33
src/sip.c
|
@ -205,7 +205,7 @@ sip_get_callid(const char* payload)
|
|||
}
|
||||
|
||||
sip_msg_t *
|
||||
sip_load_message(struct timeval tv, struct in_addr src, u_short sport, struct in_addr dst,
|
||||
sip_load_message(struct timeval tv, const char *src, u_short sport, const char* dst,
|
||||
u_short dport, u_char *payload)
|
||||
{
|
||||
sip_msg_t *msg;
|
||||
|
@ -231,22 +231,24 @@ sip_load_message(struct timeval tv, struct in_addr src, u_short sport, struct in
|
|||
|
||||
// Fill message data
|
||||
msg->ts = tv;
|
||||
msg->src = src;
|
||||
msg->sport = sport;
|
||||
msg->dst = dst;
|
||||
msg->dport = dport;
|
||||
|
||||
// Store sorce and destination address
|
||||
strcpy(msg->src, (strlen(src) > 15)? src + strlen(src) - 15 : src);
|
||||
strcpy(msg->dst, (strlen(dst) > 15)? dst + strlen(dst) - 15 : dst);
|
||||
|
||||
// Set Source and Destination attributes
|
||||
msg_set_attribute(msg, SIP_ATTR_SRC, "%s:%u", inet_ntoa(src), htons(sport));
|
||||
msg_set_attribute(msg, SIP_ATTR_DST, "%s:%u", inet_ntoa(dst), htons(dport));
|
||||
msg_set_attribute(msg, SIP_ATTR_SRC, "%s:%u", msg->src, htons(sport));
|
||||
msg_set_attribute(msg, SIP_ATTR_DST, "%s:%u", msg->dst, htons(dport));
|
||||
|
||||
// Set Source and Destination lookpued hosts
|
||||
if (is_option_enabled("capture.lookup")) {
|
||||
msg_set_attribute(msg, SIP_ATTR_SRC_HOST, "%.15s:%u", lookup_hostname(&src), htons(sport));
|
||||
msg_set_attribute(msg, SIP_ATTR_DST_HOST, "%.15s:%u", lookup_hostname(&dst), htons(dport));
|
||||
msg_set_attribute(msg, SIP_ATTR_SRC_HOST, "%.15s:%u", lookup_hostname(msg->src), htons(sport));
|
||||
msg_set_attribute(msg, SIP_ATTR_DST_HOST, "%.15s:%u", lookup_hostname(msg->dst), htons(dport));
|
||||
}
|
||||
msg_set_attribute(msg, SIP_ATTR_SRC_HOST, "%s:%u", inet_ntoa(src), htons(sport));
|
||||
msg_set_attribute(msg, SIP_ATTR_DST_HOST, "%s:%u", inet_ntoa(dst), htons(dport));
|
||||
msg_set_attribute(msg, SIP_ATTR_SRC_HOST, "%s:%u", msg->src, htons(sport));
|
||||
msg_set_attribute(msg, SIP_ATTR_DST_HOST, "%s:%u", msg->dst, htons(dport));
|
||||
|
||||
// Set message Date attribute
|
||||
time_t t = (time_t) msg->ts.tv_sec;
|
||||
|
@ -620,7 +622,10 @@ msg_parse_payload(sip_msg_t *msg, const char *payload)
|
|||
continue;
|
||||
}
|
||||
if (sscanf(pch, "c=%*s %*s %s", value) == 1) {
|
||||
msg_set_attribute(msg, SIP_ATTR_SDP_ADDRESS, value);
|
||||
if (strlen(value) > 15)
|
||||
msg_set_attribute(msg, SIP_ATTR_SDP_ADDRESS, value + strlen(value) - 15);
|
||||
else
|
||||
msg_set_attribute(msg, SIP_ATTR_SDP_ADDRESS, value);
|
||||
continue;
|
||||
}
|
||||
if (sscanf(pch, "m=%*s %s", value) == 1) {
|
||||
|
@ -664,11 +669,11 @@ msg_get_header(sip_msg_t *msg, char *out)
|
|||
// We dont use Message attributes here because it contains truncated data
|
||||
// This should not overload too much as all results should be already cached
|
||||
if (is_option_enabled("capture.lookup") && is_option_enabled("sngrep.displayhost")) {
|
||||
sprintf(from_addr, "%s:%u", lookup_hostname(&msg->src), htons(msg->sport));
|
||||
sprintf(to_addr, "%s:%u", lookup_hostname(&msg->dst), htons(msg->dport));
|
||||
sprintf(from_addr, "%s:%u", lookup_hostname(msg->src), htons(msg->sport));
|
||||
sprintf(to_addr, "%s:%u", lookup_hostname(msg->dst), htons(msg->dport));
|
||||
} else {
|
||||
sprintf(from_addr, "%s:%u", inet_ntoa(msg->src), htons(msg->sport));
|
||||
sprintf(to_addr, "%s:%u", inet_ntoa(msg->dst), htons(msg->dport));
|
||||
sprintf(from_addr, "%s:%u", msg->src, htons(msg->sport));
|
||||
sprintf(to_addr, "%s:%u", msg->dst, htons(msg->dport));
|
||||
}
|
||||
|
||||
// Get msg header
|
||||
|
|
|
@ -69,11 +69,11 @@ struct sip_msg {
|
|||
//! Timestamp
|
||||
struct timeval ts;
|
||||
//! Source address
|
||||
struct in_addr src;
|
||||
char src[50];
|
||||
//! Source port
|
||||
u_short sport;
|
||||
//! Destination address
|
||||
struct in_addr dst;
|
||||
char dst[50];
|
||||
//! Destination port
|
||||
u_short dport;
|
||||
//! Temporal payload data before being parsed
|
||||
|
@ -238,7 +238,7 @@ sip_get_callid(const char* payload);
|
|||
* @return a SIP msg structure pointer
|
||||
*/
|
||||
sip_msg_t *
|
||||
sip_load_message(struct timeval tv, struct in_addr src, u_short sport, struct in_addr dst,
|
||||
sip_load_message(struct timeval tv, const char *src, u_short sport, const char *dst,
|
||||
u_short dport, u_char *payload);
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue