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:
Kaian 2015-03-09 19:23:50 +01:00
parent cdc38bd79f
commit ff9eb99571
5 changed files with 90 additions and 67 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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

View File

@ -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);
/**