45 #include <netinet/ip.h>
46 #include <netinet/ip6.h>
47 #include <netinet/ether.h>
52 #include <sys/types.h>
54 #include <openssl/md5.h>
56 #include <flowmonexp/plugin_input.h>
84 # include <byteswap.h>
85 # if __BYTE_ORDER == __LITTLE_ENDIAN
86 # define le32toh(x) (x)
88 # define le32toh(x) bswap_32(x)
92 #ifndef PROCESS_PLUGIN
99 typedef struct ip6tun_input_private_struct {
107 int (*packet_getter) (
unsigned char**, packet_info_t*,
struct ip6tun_input_private_struct*);
108 int (*shutdown) (
struct ip6tun_input_private_struct*);
110 unsigned char *packet_data;
111 unsigned int packet_data_offset;
112 unsigned int packet_length;
142 static unsigned int ip6tun_packet_data_offset;
143 static unsigned char *ip6tun_packet_data;
145 static plugin_desc_t ip6tun_input_plugin_desc = {
148 "\nInput plugin processing tunneled IPv6 traffic\
149 \n One of input parameters (mandatory)\
150 \n\tpcap_if=interface network interface using pcap"
151 "\n\t id=value set interface ID (default = 0)"
152 "\n\tpcap_file=file pcap file using pcap"
153 "\n\t id=value set interface ID (default = 0)"
155 "\n\tsnf=snf_interface snf network interface"
156 "\n\t id=value set interface ID (default = 0)"
159 "\n\trawnetcap=interface network interface using rawnetcap"
160 "\n\t id=value set interface ID (default = 0)"
163 "\n\thanic=mask bitmask of DMA channels"
164 "\n\t card=value COMBO card to use (0-9), default 0"
165 "\n\t id=value common interface ID for all input interfaces, set automatically by default"
179 return (&ip6tun_input_plugin_desc);
251 void value_fill_srcaddr6 (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
256 record_universal_get (dst, &(ip6tun_record->
l3.addr.ipv6.src), 0, 16, len, 0);
267 void value_fill_dstaddr6 (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
272 record_universal_get (dst, &(ip6tun_record->
l3.addr.ipv6.dst), 0, 16, len, 0);
283 void value_fill_srcport (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
288 record_universal_get (dst, &(ip6tun_record->
l4.src_port), 0, sizeof (uint16_t), len, 0);
304 record_universal_get (dst, &(ip6tun_record->
l4.icmp_type_code), 0, sizeof (uint16_t), len, 0);
315 void value_fill_dstport (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
320 record_universal_get (dst, &(ip6tun_record->
l4.dst_port), 0, sizeof (uint16_t), len, 0);
336 record_universal_get (dst, &(ip6tun_record->
l4.tcp_flags), 0, sizeof (uint8_t), len, 0);
352 record_universal_get (dst, &(ip6tun_record->
teredo.
headers), 0, sizeof (uint8_t), len, 0);
368 record_universal_get (dst, &(ip6tun_record->
teredo.
trailers), 0, sizeof (uint8_t), len, 0);
379 void value_fill_ttl_hop (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
384 record_universal_get (dst, &(ip6tun_record->
ttl_hop), 0, sizeof (uint8_t), len, 0);
395 void value_fill_hop (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
400 record_universal_get (dst, &(ip6tun_record->
hop), 0, sizeof (uint8_t), len, 0);
416 record_universal_get (dst, &(ip6tun_record->
l4.protocol), 0, sizeof (uint8_t), len, 0);
427 void value_fill_mechnism (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
432 record_universal_get (dst, &(ip6tun_record->
mechanism), 0, sizeof (uint8_t), len, 0);
444 void value_fill_geoip_ip6tun_src (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
449 record_universal_get (dst, &(ip6tun_record->geoip.ip6tun_src), 0, sizeof (
char) * COUNTRY_CODE_LEN, len, 0);
460 void value_fill_geoip_ip6tun_dst (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
465 record_universal_get (dst, &(ip6tun_record->geoip.ip6tun_dst), 0, sizeof (
char) * COUNTRY_CODE_LEN, len, 0);
476 void value_fill_geoip_regular_src (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
481 record_universal_get (dst, &(ip6tun_record->geoip.regular_src), 0, sizeof (
char) * COUNTRY_CODE_LEN, len, 0);
492 void value_fill_geoip_regular_dst (
void *
self, flow_record_t *record,
void *dst,
int len,
int to_network_byte_order)
497 record_universal_get (dst, &(ip6tun_record->geoip.regular_dst), 0, sizeof (
char) * COUNTRY_CODE_LEN, len, 0);
508 int validity_geoip_regular (
void *
self, flow_record_t *record)
528 int validity_geoip_ip6tun (
void *
self, flow_record_t *record)
750 int value_length_geoip (
void *
self, flow_record_t *record)
752 return (
sizeof(
char) * COUNTRY_CODE_LEN);
766 return (
sizeof(uint8_t));
779 return (
sizeof(uint8_t));
792 return (
sizeof(uint8_t));
805 return (
sizeof(uint8_t));
818 return (
sizeof(uint16_t));
831 return (
sizeof(uint8_t));
844 return (
sizeof(uint16_t));
857 return (
sizeof (ipv6_addr_t));
887 getter_add (getter_list,
"TUN_SRC_COUNTRY", 4, plugin_private, &validity_geoip_ip6tun, &value_length_geoip, &value_fill_geoip_ip6tun_src);
888 getter_add (getter_list,
"TUN_DST_COUNTRY", 4, plugin_private, &validity_geoip_ip6tun, &value_length_geoip, &value_fill_geoip_ip6tun_dst);
890 getter_add (getter_list,
"SRC_COUNTRY", 4, plugin_private, &validity_geoip_regular, &value_length_geoip, &value_fill_geoip_regular_src);
891 getter_add (getter_list,
"DST_COUNTRY", 4, plugin_private, &validity_geoip_regular, &value_length_geoip, &value_fill_geoip_regular_dst);
907 char errbuf[PCAP_ERRBUF_SIZE];
909 plugin_private->pcap_file = pcap_open_offline (source, errbuf);
911 if (plugin_private->pcap_file == NULL) {
927 char errbuf[PCAP_ERRBUF_SIZE];
929 plugin_private->pcap_if = pcap_open_live (source,
PCAP_SIZE, 1, 0, errbuf);
931 if (plugin_private->pcap_if == NULL) {
948 unsigned int rx = 0xffff, tx = 0;
954 if ((plugin_private->sze = szedata_open(plugin_private->card)) == NULL) {
955 fprintf(stderr,
"IP6TUN: szedata_open failed\n");
956 return (EXIT_FAILURE);
960 if (szedata_subscribe3(plugin_private->sze, &rx, &tx)) {
961 fprintf(stderr,
"IP6TUN: szedata subscribe failed\n");
962 return (EXIT_FAILURE);
966 if(szedata_start(plugin_private->sze)) {
967 fprintf(stderr,
"IP6TUN: szedata start failed\n");
968 return (EXIT_FAILURE);
976 szedata_close(plugin_private->sze);
1007 return EXIT_FAILURE;
1013 return EXIT_SUCCESS;
1026 struct pcap_pkthdr hdr;
1028 *buf = (
unsigned char*) pcap_next (plugin_private->pcap_file, &hdr);
1034 return EXIT_FAILURE;
1037 packet_info->length = hdr.len;
1038 packet_info->cap_length = hdr.caplen;
1039 packet_info->arrival_time = ((uint64_t) hdr.ts.tv_sec *
NSEC_IN_SEC) + ((uint64_t) hdr.ts.tv_usec *
NSEC_IN_USEC);
1040 packet_info->input_interface = (uint16_t) plugin_private->id;
1041 packet_info->output_interface = 0;
1043 return EXIT_SUCCESS;
1056 struct pcap_pkthdr hdr;
1058 *buf = (
unsigned char*) pcap_next (plugin_private->pcap_if, &hdr);
1060 packet_info->length = hdr.len;
1061 packet_info->cap_length = hdr.caplen;
1062 packet_info->arrival_time = ((uint64_t) hdr.ts.tv_sec *
NSEC_IN_SEC) + ((uint64_t) hdr.ts.tv_usec *
NSEC_IN_USEC);
1063 packet_info->input_interface = (uint16_t) plugin_private->id;
1064 packet_info->output_interface = 0;
1067 return EXIT_FAILURE;
1069 return EXIT_SUCCESS;
1081 int ip6tun_get_packet_hanic (
unsigned char **buf, packet_info_t *packet_info,
ip6tun_input_private_t *plugin_private)
1083 unsigned char *hw_data, *data;
1084 unsigned int hw_data_len, sw_data_len, len;
1088 if ((data = szedata_read_next (plugin_private->sze, &len)) == NULL) {
1089 return (EXIT_FAILURE);
1093 szedata_decode_packet (data, buf, &hw_data, &sw_data_len, &hw_data_len);
1095 packet_info->cap_length = sw_data_len;
1097 sec =
le32toh(*(uint32_t*)(hw_data + 8));
1098 nsec =
le32toh(*(uint32_t*)(hw_data + 4));
1099 packet_info->arrival_time = ((uint64_t) sec *
NSEC_IN_SEC) + nsec;
1101 if (plugin_private->id < 0) {
1102 packet_info->input_interface = (uint16_t) hw_data[3];
1104 packet_info->input_interface = (uint16_t) plugin_private->id;
1107 return EXIT_SUCCESS;
1120 int ip6tun_get_packet_rawnetcap (
unsigned char **buf, packet_info_t *packet_info,
ip6tun_input_private_t *plugin_private)
1122 return EXIT_FAILURE;
1135 int ip6tun_get_packet_snf (
unsigned char **buf, packet_info_t *packet_info,
ip6tun_input_private_t *plugin_private)
1137 return EXIT_FAILURE;
1154 void *
plugin_input_init(
char *params, flow_record_getter_t **getter_list,
int full_packet,
int data_offset)
1157 char *source = NULL, *next_param = NULL, *next_value = NULL, *endptr = NULL;
1160 init_packet_getter = NULL;
1162 DBG(
"IP6TUN: Params: %s\n", params);
1176 strncpy(retval->card,
"/dev/szedataII0", BUFSIZE - 1);
1179 if (params == NULL) {
1180 fprintf(stderr,
"Parameters: \n");
1187 next_param = strtok (params,
"=");
1188 while (next_param) {
1190 if ((next_value = strtok (NULL,
",")) == NULL) {
1194 if (strcmp(
"pcap_file", next_param) == 0) {
1197 source = strdup(next_value);
1198 DBG(
"IP6TUN: PCAP file as a source\n");
1200 if (strcmp(
"pcap_if", next_param) == 0) {
1203 source = strdup(next_value);
1204 DBG(
"IP6TUN: PCAP interface as a source\n");
1206 if (strcmp(
"id", next_param) == 0) {
1207 retval->id = strtol(next_value, &endptr, 10);
1208 if (*endptr !=
'\0') {
1209 fprintf(stderr,
"IP6TUN: id number must be a valid number!\n");
1214 if (strcmp(
"rawnetcap", next_param) == 0) {
1215 init_packet_getter = &ip6tun_init_rawnetcap;
1216 retval->packet_getter = &ip6tun_get_packet_rawnetcap;
1217 source = strdup(next_value);
1218 DBG(
"IP6TUN: rawnetcap interface as a source\n");
1222 if (strcmp(
"snf", next_param) == 0) {
1223 init_packet_getter = &ip6tun_init_snf;
1224 retval->packet_getter = &ip6tun_get_packet_snf;
1225 source = strdup(next_value);
1226 DBG(
"IP6TUN: snf interface as a source\n");
1230 if (strcmp(
"hanic", next_param) == 0) {
1231 init_packet_getter = &ip6tun_init_hanic;
1232 retval->packet_getter = &ip6tun_get_packet_hanic;
1233 source = strdup(next_value);
1235 retval->shutdown = &ip6tun_shutdown_hanic;
1237 if (strcmp(
"card", next_param) == 0) {
1238 strtol(next_value, &endptr, 10);
1239 if (*endptr !=
'\0') {
1240 fprintf(stderr,
"IP6TUN: Card number must be a valid number!\n");
1243 strncpy(retval->card + strlen(retval->card) - 1, next_value, BUFSIZE - strlen(retval->card) - 1);
1247 fprintf(stderr,
"IP6TUN: Unknown parameter '%s'\n", next_param);
1251 next_param = strtok (NULL,
"=");
1254 if (init_packet_getter == NULL) {
1255 fprintf(stderr,
"IP6TUN: You must select an input\n");
1259 if (next_value == NULL) {
1260 fprintf(stderr,
"IP6TUN: Parameter '%s' requires value\n", next_param);
1264 if (init_packet_getter (retval, source) == EXIT_SUCCESS) {
1265 DBG(
"IP6TUN: source initialized\n");
1266 retval->data_offset = ip6tun_input_record_offset = data_offset;
1268 DBG(
"IP6TUN: source initialized failed\n");
1272 DBG(
"IP6TUN: ID: %ld\n", retval->id);
1289 ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, ip6tun_private->data_offset);
1291 packet_info_t packet_info;
1294 unsigned char *buf = NULL;
1299 ip6tun_private->packet_data = NULL;
1300 ip6tun_private->packet_data_offset = 0;
1301 ip6tun_private->packet_length = 0;
1303 if (ip6tun_private->packet_getter(&buf, &packet_info, ip6tun_private) == EXIT_SUCCESS) {
1305 record->flow_end = record->flow_start = packet_info.arrival_time;
1307 record->flow_packets = 1;
1312 ip6tun_packet_data = buf;
1314 ret =
parse_eth (buf, (uint32_t) packet_info.cap_length,record, ip6tun_record);
1315 record->flow_input_interface_id = packet_info.input_interface;
1317 if (ret != EXIT_SUCCESS) {
1320 MD5_Final ((
unsigned char *) hash, &md5);
1323 ip6tun_private->packet_data = buf;
1324 ip6tun_private->packet_data_offset = ip6tun_packet_data_offset;
1325 ip6tun_private->packet_length = packet_info.cap_length;
1327 return ((hash[0] ^ hash[1]) | FLOW_OK_BIT);
1343 *length = ip6tun_private->packet_length;
1344 *data_offset = ip6tun_private->packet_data_offset;
1346 return ip6tun_private->packet_data;
1356 return ip6tun_private->shutdown(ip6tun_private);
1371 uint64_t internal_hash = 0;
1373 uint32_t orig_caplen = caplen;
1375 unsigned char* next_hdr = buf;
1376 int ret = EXIT_SUCCESS;
1384 if (caplen < ETH_HLEN) {
1385 return (EXIT_FAILURE);
1388 eth = (
struct ethhdr*) buf;
1389 ethtype = ntohs (eth->h_proto);
1391 if (ethtype > ETH_DATA_LEN) {
1392 if ((mac = record_mac(record)) != NULL) {
1393 memcpy (mac->src_mac, eth->h_source, ETH_ALEN);
1394 memcpy (mac->dst_mac, eth->h_dest, ETH_ALEN);
1395 MD5_Update (&md5, mac, 2 * ETH_ALEN);
1399 next_hdr += ETH_HLEN;
1406 if ((internal_hash = record_process_packet (buf, (
int) orig_caplen, record)) == 0) {
1407 return (EXIT_FAILURE);
1413 get_packet_data(&orig_caplen, &ip6tun_packet_data_offset);
1424 if ((record->l4.protocol == IPPROTO_UDP) && ((record->l4.src_port ==
AYIYA_PORT) || (record->l4.dst_port ==
AYIYA_PORT))) {
1430 DBG(
"IP6TUN: possible ayiya udp packet found\n");
1431 parse_ayiya (next_hdr, caplen, record, ip6tun_record);
1434 if (record->l4.protocol == IPPROTO_UDP) {
1439 parse_teredo (next_hdr, caplen, record, ip6tun_record);
1441 if (record->l4.protocol == IPPROTO_TCP && ((record->l4.src_port ==
AYIYA_PORT) || (record->l4.dst_port ==
AYIYA_PORT))) {
1448 DBG(
"IP6TUN: possible ayiya tcp packet found\n");
1449 parse_ayiya (next_hdr, caplen, record, ip6tun_record);
1454 MD5_Update (&md5, &internal_hash, 8);
1459 if ((internal_hash = record_process_packet (buf, (
int) orig_caplen, record)) == 0) {
1460 return (EXIT_FAILURE);
1466 MD5_Update (&md5, &internal_hash, 8);
1469 get_packet_data(&orig_caplen, &ip6tun_packet_data_offset);
1480 return (EXIT_FAILURE);
1492 ethtype = ntohs (*(uint16_t *) (next_hdr + 2));
1502 return (EXIT_FAILURE);
1516 switch(*(uint8_t *) (next_hdr +
MPLS_HLEN) >> 4) {
1522 ethtype = ETH_P_IPV6;
1526 return (EXIT_FAILURE);
1537 DBG(
"IP6TUN: probably non IP packet detected\n");
1538 return (EXIT_FAILURE);
1558 int retval = EXIT_SUCCESS;
1559 struct teredo_trailer_hdr *trailer;
1560 uint16_t payload_length = 0;
1561 unsigned char *next_header;
1565 return (EXIT_FAILURE);
1568 struct ip6_hdr *ip6 = (
struct ip6_hdr*) buf;
1570 ip6tun_record->
l3.protocol = (ip6->ip6_vfc) >> 4;
1571 ip6tun_record->
l4.protocol = ip6->ip6_nxt;
1573 if (ip6tun_record->
l3.protocol != 0x6) {
1574 return (EXIT_FAILURE);
1577 payload_length = ntohs(ip6->ip6_plen);
1579 if (payload_length < (caplen -
IPV6_HLEN)) {
1582 return (EXIT_FAILURE);
1585 next_header = buf +
IPV6_HLEN + payload_length;
1586 caplen_trailer = caplen -
IPV6_HLEN - payload_length;
1591 return (EXIT_FAILURE);
1594 trailer = (
struct teredo_trailer_hdr *) (next_header);
1596 switch (trailer->type) {
1598 DBG(
"IP6TUN: Nonce Trailer\n");
1602 DBG(
"IP6TUN: Alternate Address Trailer\n");
1606 DBG(
"IP6TUN: Neighbor Discovery Option Trailer\n");
1610 DBG(
"IP6TUN: Random Port Trailer\n");
1614 return (EXIT_FAILURE);
1620 if (caplen_trailer > 0) {
1622 }
else if (caplen_trailer < 0) {
1623 return (EXIT_FAILURE);
1629 }
else if (payload_length > (caplen -
IPV6_HLEN)) {
1630 return (EXIT_FAILURE);
1636 memcpy (&(ip6tun_record->
l3.addr.ipv6.src), &(ip6->ip6_src),
sizeof(
struct in6_addr));
1637 memcpy (&(ip6tun_record->
l3.addr.ipv6.dst), &(ip6->ip6_dst),
sizeof(
struct in6_addr));
1639 ip6tun_record->
hop = ip6->ip6_hops;
1644 MD5_Update (&md5, &(ip6tun_record->
l3.addr.ipv6.src), 16);
1645 MD5_Update (&md5, &(ip6tun_record->
l3.addr.ipv6.dst), 16);
1646 MD5_Update (&md5, &(ip6tun_record->
l4.protocol), 1);
1651 switch (ip6tun_record->
l4.protocol) {
1661 MD5_Update (&md5, &(ip6tun_record->
l4.src_port), 2);
1662 MD5_Update (&md5, &(ip6tun_record->
l4.dst_port), 2);
1664 if (ip6tun_record->
l4.protocol == IPPROTO_TCP) {
1672 case IPPROTO_ICMPV6: {
1678 ip6tun_record->
l4.icmp_type_code = ntohs(*(uint16_t*) buf);
1693 ip6tun_packet_data_offset = buf - ip6tun_packet_data;
1694 switch (ip6tun_record->
l4.protocol) {
1699 ip6tun_packet_data_offset +=
UDP_HLEN;
1702 ip6tun_packet_data_offset += 12;
1705 case IPPROTO_ICMPV6:
1706 ip6tun_packet_data_offset += 4;
1726 if (
parse_ipv6 (buf, caplen, record, ip6tun_record, 0) == EXIT_SUCCESS) {
1731 if ((record->l3.addr.ipv4.src.ip4_addr32[0] ==
_6TO4_RELAY) || (record->l3.addr.ipv4.dst.ip4_addr32[0] ==
_6TO4_RELAY)) {
1733 DBG(
"IP6TUN: 6to4 packet found\n");
1739 DBG(
"IP6TUN: 6to4 packet found (SRC)\n");
1744 DBG(
"IP6TUN: ISATAP packet found (SRC)\n");
1748 if ((ip6tun_record->
l3.addr.ipv6.src.ip6_addr16[0] ==
_6OVER4_PREFIX_NO) && (ip6tun_record->
l3.addr.ipv6.src.ip6_addr16[5] == 0x0000)) {
1749 DBG(
"IP6TUN: 6over4 packet found (SRC)\n");
1756 DBG(
"IP6TUN: 6to4 packet found (DST)\n");
1761 DBG(
"IP6TUN: ISATAP packet found (DST)\n");
1765 if ((ip6tun_record->
l3.addr.ipv6.dst.ip6_addr16[0] ==
_6OVER4_PREFIX_NO) && (ip6tun_record->
l3.addr.ipv6.dst.ip6_addr16[5] == 0x0000)) {
1766 DBG(
"IP6TUN: 6over4 packet found (DST)\n");
1775 DBG(
"IP6TUN: proto 41 packet found (DST)\n");
1780 MD5_Update (&md5, &(ip6tun_record->
validity_map),
sizeof(uint32_t));
1783 return (EXIT_FAILURE);
1786 return (EXIT_SUCCESS);
1801 unsigned char* next_hdr = buf;
1802 int hlen, parse_retval;
1807 return EXIT_FAILURE;
1810 preamble = *(uint16_t*) (next_hdr);
1814 DBG(
"IP6TUN: teredo origin header found\n");
1823 DBG(
"IP6TUN: teredo authentication header found\n");
1824 struct teredo_basic_auth_hdr *teredo_auth = (
struct teredo_basic_auth_hdr*) next_hdr;
1833 parse_retval =
parse_ipv6 (next_hdr, caplen, record, ip6tun_record,1);
1839 DBG(
"IP6TUN: valid teredo packet found\n");
1855 DBG(
"IP6TUN: valid teredo packet found (LL address)\n");
1867 return EXIT_FAILURE;
1872 return EXIT_SUCCESS;
1887 struct ayiya_hdr *ayiya = (
struct ayiya_hdr*) buf;
1889 unsigned char* next_hdr = buf;
1892 if (((ayiya->gethshmeth) < 0x03) && ((ayiya->getautmeth) < 0x03)
1893 && ((ayiya->getopcode) < 0x08) && ((ayiya->next_header) ==
IPPROTO_41)) {
1897 hlen =
AYIYA_BASE_HLEN + (4 * ayiya->getsiglen) + (0x01 << ayiya->getidlen);
1901 if (
parse_ipv6 (next_hdr, caplen, record, ip6tun_record, 0) == EXIT_SUCCESS) {
1902 DBG(
"IP6TUN: valid ayiya packet found\n");
1906 return EXIT_FAILURE;
1912 return EXIT_FAILURE;
1915 return EXIT_SUCCESS;