FlowMon IPv6 Tunnel Monitoring Plugin
FlowMon IPv6 Tunnel Monitoring Plugin
 All Data Structures Files Functions Variables Macros Pages
input-ip6tun.c
Go to the documentation of this file.
1 
39 #define VERSION "0.1"
40 
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <pcap.h>
45 #include <netinet/ip.h>
46 #include <netinet/ip6.h>
47 #include <netinet/ether.h>
48 #include <poll.h>
49 #include <string.h>
50 #include <errno.h>
51 #include <signal.h>
52 #include <sys/types.h>
53 #include <endian.h>
54 #include <openssl/md5.h>
55 
56 #include <flowmonexp/plugin_input.h>
57 
58 #ifdef HANIC
59 #include <libsze2.h>
60 #endif
61 
62 #include "input-ip6tun.h"
63 
82 #include <endian.h>
83 #ifndef le32toh
84 # include <byteswap.h>
85 # if __BYTE_ORDER == __LITTLE_ENDIAN
86 # define le32toh(x) (x)
87 # else /* __BIG_ENDIAN platform */
88 # define le32toh(x) bswap_32(x)
89 # endif
90 #endif
91 
92 #ifndef PROCESS_PLUGIN
93 unsigned int __attribute__((used))plugin_type = (PLUGIN_TYPE_INPUT);
94 #endif
95 
99 typedef struct ip6tun_input_private_struct {
100  pcap_t *pcap_if;
101  pcap_t *pcap_file;
102  long id;
103 #ifdef HANIC
104  struct szedata *sze;
105  char card[BUFSIZE];
106 #endif
107  int (*packet_getter) (unsigned char**, packet_info_t*, struct ip6tun_input_private_struct*);
108  int (*shutdown) (struct ip6tun_input_private_struct*);
109  int data_offset;
110  unsigned char *packet_data;
111  unsigned int packet_data_offset;
112  unsigned int packet_length;
114 
118 typedef struct {
119  l3_t l3;
120  l4_t l4;
121  uint8_t mechanism;
122  uint8_t ttl_hop;
123  uint8_t hop;
124  uint32_t validity_map;
125  struct {
126  uint8_t headers;
127  uint8_t trailers;
128  } teredo;
129 #ifdef IP6TUN_GEOIP
130  struct {
131  char regular_src[4];
132  char regular_dst[4];
133  char ip6tun_src[4];
134  char ip6tun_dst[4];
135  } geoip;
136 #endif
138 
139 
142 static unsigned int ip6tun_packet_data_offset;
143 static unsigned char *ip6tun_packet_data;
145 static plugin_desc_t ip6tun_input_plugin_desc = {
146  "input-ip6tun",
147  "Version " VERSION
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)"
154 #ifdef SNF
155  "\n\tsnf=snf_interface snf network interface"
156  "\n\t id=value set interface ID (default = 0)"
157 #endif
158 #ifdef RAWNETCAP
159  "\n\trawnetcap=interface network interface using rawnetcap"
160  "\n\t id=value set interface ID (default = 0)"
161 #endif
162 #ifdef HANIC
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"
166 #endif
167  ,
168  sizeof(ip6tun_record_t),
169  0
170 };
171 
172 
177 plugin_desc_t *plugin_input_desc()
178 {
179  return (&ip6tun_input_plugin_desc);
180 }
181 
193 int parse_ipv6 (unsigned char *buf, uint32_t caplen, flow_record_t *record, ip6tun_record_t *ip6tun_record, int teredo);
194 
205 int parse_proto41 (unsigned char *buf, uint32_t caplen, flow_record_t *record, ip6tun_record_t *ip6tun_record);
206 
217 int parse_teredo (unsigned char *buf, uint32_t caplen, flow_record_t *record, ip6tun_record_t *ip6tun_record);
218 
229 int parse_ayiya (unsigned char *buf, uint32_t caplen, flow_record_t *record, ip6tun_record_t *ip6tun_record);
230 
241 int parse_eth (unsigned char *buf, uint32_t caplen, flow_record_t *record, ip6tun_record_t *ip6tun_record);
242 
251 void value_fill_srcaddr6 (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
252 {
254  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
255 
256  record_universal_get (dst, &(ip6tun_record->l3.addr.ipv6.src), 0, 16, len, 0);
257 }
258 
267 void value_fill_dstaddr6 (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
268 {
270  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
271 
272  record_universal_get (dst, &(ip6tun_record->l3.addr.ipv6.dst), 0, 16, len, 0);
273 }
274 
283 void value_fill_srcport (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
284 {
286  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
287 
288  record_universal_get (dst, &(ip6tun_record->l4.src_port), 0, sizeof (uint16_t), len, 0);
289 }
290 
299 void value_fill_icmp_type_code (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
300 {
302  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
303 
304  record_universal_get (dst, &(ip6tun_record->l4.icmp_type_code), 0, sizeof (uint16_t), len, 0);
305 }
306 
315 void value_fill_dstport (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
316 {
318  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
319 
320  record_universal_get (dst, &(ip6tun_record->l4.dst_port), 0, sizeof (uint16_t), len, 0);
321 }
322 
331 void value_fill_tcp_flags (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
332 {
334  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
335 
336  record_universal_get (dst, &(ip6tun_record->l4.tcp_flags), 0, sizeof (uint8_t), len, 0);
337 }
338 
347 void value_fill_teredo_headers (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
348 {
350  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
351 
352  record_universal_get (dst, &(ip6tun_record->teredo.headers), 0, sizeof (uint8_t), len, 0);
353 }
354 
363 void value_fill_teredo_trailers (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
364 {
366  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
367 
368  record_universal_get (dst, &(ip6tun_record->teredo.trailers), 0, sizeof (uint8_t), len, 0);
369 }
370 
379 void value_fill_ttl_hop (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
380 {
382  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
383 
384  record_universal_get (dst, &(ip6tun_record->ttl_hop), 0, sizeof (uint8_t), len, 0);
385 }
386 
395 void value_fill_hop (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
396 {
398  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
399 
400  record_universal_get (dst, &(ip6tun_record->hop), 0, sizeof (uint8_t), len, 0);
401 }
402 
411 void value_fill_l4protocol (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
412 {
414  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
415 
416  record_universal_get (dst, &(ip6tun_record->l4.protocol), 0, sizeof (uint8_t), len, 0);
417 }
418 
427 void value_fill_mechnism (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
428 {
430  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
431 
432  record_universal_get (dst, &(ip6tun_record->mechanism), 0, sizeof (uint8_t), len, 0);
433 }
434 
435 #ifdef IP6TUN_GEOIP
436 
444 void value_fill_geoip_ip6tun_src (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
445 {
447  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
448 
449  record_universal_get (dst, &(ip6tun_record->geoip.ip6tun_src), 0, sizeof (char) * COUNTRY_CODE_LEN, len, 0);
450 }
451 
460 void value_fill_geoip_ip6tun_dst (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
461 {
463  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
464 
465  record_universal_get (dst, &(ip6tun_record->geoip.ip6tun_dst), 0, sizeof (char) * COUNTRY_CODE_LEN, len, 0);
466 }
467 
476 void value_fill_geoip_regular_src (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
477 {
479  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
480 
481  record_universal_get (dst, &(ip6tun_record->geoip.regular_src), 0, sizeof (char) * COUNTRY_CODE_LEN, len, 0);
482 }
483 
492 void value_fill_geoip_regular_dst (void *self, flow_record_t *record, void *dst, int len, int to_network_byte_order)
493 {
495  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
496 
497  record_universal_get (dst, &(ip6tun_record->geoip.regular_dst), 0, sizeof (char) * COUNTRY_CODE_LEN, len, 0);
498 }
499 
508 int validity_geoip_regular (void *self, flow_record_t *record)
509 {
511  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
512 
513  if (ip6tun_record->validity_map & IP6TUN_RECORD_GEOIP_REG) {
514  return (VALIDITE_SUCCESS);
515  } else {
516  return (VALIDITE_FAILED);
517  }
518 }
519 
528 int validity_geoip_ip6tun (void *self, flow_record_t *record)
529 {
531  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
532 
533  if (ip6tun_record->validity_map & IP6TUN_RECORD_GEOIP_IP6TUN) {
534  return (VALIDITE_SUCCESS);
535  } else {
536  return (VALIDITE_FAILED);
537  }
538 }
539 
540 #endif
541 
550 int validity_addr6 (void *self, flow_record_t *record)
551 {
553  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
554 
555  if (ip6tun_record->validity_map & IP6TUN_RECORD_IPV6) {
556  return (VALIDITE_SUCCESS);
557  } else {
558  return (VALIDITE_FAILED);
559  }
560 }
561 
570 int validity_port (void *self, flow_record_t *record)
571 {
573  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
574 
575  if (ip6tun_record->validity_map & IP6TUN_RECORD_PORTS) {
576  return (VALIDITE_SUCCESS);
577  } else {
578  return (VALIDITE_FAILED);
579  }
580 }
581 
590 int validity_tcp_flags (void *self, flow_record_t *record)
591 {
593  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
594 
595  if (ip6tun_record->validity_map & IP6TUN_RECORD_FLAGS) {
596  return (VALIDITE_SUCCESS);
597  } else {
598  return (VALIDITE_FAILED);
599  }
600 }
609 int validity_teredo_headers (void *self, flow_record_t *record)
610 {
612  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
613 
614  if (ip6tun_record->validity_map & IP6TUN_RECORD_TEREDO_HDR) {
615  return (VALIDITE_SUCCESS);
616  } else {
617  return (VALIDITE_FAILED);
618  }
619 }
620 
629 int validity_teredo_trailers (void *self, flow_record_t *record)
630 {
632  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
633 
634  if (ip6tun_record->validity_map & IP6TUN_RECORD_TEREDO_TRL) {
635  return (VALIDITE_SUCCESS);
636  } else {
637  return (VALIDITE_FAILED);
638  }
639 }
640 
649 int validity_ttl_hop (void *self, flow_record_t *record)
650 {
652  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
653 
654  if (ip6tun_record->validity_map & IP6TUN_RECORD_TTL_HOP) {
655  return (VALIDITE_SUCCESS);
656  } else {
657  return (VALIDITE_FAILED);
658  }
659 }
660 
669 int validity_hop (void *self, flow_record_t *record)
670 {
672  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
673 
674  if (ip6tun_record->validity_map & IP6TUN_RECORD_HOP) {
675  return (VALIDITE_SUCCESS);
676  } else {
677  return (VALIDITE_FAILED);
678  }
679 }
680 
689 int validity_l4protocol (void *self, flow_record_t *record)
690 {
692  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
693 
694  if (ip6tun_record->validity_map & IP6TUN_RECORD_L4_PROTO) {
695  return (VALIDITE_SUCCESS);
696  } else {
697  return (VALIDITE_FAILED);
698  }
699 }
700 
709 int validity_icmp_type_code (void *self, flow_record_t *record)
710 {
712  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
713 
714  if (ip6tun_record->validity_map & IP6TUN_RECORD_ICMP) {
715  return (VALIDITE_SUCCESS);
716  } else {
717  return (VALIDITE_FAILED);
718  }
719 }
720 
729 int validity_mechanism (void *self, flow_record_t *record)
730 {
732  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, p->data_offset);
733 
734  if (ip6tun_record->validity_map & IP6TUN_RECORD_TMECH) {
735  return (VALIDITE_SUCCESS);
736  } else {
737  return (VALIDITE_FAILED);
738  }
739 }
740 
741 #ifdef IP6TUN_GEOIP
742 
750 int value_length_geoip (void *self, flow_record_t *record)
751 {
752  return (sizeof(char) * COUNTRY_CODE_LEN);
753 }
754 #endif
755 
764 int value_length_mechanism (void *self, flow_record_t *record)
765 {
766  return (sizeof(uint8_t));
767 }
768 
777 int value_length_ttl_hop (void *self, flow_record_t *record)
778 {
779  return (sizeof(uint8_t));
780 }
781 
790 int value_length_tcp_flags (void *self, flow_record_t *record)
791 {
792  return (sizeof(uint8_t));
793 }
794 
803 int value_length_protocol (void *self, flow_record_t *record)
804 {
805  return (sizeof(uint8_t));
806 }
807 
816 int value_length_port (void *self, flow_record_t *record)
817 {
818  return (sizeof(uint16_t));
819 }
820 
829 int value_length_teredo_headers_trailers (void *self, flow_record_t *record)
830 {
831  return (sizeof(uint8_t));
832 }
833 
842 int value_length_icmp_type_code (void *self, flow_record_t *record)
843 {
844  return (sizeof(uint16_t));
845 }
846 
855 int value_length_addr6 (void *self, flow_record_t *record)
856 {
857  return (sizeof (ipv6_addr_t));
858 }
859 
866 void plugin_input_getter_init(void *plugin_private, flow_record_getter_t **getter_list)
867 {
868  getter_add (getter_list, "TUN_SRC_IPv6", 16, plugin_private, &validity_addr6, &value_length_addr6, &value_fill_srcaddr6);
869  getter_add (getter_list, "TUN_DST_IPv6", 16, plugin_private, &validity_addr6, &value_length_addr6, &value_fill_dstaddr6);
870 
871  getter_add (getter_list, "TUN_SRC_PORT", 2, plugin_private, &validity_port, &value_length_port, &value_fill_srcport);
872  getter_add (getter_list, "TUN_DST_PORT", 2, plugin_private, &validity_port, &value_length_port, &value_fill_dstport);
873 
874  getter_add (getter_list, "TUN_PROTOCOL", 1, plugin_private, &validity_l4protocol, &value_length_protocol, &value_fill_l4protocol);
875  getter_add (getter_list, "TUN_TYPE", 1, plugin_private, &validity_mechanism, &value_length_mechanism, &value_fill_mechnism);
876 
877  getter_add (getter_list, "TUN_TCP_FLAGS", 1, plugin_private, &validity_tcp_flags, &value_length_tcp_flags, &value_fill_tcp_flags);
878  getter_add (getter_list, "TUN_ICMP_TYPE_CODE", 2, plugin_private, &validity_icmp_type_code, &value_length_icmp_type_code, &value_fill_icmp_type_code);
879 
880  getter_add (getter_list, "TUN_TEREDO_HDRS", 1, plugin_private, &validity_teredo_headers, &value_length_teredo_headers_trailers, &value_fill_teredo_headers);
881  getter_add (getter_list, "TUN_TEREDO_TRLS", 1, plugin_private, &validity_teredo_trailers, &value_length_teredo_headers_trailers, &value_fill_teredo_trailers);
882 
883  getter_add (getter_list, "TUN_HOP", 1, plugin_private, &validity_hop, &value_length_ttl_hop, &value_fill_hop);
884  getter_add (getter_list, "TTL_HOP", 1, plugin_private, &validity_ttl_hop, &value_length_ttl_hop, &value_fill_ttl_hop);
885 
886 #ifdef IP6TUN_GEOIP
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);
889 
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);
892 #endif
893 }
894 
895 static MD5_CTX md5;
896 
897 
905 int ip6tun_init_pcap_file (ip6tun_input_private_t *plugin_private, char *source)
906 {
907  char errbuf[PCAP_ERRBUF_SIZE];
908 
909  plugin_private->pcap_file = pcap_open_offline (source, errbuf);
910 
911  if (plugin_private->pcap_file == NULL) {
912  return EXIT_FAILURE;
913  }
914 
915  return EXIT_SUCCESS;
916 }
917 
925 int ip6tun_init_pcap_if (ip6tun_input_private_t *plugin_private, char *source)
926 {
927  char errbuf[PCAP_ERRBUF_SIZE];
928 
929  plugin_private->pcap_if = pcap_open_live (source, PCAP_SIZE, 1, 0, errbuf);
930 
931  if (plugin_private->pcap_if == NULL) {
932  return EXIT_FAILURE;
933  }
934 
935  return EXIT_SUCCESS;
936 }
937 
938 #ifdef HANIC
939 
946 int ip6tun_init_hanic (ip6tun_input_private_t *plugin_private, char *source)
947 {
948  unsigned int rx = 0xffff, tx = 0;
949 
950  /* set rx mask according to parameter value */
951  rx = atoi(source);
952 
953  /* open SZE device */
954  if ((plugin_private->sze = szedata_open(plugin_private->card)) == NULL) {
955  fprintf(stderr, "IP6TUN: szedata_open failed\n");
956  return (EXIT_FAILURE);
957  }
958 
959  /* subscribe required interface */
960  if (szedata_subscribe3(plugin_private->sze, &rx, &tx)) {
961  fprintf(stderr, "IP6TUN: szedata subscribe failed\n");
962  return (EXIT_FAILURE);
963  }
964 
965  /* and finally start subscribed interface */
966  if(szedata_start(plugin_private->sze)) {
967  fprintf(stderr, "IP6TUN: szedata start failed\n");
968  return (EXIT_FAILURE);
969  }
970 
971  return EXIT_SUCCESS;
972 }
973 
974 int ip6tun_shutdown_hanic(ip6tun_input_private_t *plugin_private)
975 {
976  szedata_close(plugin_private->sze);
977 
978  return EXIT_SUCCESS;
979 }
980 #endif
981 
982 #ifdef RAWNETCAP
983 
991 int ip6tun_init_rawnetcap (ip6tun_input_private_t *plugin_private, char *source)
992 {
993  return EXIT_FAILURE;
994 }
995 #endif
996 
997 #ifdef SNF
998 
1005 int ip6tun_init_snf (ip6tun_input_private_t *plugin_private, char *source)
1006 {
1007  return EXIT_FAILURE;
1008 }
1009 #endif
1010 
1012 {
1013  return EXIT_SUCCESS;
1014 }
1015 
1024 int ip6tun_get_packet_pcap_file (unsigned char **buf, packet_info_t *packet_info, ip6tun_input_private_t *plugin_private)
1025 {
1026  struct pcap_pkthdr hdr;
1027 
1028  *buf = (unsigned char*) pcap_next (plugin_private->pcap_file, &hdr);
1029 
1030  if (*buf == NULL) {
1031  sleep (5);
1032  raise (SIGQUIT);
1033  sleep (5);
1034  return EXIT_FAILURE;
1035  }
1036 
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;
1042 
1043  return EXIT_SUCCESS;
1044 }
1045 
1054 int ip6tun_get_packet_pcap_if (unsigned char **buf, packet_info_t *packet_info, ip6tun_input_private_t *plugin_private)
1055 {
1056  struct pcap_pkthdr hdr;
1057 
1058  *buf = (unsigned char*) pcap_next (plugin_private->pcap_if, &hdr);
1059 
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;
1065 
1066  if (*buf == NULL) {
1067  return EXIT_FAILURE;
1068  }
1069  return EXIT_SUCCESS;
1070 }
1071 
1072 #ifdef HANIC
1073 
1081 int ip6tun_get_packet_hanic (unsigned char **buf, packet_info_t *packet_info, ip6tun_input_private_t *plugin_private)
1082 {
1083  unsigned char *hw_data, *data;
1084  unsigned int hw_data_len, sw_data_len, len;
1085  uint32_t sec, nsec;
1086 
1087  /* read next packet from subscribed interface via sze */
1088  if ((data = szedata_read_next (plugin_private->sze, &len)) == NULL) {
1089  return (EXIT_FAILURE);
1090  }
1091 
1092  /* parse packet */
1093  szedata_decode_packet (data, buf, &hw_data, &sw_data_len, &hw_data_len);
1094  //packet_info->length = ntohs(*(uint32_t*) hw_data);
1095  packet_info->cap_length = sw_data_len;
1096 
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;
1100 
1101  if (plugin_private->id < 0) {
1102  packet_info->input_interface = (uint16_t) hw_data[3];
1103  } else {
1104  packet_info->input_interface = (uint16_t) plugin_private->id;
1105  }
1106 
1107  return EXIT_SUCCESS;
1108 }
1109 #endif
1110 
1111 #ifdef RAWNETCAP
1112 
1120 int ip6tun_get_packet_rawnetcap (unsigned char **buf, packet_info_t *packet_info, ip6tun_input_private_t *plugin_private)
1121 {
1122  return EXIT_FAILURE;
1123 }
1124 #endif
1125 
1126 #ifdef SNF
1127 
1135 int ip6tun_get_packet_snf (unsigned char **buf, packet_info_t *packet_info, ip6tun_input_private_t *plugin_private)
1136 {
1137  return EXIT_FAILURE;
1138 }
1139 #endif
1140 
1141 
1142 
1154 void *plugin_input_init(char *params, flow_record_getter_t **getter_list, int full_packet, int data_offset)
1155 {
1156  ip6tun_input_private_t *retval;
1157  char *source = NULL, *next_param = NULL, *next_value = NULL, *endptr = NULL;
1158  int (*init_packet_getter) (ip6tun_input_private_t*, char*);
1159 
1160  init_packet_getter = NULL;
1161 
1162  DBG("IP6TUN: Params: %s\n", params);
1163 
1164  retval = malloc (sizeof(ip6tun_input_private_t));
1165  if (!retval) {
1166  return (NULL);
1167  }
1168 
1169  retval->id = 0;
1170 
1171  /* Init getters */
1172  plugin_input_getter_init(retval, getter_list);
1173 
1174 
1175 #ifdef HANIC
1176  strncpy(retval->card, "/dev/szedataII0", BUFSIZE - 1);
1177 #endif
1178 
1179  if (params == NULL) {
1180  fprintf(stderr, "Parameters: \n");
1181  return (NULL);
1182  }
1183 
1184  /* Set default shutdown function */
1185  retval->shutdown = &ip6tun_shutdown_uni;
1186 
1187  next_param = strtok (params, "=");
1188  while (next_param) {
1189  // each parameter must have a value
1190  if ((next_value = strtok (NULL, ",")) == NULL) {
1191  break;
1192  }
1193 
1194  if (strcmp("pcap_file", next_param) == 0) {
1195  init_packet_getter = &ip6tun_init_pcap_file;
1196  retval->packet_getter = &ip6tun_get_packet_pcap_file;
1197  source = strdup(next_value);
1198  DBG("IP6TUN: PCAP file as a source\n");
1199  } else
1200  if (strcmp("pcap_if", next_param) == 0) {
1201  init_packet_getter = &ip6tun_init_pcap_if;
1202  retval->packet_getter = &ip6tun_get_packet_pcap_if;
1203  source = strdup(next_value);
1204  DBG("IP6TUN: PCAP interface as a source\n");
1205  } else
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");
1210  return (NULL);
1211  }
1212  } else
1213 #ifdef RAWNETCAP
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");
1219  } else
1220 #endif
1221 #ifdef SNF
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");
1227  } else
1228 #endif
1229 #ifdef HANIC
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);
1234  retval->id = -1;
1235  retval->shutdown = &ip6tun_shutdown_hanic;
1236  } else
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");
1241  return (NULL);
1242  }
1243  strncpy(retval->card + strlen(retval->card) - 1, next_value, BUFSIZE - strlen(retval->card) - 1);
1244  } else
1245 #endif
1246  {
1247  fprintf(stderr, "IP6TUN: Unknown parameter '%s'\n", next_param);
1248  return (NULL);
1249  }
1250 
1251  next_param = strtok (NULL, "=");
1252  }
1253 
1254  if (init_packet_getter == NULL) {
1255  fprintf(stderr, "IP6TUN: You must select an input\n");
1256  return (NULL);
1257  }
1258 
1259  if (next_value == NULL) {
1260  fprintf(stderr, "IP6TUN: Parameter '%s' requires value\n", next_param);
1261  return (NULL);
1262  }
1263 
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;
1267  } else {
1268  DBG("IP6TUN: source initialized failed\n");
1269  return (NULL);
1270  }
1271 
1272  DBG("IP6TUN: ID: %ld\n", retval->id);
1273 
1274  return (retval);
1275 }
1276 
1286 uint64_t plugin_input_get_flow(void *plugin_private, flow_record_t *record)
1287 {
1288  ip6tun_input_private_t *ip6tun_private = (ip6tun_input_private_t*) plugin_private;
1289  ip6tun_record_t *ip6tun_record = PLUGIN_DATA(record, ip6tun_private->data_offset);
1290 
1291  packet_info_t packet_info;
1292  int ret;
1293  uint64_t hash[2];
1294  unsigned char *buf = NULL;
1295 
1296  memset ((void*) ip6tun_record, 0, sizeof(ip6tun_record_t));
1297 
1298  /* No packet processed yet */
1299  ip6tun_private->packet_data = NULL;
1300  ip6tun_private->packet_data_offset = 0;
1301  ip6tun_private->packet_length = 0;
1302 
1303  if (ip6tun_private->packet_getter(&buf, &packet_info, ip6tun_private) == EXIT_SUCCESS) {
1304 
1305  record->flow_end = record->flow_start = packet_info.arrival_time;
1306  // record->flow_octets = packet_info.length;
1307  record->flow_packets = 1;
1308 
1309  MD5_Init (&md5);
1310 
1311  // Store the original buf pointer to global variable to be accessible for all parse_ functions
1312  ip6tun_packet_data = buf;
1313 
1314  ret = parse_eth (buf, (uint32_t) packet_info.cap_length,record, ip6tun_record);
1315  record->flow_input_interface_id = packet_info.input_interface;
1316 
1317  if (ret != EXIT_SUCCESS) {
1318  return GET_FAILED;
1319  } else {
1320  MD5_Final ((unsigned char *) hash, &md5);
1321 
1322  /* Store info for get_flow_packet */
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;
1326 
1327  return ((hash[0] ^ hash[1]) | FLOW_OK_BIT);
1328  }
1329  }
1330 
1331  return GET_FAILED;
1332 }
1333 
1339 unsigned char *plugin_input_get_flow_packet(void *plugin_private, unsigned int *length, unsigned int *data_offset)
1340 {
1341  ip6tun_input_private_t *ip6tun_private = (ip6tun_input_private_t*) plugin_private;
1342 
1343  *length = ip6tun_private->packet_length;
1344  *data_offset = ip6tun_private->packet_data_offset;
1345 
1346  return ip6tun_private->packet_data;
1347 }
1348 
1352 int plugin_input_shutdown(void * plugin_private)
1353 {
1354  ip6tun_input_private_t *ip6tun_private = (ip6tun_input_private_t*) plugin_private;
1355 
1356  return ip6tun_private->shutdown(ip6tun_private);
1357 }
1358 
1369 int parse_eth (unsigned char* buf, uint32_t caplen, flow_record_t *record, ip6tun_record_t *ip6tun_record)
1370 {
1371  uint64_t internal_hash = 0;
1372  uint16_t ethtype;
1373  uint32_t orig_caplen = caplen;
1374  struct ethhdr *eth;
1375  unsigned char* next_hdr = buf;
1376  int ret = EXIT_SUCCESS;
1377  //~ vlan_t *vlan;
1378  //~ mpls_t *mpls;
1379  l2_t *mac;
1380  uint8_t hlen;
1381 
1382  //~ uint32_t bytes = record->flow_octets; /* store it for later use */
1383 
1384  if (caplen < ETH_HLEN) {
1385  return (EXIT_FAILURE);
1386  }
1387 
1388  eth = (struct ethhdr*) buf;
1389  ethtype = ntohs (eth->h_proto);
1390 
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);
1396  }
1397 
1398  /* move from simple 802.3 header to PDU */
1399  next_hdr += ETH_HLEN;
1400  caplen -= ETH_HLEN;
1401  }
1402 
1403  recurse:
1404  switch (ethtype) {
1405  case ETH_P_IP: {
1406  if ((internal_hash = record_process_packet (buf, (int) orig_caplen, record)) == 0) {
1407  return (EXIT_FAILURE);
1408  }
1409  ip6tun_record->ttl_hop = *(uint8_t *) (next_hdr + IP_TTL_OFFSET);
1410  ip6tun_record->validity_map |= IP6TUN_RECORD_TTL_HOP;
1411 
1412  // Get data offset
1413  get_packet_data(&orig_caplen, &ip6tun_packet_data_offset);
1414 
1415  // jump the ip header
1416  hlen = (*(uint8_t *) next_hdr & IP_HLEN_MASK) * 4;
1417  next_hdr += hlen;
1418  caplen -= hlen;
1419 
1420  if (caplen > IPV6_HLEN) {
1421  if (record->l4.protocol == IPPROTO_41) {
1422  parse_proto41 (next_hdr, caplen, record, ip6tun_record);
1423  } else
1424  if ((record->l4.protocol == IPPROTO_UDP) && ((record->l4.src_port == AYIYA_PORT) || (record->l4.dst_port == AYIYA_PORT))) {
1425  // jump the udp header
1426  next_hdr += UDP_HLEN;
1427  caplen -= UDP_HLEN;
1428 
1429  if (caplen > (AYIYA_BASE_HLEN + IPV6_HLEN)) {
1430  DBG("IP6TUN: possible ayiya udp packet found\n");
1431  parse_ayiya (next_hdr, caplen, record, ip6tun_record);
1432  }
1433  } else
1434  if (record->l4.protocol == IPPROTO_UDP) {
1435  // jump the udp header
1436  next_hdr += UDP_HLEN;
1437  caplen -= UDP_HLEN;
1438 
1439  parse_teredo (next_hdr, caplen, record, ip6tun_record);
1440  } else
1441  if (record->l4.protocol == IPPROTO_TCP && ((record->l4.src_port == AYIYA_PORT) || (record->l4.dst_port == AYIYA_PORT))) {
1442  // jump the tcp header
1443  hlen = ((*(uint8_t *) (next_hdr + TCP_DATA_OFFSET_OFFSET)) >> TCP_DATA_OFFSET_SHIFT) * 4;
1444  next_hdr += hlen;
1445  caplen -= hlen;
1446 
1447  if (caplen > (AYIYA_BASE_HLEN + IPV6_HLEN)) {
1448  DBG("IP6TUN: possible ayiya tcp packet found\n");
1449  parse_ayiya (next_hdr, caplen, record, ip6tun_record);
1450  }
1451  }
1452  }
1453 
1454  MD5_Update (&md5, &internal_hash, 8);
1455 
1456  break;
1457  }
1458  case ETH_P_IPV6: {
1459  if ((internal_hash = record_process_packet (buf, (int) orig_caplen, record)) == 0) {
1460  return (EXIT_FAILURE);
1461  }
1462 
1463  ip6tun_record->ttl_hop = *(uint8_t *) (next_hdr + IPV6_HOP_OFFSET);
1464  ip6tun_record->validity_map |= IP6TUN_RECORD_TTL_HOP;
1465 
1466  MD5_Update (&md5, &internal_hash, 8);
1467 
1468  // Get data offset
1469  get_packet_data(&orig_caplen, &ip6tun_packet_data_offset);
1470 
1471  break;
1472  }
1473  case ETH_P_8021Q:
1474  case _ETH_P_8021QINQ:
1477  case _ETH_P_8021AD: {
1478 
1479  if (caplen < VLAN_HLEN) {
1480  return (EXIT_FAILURE);
1481  }
1482 
1483  // not sure if we should fill these or record_process_packet takes care of that
1484  //~ if ((vlan = record_vlan (record)) != NULL) {
1485  //~ if (vlan->count < VLAN_MAX) {
1486  //~ vlan->id[vlan->count] = htons((*(uint16_t *) next_hdr) & VLAN_ID_MASK);
1487  //~ MD5_Update (&md5, &(vlan->id[vlan->count]), 2);
1488  //~ vlan->count++;
1489  //~ }
1490  //~ }
1491 
1492  ethtype = ntohs (*(uint16_t *) (next_hdr + 2));
1493  next_hdr += VLAN_HLEN;
1494  caplen -= VLAN_HLEN;
1495 
1496  goto recurse;
1497  }
1498  case ETH_P_MPLS_UC:
1499  case ETH_P_MPLS_MC: {
1500 
1501  if (caplen < MPLS_HLEN) {
1502  return (EXIT_FAILURE);
1503  }
1504 
1505  // not sure if we should fill these or record_process_packet takes care of that
1506  //~ if ((mpls = record_mpls (record)) != NULL) {
1507  //~ if (mpls->count < MPLS_MAX) {
1508  //~ mpls->id[mpls->count] = htonl((*(uint32_t *) next_hdr) >> MPLS_LABEL_SHIFT);
1509  //~ MD5_Update (&md5, &(mpls->id[mpls->count]), 2);
1510  //~ mpls->count++;
1511  //~ }
1512  //~ }
1513 
1514  if ((*(uint32_t *) next_hdr) & MPLS_STACK_MASK) {
1515  // try to guess the ethtype
1516  switch(*(uint8_t *) (next_hdr + MPLS_HLEN) >> 4) {
1517  case 4: {
1518  ethtype = ETH_P_IP;
1519  break;
1520  }
1521  case 6: {
1522  ethtype = ETH_P_IPV6;
1523  break;
1524  }
1525  default:
1526  return (EXIT_FAILURE);
1527  }
1528  }
1529 
1530  next_hdr += MPLS_HLEN;
1531  caplen -= MPLS_HLEN;
1532 
1533  goto recurse;
1534  }
1535  default: {
1536  // we dont know it -> dont process it
1537  DBG("IP6TUN: probably non IP packet detected\n");
1538  return (EXIT_FAILURE);
1539  }
1540  }
1541 
1542  return (ret);
1543 }
1544 
1556 int parse_ipv6 (unsigned char *buf, uint32_t caplen, flow_record_t *record, ip6tun_record_t *ip6tun_record, int teredo)
1557 {
1558  int retval = EXIT_SUCCESS;
1559  struct teredo_trailer_hdr *trailer;
1560  uint16_t payload_length = 0;
1561  unsigned char *next_header;
1562  int caplen_trailer;
1563 
1564  if (caplen < IPV6_HLEN) {
1565  return (EXIT_FAILURE);
1566  }
1567 
1568  struct ip6_hdr *ip6 = (struct ip6_hdr*) buf;
1569 
1570  ip6tun_record->l3.protocol = (ip6->ip6_vfc) >> 4;
1571  ip6tun_record->l4.protocol = ip6->ip6_nxt;
1572 
1573  if (ip6tun_record->l3.protocol != 0x6) {
1574  return (EXIT_FAILURE);
1575  }
1576 
1577  payload_length = ntohs(ip6->ip6_plen);
1578 
1579  if (payload_length < (caplen - IPV6_HLEN)) {
1580 
1581  if (teredo == 0) {
1582  return (EXIT_FAILURE);
1583  }
1584 
1585  next_header = buf + IPV6_HLEN + payload_length;
1586  caplen_trailer = caplen - IPV6_HLEN - payload_length;
1587 
1588  recurse:
1589 
1590  if (caplen_trailer < TEREDO_TRAILER_BASIC_LEN) {
1591  return (EXIT_FAILURE);
1592  }
1593 
1594  trailer = (struct teredo_trailer_hdr *) (next_header);
1595 
1596  switch (trailer->type) {
1597  case 0x01: /* Nonce Trailer */
1598  DBG("IP6TUN: Nonce Trailer\n");
1599  ip6tun_record->teredo.trailers |= TEREDO_TRL_NONCE;
1600  break;
1601  case 0x03: /* Alternate Address Trailer */
1602  DBG("IP6TUN: Alternate Address Trailer\n");
1603  ip6tun_record->teredo.trailers |= TEREDO_TRL_AADDR;
1604  break;
1605  case 0x04: /* Neighbor Discovery Option Trailer */
1606  DBG("IP6TUN: Neighbor Discovery Option Trailer\n");
1607  ip6tun_record->teredo.trailers |= TEREDO_TRL_NDISC;
1608  break;
1609  case 0x05: /* Random Port Trailer */
1610  DBG("IP6TUN: Random Port Trailer\n");
1611  ip6tun_record->teredo.trailers |= TEREDO_TRL_RPORT;
1612  break;
1613  default:
1614  return (EXIT_FAILURE);
1615  }
1616 
1617  next_header += TEREDO_TRAILER_BASIC_LEN + trailer->len;
1618  caplen_trailer -= TEREDO_TRAILER_BASIC_LEN + trailer->len;
1619 
1620  if (caplen_trailer > 0) {
1621  goto recurse;
1622  } else if (caplen_trailer < 0) {
1623  return (EXIT_FAILURE);
1624  }
1625 
1626  ip6tun_record->validity_map |= IP6TUN_RECORD_TEREDO_TRL;
1627 
1628  retval = EXIT_TEREDO_TRAILER;
1629  } else if (payload_length > (caplen - IPV6_HLEN)) {
1630  return (EXIT_FAILURE);
1631  }
1632 
1633  ip6tun_record->validity_map |= IP6TUN_RECORD_L3_PROTO;
1634  ip6tun_record->validity_map |= IP6TUN_RECORD_L4_PROTO;
1635 
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));
1638 
1639  ip6tun_record->hop = ip6->ip6_hops;
1640  ip6tun_record->validity_map |= IP6TUN_RECORD_HOP;
1641 
1642  ip6tun_record->validity_map |= IP6TUN_RECORD_IPV6;
1643 
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);
1647 
1648  buf += IPV6_HLEN;
1649 
1650  //~ recurse:
1651  switch (ip6tun_record->l4.protocol) {
1652  case IPPROTO_TCP:
1653  case IPPROTO_UDP:
1654  case IPPROTO_SCTP:
1655  /*case IPPROTO_DCCP:*/ {
1656  ip6tun_record->l4.src_port = *(uint16_t*) (buf + TCP_SPORT_OFFSET);
1657  ip6tun_record->l4.dst_port = *(uint16_t*) (buf + TCP_DPORT_OFFSET);
1658 
1659  ip6tun_record->validity_map |= IP6TUN_RECORD_PORTS;
1660 
1661  MD5_Update (&md5, &(ip6tun_record->l4.src_port), 2);
1662  MD5_Update (&md5, &(ip6tun_record->l4.dst_port), 2);
1663 
1664  if (ip6tun_record->l4.protocol == IPPROTO_TCP) {
1665  ip6tun_record->l4.tcp_flags = *(uint8_t*) (buf + TCP_FLAGS_OFFSET);
1666  ip6tun_record->validity_map |= IP6TUN_RECORD_FLAGS;
1667  }
1668 
1669  break;
1670  }
1671  case IPPROTO_ICMP:
1672  case IPPROTO_ICMPV6: {
1673  // ip6tun_record->l4.src_port = 0;
1674  // ip6tun_record->l4.dst_port = 0;
1675 
1676  // ip6tun_record->validity_map |= IP6TUN_RECORD_PORTS;
1677 
1678  ip6tun_record->l4.icmp_type_code = ntohs(*(uint16_t*) buf);
1679  ip6tun_record->validity_map |= IP6TUN_RECORD_ICMP;
1680 
1681  break;
1682  }
1683  //~ case IPPROTO_FRAGMENT: {
1684  //~ ip6tun_record->l4.protocol = *(uint8_t*) buf;
1685  //~ buf += 8;
1686  //~
1687  //~ goto recurse;
1688  //~ break;
1689  //~ }
1690  }
1691 
1692  // IPv6 tunnel header is parsed, set data offset
1693  ip6tun_packet_data_offset = buf - ip6tun_packet_data;
1694  switch (ip6tun_record->l4.protocol) {
1695  case IPPROTO_TCP:
1696  ip6tun_packet_data_offset += ((*(uint8_t *) (buf + TCP_DATA_OFFSET_OFFSET)) >> TCP_DATA_OFFSET_SHIFT) * 4;
1697  break;
1698  case IPPROTO_UDP:
1699  ip6tun_packet_data_offset += UDP_HLEN;
1700  break;
1701  case IPPROTO_SCTP:
1702  ip6tun_packet_data_offset += 12; /* SCTP common header length */
1703  break;
1704  case IPPROTO_ICMP:
1705  case IPPROTO_ICMPV6:
1706  ip6tun_packet_data_offset += 4; /* The first part is 4 byte constant */
1707  break;
1708  }
1709 
1710 
1711  return (retval);
1712 }
1713 
1724 int parse_proto41 (unsigned char* buf, uint32_t caplen, flow_record_t *record, ip6tun_record_t *ip6tun_record)
1725 {
1726  if (parse_ipv6 (buf, caplen, record, ip6tun_record, 0) == EXIT_SUCCESS) {
1727  /* ipv6tun record shoudl be filled
1728  * - now try to detect the mechanism
1729  * - or more likely try to guess it */
1730 
1731  if ((record->l3.addr.ipv4.src.ip4_addr32[0] == _6TO4_RELAY) || (record->l3.addr.ipv4.dst.ip4_addr32[0] == _6TO4_RELAY)) {
1732  // this one is solid as a rock
1733  DBG("IP6TUN: 6to4 packet found\n");
1734  ip6tun_record->mechanism |= IP6TUN_TMECH_6TO4;
1735  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1736  } else {
1737  // based on source address
1738  if (ip6tun_record->l3.addr.ipv6.src.ip6_addr16[0] == _6TO4_PREFIX_NO) {
1739  DBG("IP6TUN: 6to4 packet found (SRC)\n");
1740  ip6tun_record->mechanism |= IP6TUN_TMECH_6TO4;
1741  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1742  } else
1743  if (ip6tun_record->l3.addr.ipv6.src.ip6_addr16[5] == ISATAP_MARK_NO) {
1744  DBG("IP6TUN: ISATAP packet found (SRC)\n");
1745  ip6tun_record->mechanism |= IP6TUN_TMECH_ISATAP;
1746  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1747  } else
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");
1750  ip6tun_record->mechanism |= IP6TUN_TMECH_6OVER4;
1751  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1752  }
1753 
1754  // based on destination address
1755  if (ip6tun_record->l3.addr.ipv6.dst.ip6_addr16[0] == _6TO4_PREFIX_NO) {
1756  DBG("IP6TUN: 6to4 packet found (DST)\n");
1757  ip6tun_record->mechanism |= IP6TUN_TMECH_6TO4;
1758  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1759  } else
1760  if (ip6tun_record->l3.addr.ipv6.dst.ip6_addr16[5] == ISATAP_MARK_NO) {
1761  DBG("IP6TUN: ISATAP packet found (DST)\n");
1762  ip6tun_record->mechanism |= IP6TUN_TMECH_ISATAP;
1763  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1764  } else
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");
1767  ip6tun_record->mechanism |= IP6TUN_TMECH_6OVER4;
1768  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1769  }
1770 
1771  // this way we can get possible mechanism type set
1772  }
1773 
1774  if (!ip6tun_record->mechanism) {
1775  DBG("IP6TUN: proto 41 packet found (DST)\n");
1776  ip6tun_record->mechanism |= IP6TUN_TMECH_OTHER41;
1777  }
1778 
1779  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1780  MD5_Update (&md5, &(ip6tun_record->validity_map), sizeof(uint32_t));
1781 
1782  } else {
1783  return (EXIT_FAILURE);
1784  }
1785 
1786  return (EXIT_SUCCESS);
1787 }
1788 
1799 int parse_teredo (unsigned char* buf, uint32_t caplen, flow_record_t *record, ip6tun_record_t *ip6tun_record)
1800 {
1801  unsigned char* next_hdr = buf;
1802  int hlen, parse_retval;
1803  uint16_t preamble;
1804 
1805  recurse:
1806  if (caplen < IPV6_HLEN) {
1807  return EXIT_FAILURE;
1808  }
1809 
1810  preamble = *(uint16_t*) (next_hdr);
1811 
1812  switch (preamble) {
1813  case TEREDO_ORIG_PRE_NO: {
1814  DBG("IP6TUN: teredo origin header found\n");
1815  // fixed length skip it
1816  next_hdr += TEREDO_ORIG_HLEN;
1817  caplen -= TEREDO_ORIG_HLEN;
1818  ip6tun_record->teredo.headers |= TEREDO_HDR_ORIG;
1819  ip6tun_record->validity_map |= IP6TUN_RECORD_TEREDO_HDR;
1820  goto recurse;
1821  }
1822  case TEREDO_AUTH_PRE_NO: {
1823  DBG("IP6TUN: teredo authentication header found\n");
1824  struct teredo_basic_auth_hdr *teredo_auth = (struct teredo_basic_auth_hdr*) next_hdr;
1825  hlen = TEREDO_AUTH_BASIC_HLEN + teredo_auth->idlen + teredo_auth->aulen;
1826  next_hdr += hlen;
1827  caplen -= hlen;
1828  ip6tun_record->teredo.headers |= TEREDO_HDR_AUTH;
1829  ip6tun_record->validity_map |= IP6TUN_RECORD_TEREDO_HDR;
1830  goto recurse;
1831  }
1832  default: {
1833  parse_retval = parse_ipv6 (next_hdr, caplen, record, ip6tun_record,1);
1834  if ((parse_retval == EXIT_SUCCESS) || (parse_retval == EXIT_TEREDO_TRAILER)) {
1835 
1836  if ((ip6tun_record->l3.addr.ipv6.src.ip6_addr16[0] == TEREDO_PREFIX_NO)
1837  || (ip6tun_record->l3.addr.ipv6.dst.ip6_addr16[0] == TEREDO_PREFIX_NO))
1838  {
1839  DBG("IP6TUN: valid teredo packet found\n");
1840  ip6tun_record->mechanism |= IP6TUN_TMECH_TEREDO;
1841  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1842  } else {
1843  // most likely there vas no ipv6 header just the first 4 bits were the same
1844  // possible dns traffic
1845  if ((record->l4.src_port == UDP_DNS_PORT) || (record->l4.dst_port == UDP_DNS_PORT)) {
1846  // invalidate ip6 record
1847  ip6tun_record->validity_map = IP6TUN_RECORD_INVALID;
1848  // reinit the hash so we dont break the flow
1849  MD5_Init (&md5);
1850  } else {
1851  // this is possible teredo traffic - check if there are some lokal link addresses present
1852  if (((ip6tun_record->l3.addr.ipv6.src.ip6_addr16[0] & IPV6_LL_MASK_NO) == IPV6_LL_MASK_NO)
1853  || ((ip6tun_record->l3.addr.ipv6.dst.ip6_addr16[0] & IPV6_LL_MASK_NO) == IPV6_LL_MASK_NO)) {
1854  // local link address found -> teredo
1855  DBG("IP6TUN: valid teredo packet found (LL address)\n");
1856  ip6tun_record->mechanism |= IP6TUN_TMECH_TEREDO;
1857  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1858  } else {
1859  // invalidate ip6 record
1860  ip6tun_record->validity_map = IP6TUN_RECORD_INVALID;
1861  // reinit the hash so we dont break the flow
1862  MD5_Init (&md5);
1863  }
1864  }
1865  }
1866  } else {
1867  return EXIT_FAILURE;
1868  }
1869  }
1870  }
1871 
1872  return EXIT_SUCCESS;
1873 }
1874 
1885 int parse_ayiya (unsigned char* buf, uint32_t caplen, flow_record_t *record, ip6tun_record_t *ip6tun_record)
1886 {
1887  struct ayiya_hdr *ayiya = (struct ayiya_hdr*) buf;
1888  int hlen;
1889  unsigned char* next_hdr = buf;
1890 
1891 
1892  if (((ayiya->gethshmeth) < 0x03) && ((ayiya->getautmeth) < 0x03)
1893  && ((ayiya->getopcode) < 0x08) && ((ayiya->next_header) == IPPROTO_41)) {
1894  // check the timestamp ayiya one is in utc - dont check it now
1895  //~ if (abs((record->flow_start / NSEC_IN_SEC) - ntohl(ayiya->timestamp)) < AYIYA_TIME_TOL)
1896  //~ {
1897  hlen = AYIYA_BASE_HLEN + (4 * ayiya->getsiglen) + (0x01 << ayiya->getidlen);
1898  next_hdr += hlen;
1899  caplen -= hlen;
1900 
1901  if (parse_ipv6 (next_hdr, caplen, record, ip6tun_record, 0) == EXIT_SUCCESS) {
1902  DBG("IP6TUN: valid ayiya packet found\n");
1903  ip6tun_record->mechanism |= IP6TUN_TMECH_AYIYA;
1904  ip6tun_record->validity_map |= IP6TUN_RECORD_TMECH;
1905  } else {
1906  return EXIT_FAILURE;
1907  }
1908  //~ } else {
1909  //~ return EXIT_FAILURE;
1910  //~ }
1911  } else {
1912  return EXIT_FAILURE;
1913  }
1914 
1915  return EXIT_SUCCESS;
1916 }
1917 

© 2012 Masaryk University - Institute of Computer Science - visit http://www.muni.cz/ics/