diff --git a/configure.ac b/configure.ac index cd8b8f1..ddb157d 100644 --- a/configure.ac +++ b/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 diff --git a/src/capture.c b/src/capture.c index bbde0fa..7dce293 100644 --- a/src/capture.c +++ b/src/capture.c @@ -39,6 +39,9 @@ #include "sip.h" #include "option.h" #include "ui_manager.h" +#ifdef WITH_IPV6 +#include +#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 { diff --git a/src/capture.h b/src/capture.h index 9fa4cac..72de4a3 100644 --- a/src/capture.h +++ b/src/capture.h @@ -39,6 +39,7 @@ #include #include #include +#include //! 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 diff --git a/src/sip.c b/src/sip.c index 43fbf1a..66a0d41 100644 --- a/src/sip.c +++ b/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 diff --git a/src/sip.h b/src/sip.h index 22c1a3a..0823898 100644 --- a/src/sip.h +++ b/src/sip.h @@ -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); /**