diff -rc tcpxtract-1.0.1/tcpxtract.c tcpxtract-1.0.1+vlan/tcpxtract.c *** tcpxtract-1.0.1/tcpxtract.c 2005-10-05 21:44:39.000000000 -0400 --- tcpxtract-1.0.1+vlan/tcpxtract.c 2008-02-27 14:56:14.364128000 -0500 *************** *** 46,51 **** --- 46,52 ---- #include "util.h" #include "confy.h" #include "search.h" + #include "vlan.h" #ifndef DEFAULT_CONFIG_FILE #define DEFAULT_CONFIG_FILE "/usr/local/etc/tcpxtract.conf" *************** *** 144,149 **** --- 145,157 ---- u_short uh_sum; /* checksum */ }; + + /* Update - david@vorant.com 27 Feb 2008 + * Try to detect whether the packet has an 802.1Q VLAN tag on it. If so, + * try to automatically skip the tag and treat it as regular TCP/IP traffic. + * Otherwise the handler won't process the packet. This is useful when, + * for example, you are monitoring a VLAN trunk line. + */ static void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) { /* Define pointers for packet's attributes */ *************** *** 152,158 **** --- 160,169 ---- struct sniff_tcp *tcp; /* The TCP header */ struct sniff_udp *udp; /* The UDP header */ uint8_t *payload; /* The data */ + u_char * my_packet; + my_packet = (u_char *) packet; + /* And define the size of the structures we're using */ int size_ethernet = sizeof(struct sniff_ethernet); int size_ip; *************** *** 169,180 **** /* -- Define our packet's attributes -- */ /* There is obviously a lot of unused potential here since we only want to dump */ ethernet = (struct sniff_ethernet*)(packet); ! ip = (struct sniff_ip*)(packet + size_ethernet); size_ip = ip->ip_hl << 2; ! tcp = (struct sniff_tcp*)(packet + size_ethernet + size_ip); size_tcp = tcp->th_off << 2; ! udp = (struct sniff_udp*)(packet + size_ethernet + size_ip); /* if it ain't IP, bail, hard */ if (ethernet->ether_type != 0x08) /* I think 0x08 is IP, at least it looks that way */ return; --- 180,201 ---- /* -- Define our packet's attributes -- */ /* There is obviously a lot of unused potential here since we only want to dump */ ethernet = (struct sniff_ethernet*)(packet); ! ! /* Check for VLAN tag */ ! if(ntohs(ethernet->ether_type) == VLAN_ETHERTYPE) { ! /* pkt haz VLAN tagz. DO NOT WANT! */ ! ethernet = (struct sniff_ethernet *) (my_packet + VLAN_HDRLEN); ! my_packet += VLAN_HDRLEN; ! } ! ! ip = (struct sniff_ip*)(my_packet + size_ethernet); size_ip = ip->ip_hl << 2; ! tcp = (struct sniff_tcp*)(my_packet + size_ethernet + size_ip); size_tcp = tcp->th_off << 2; ! udp = (struct sniff_udp*)(my_packet + size_ethernet + size_ip); + + /* if it ain't IP, bail, hard */ if (ethernet->ether_type != 0x08) /* I think 0x08 is IP, at least it looks that way */ return; *************** *** 193,206 **** payload_size = header->len - header_size; if (payload_size <= 0) return; ! payload = (uint8_t *)(packet + header_size); conn.ip_src = ip->ip_src.s_addr; conn.ip_dst = ip->ip_dst.s_addr; memcpy(conn.eth_src, ethernet->ether_shost, ETHER_ADDR_LEN); memcpy(conn.eth_dst, ethernet->ether_dhost, ETHER_ADDR_LEN); ! conn.port_src = tcp->th_sport; ! conn.port_dst = tcp->th_dport; if (sessions != NULL) { session = find_session(&sessions, &conn); --- 214,227 ---- payload_size = header->len - header_size; if (payload_size <= 0) return; ! payload = (uint8_t *)(my_packet + header_size); conn.ip_src = ip->ip_src.s_addr; conn.ip_dst = ip->ip_dst.s_addr; memcpy(conn.eth_src, ethernet->ether_shost, ETHER_ADDR_LEN); memcpy(conn.eth_dst, ethernet->ether_dhost, ETHER_ADDR_LEN); ! conn.port_src = ntohs(tcp->th_sport); ! conn.port_dst = ntohs(tcp->th_dport); if (sessions != NULL) { session = find_session(&sessions, &conn); *************** *** 243,249 **** struct bpf_program filter; /* hold compiled program */ bpf_u_int32 mask; /* subnet mask */ bpf_u_int32 net; /* ip */ ! char filter_app[] = ""; progname = strdup(argv[0]); sessions = NULL; --- 264,271 ---- struct bpf_program filter; /* hold compiled program */ bpf_u_int32 mask; /* subnet mask */ bpf_u_int32 net; /* ip */ ! char filter_app[1044] = ""; ! char temp_filter[1044] = ""; progname = strdup(argv[0]); sessions = NULL; *************** *** 311,316 **** --- 333,348 ---- yyparse(); + + /* Set up the pcap filter. Make sure to include 802.1Q traffic */ + if(filter_app[0] != 0) { + strcpy(temp_filter, "(ip or vlan) and "); + strncat(temp_filter, filter_app, 1024); + strcpy(filter_app, temp_filter); + } else { + strcpy(filter_app, "(ip or vlan)"); + } + if (optind < argc) { if (!dev) dev = argv[optind]; *************** *** 350,356 **** signal(SIGQUIT, quit_signal); signal(SIGINT, quit_signal); ! /* Compile and apply the filter */ if (pcap_compile(handle, &filter, filter_app, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter, pcap_geterr(handle)); return(2); --- 382,389 ---- signal(SIGQUIT, quit_signal); signal(SIGINT, quit_signal); ! /* Compile and apply the pcap filter */ ! if (pcap_compile(handle, &filter, filter_app, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter, pcap_geterr(handle)); return(2); diff -rc tcpxtract-1.0.1/vlan.h tcpxtract-1.0.1+vlan/vlan.h *** tcpxtract-1.0.1/vlan.h 2008-02-27 14:56:40.965775000 -0500 --- tcpxtract-1.0.1+vlan/vlan.h 2008-02-27 12:50:19.578081000 -0500 *************** *** 0 **** --- 1,5 ---- + /* 802.1Q VLAN tags are 4 bytes long. */ + #define VLAN_HDRLEN (4 * sizeof(char)) + + /* This is the decimal equivalent of the VLAN tag's ether frame type */ + #define VLAN_ETHERTYPE 33024