static void show_dlts_and_exit(pcap_t *pd) { int n_dlts; int *dlts = 0; const char *dlt_name; n_dlts = pcap_list_datalinks(pd, &dlts); if (n_dlts < 0) error("%s", pcap_geterr(pd)); else if (n_dlts == 0 || !dlts) error("No data link types."); (void) fprintf(stderr, "Data link types (use option -y to set):\n"); while (--n_dlts >= 0) { dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); if (dlt_name != NULL) { (void) fprintf(stderr, " %s (%s)", dlt_name, pcap_datalink_val_to_description(dlts[n_dlts])); /* * OK, does tcpdump handle that type? */ if (lookup_printer(dlts[n_dlts]) == NULL) (void) fprintf(stderr, " (not supported)"); putchar('\n'); } else { (void) fprintf(stderr, " DLT %d (not supported)\n", dlts[n_dlts]); } } free(dlts); exit(0); }
static void print_datalinks(const char *dev) { int *linktypes; int err, i, nlinktypes; char errbuf[PCAP_ERRBUF_SIZE]; pcap_t *handle; handle = pcap_create(dev, errbuf); if(!handle) return; err = pcap_activate(handle); if(err) return; nlinktypes = pcap_list_datalinks(handle, &linktypes); if(nlinktypes > 0) printf(" Linktypes:%s", options.verbose > 1 ? "\n" : " "); if(options.verbose > 1) for(i = 0; i < nlinktypes; ++i) printf(" %-20s %s\n" , pcap_datalink_val_to_name(linktypes[i]) , pcap_datalink_val_to_description(linktypes[i])); else for(i = 0; i < nlinktypes; ++i) printf("%s%s", pcap_datalink_val_to_name(linktypes[i]) , i + 1 > nlinktypes ? ", " : "\n"); pcap_free_datalinks(linktypes); pcap_close(handle); }
pcap_parser_file * pcap_file_open(char *filename) { char errbuf[PCAP_ERRBUF_SIZE]; pcap_parser_file *thefile; struct stat result; thefile = malloc(sizeof(pcap_parser_file)); thefile->packetnum = 0; thefile->dnspacketnum = 0; if (stat(filename, &result) != 0) { fatal("File %s does not exist or is not accessible: %s", filename, strerror(errno)); } thefile->size = result.st_size; thefile->creation = result.st_ctime; thefile->firstpacket.tv_sec = 0; thefile->firstpacket.tv_usec = 0; thefile->lastpacket.tv_sec = 0; thefile->lastpacket.tv_usec = 0; thefile->handle = pcap_open_offline(filename, errbuf); if (thefile->handle == NULL) { fatal("Couldn't open file %s: %s\n", filename, errbuf); } thefile->datalink = pcap_datalink(thefile->handle); thefile->snaplen = pcap_snapshot(thefile->handle); if (verbose) { fprintf(stdout, "Analyzing %s, version %i.%i, type %s, max packet size %u bytes...\n", filename, pcap_major_version(thefile->handle), pcap_minor_version(thefile->handle), pcap_datalink_val_to_description(thefile->datalink), thefile->snaplen); } return thefile; }
static int get_l2_len(const unsigned char *packet, const int pkt_len, const int datalink) { struct ethernet_hdr *eth_hdr; switch (datalink) { case DLT_RAW: return 0; break; case DLT_EN10MB: eth_hdr = (struct ethernet_hdr *)packet; switch (ntohs(eth_hdr->ether_type)) { case ETHERTYPE_VLAN: return 18; break; default: return 14; break; } break; case DLT_C_HDLC: return CISCO_HDLC_LEN; break; case DLT_LINUX_SLL: return SLL_HDR_LEN; break; default: tc_log_info(LOG_ERR, 0, "unsupported DLT type: %s (0x%x)", pcap_datalink_val_to_description(datalink), datalink); break; } return -1; }
static void show_dlts_and_exit(const char *device, pcap_t *pd) { int n_dlts; int *dlts = 0; const char *dlt_name; n_dlts = pcap_list_datalinks(pd, &dlts); if (n_dlts < 0) error("%s", pcap_geterr(pd)); else if (n_dlts == 0 || !dlts) error("No data link types."); /* * If the interface is known to support monitor mode, indicate * whether these are the data link types available when not in * monitor mode, if -I wasn't specified, or when in monitor mode, * when -I was specified (the link-layer types available in * monitor mode might be different from the ones available when * not in monitor mode). */ if (supports_monitor_mode) (void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n", device, Iflag ? "when in monitor mode" : "when not in monitor mode"); else (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n", device); while (--n_dlts >= 0) { dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); if (dlt_name != NULL) { (void) fprintf(stderr, " %s (%s)", dlt_name, pcap_datalink_val_to_description(dlts[n_dlts])); /* * OK, does tcpdump handle that type? */ if (lookup_printer(dlts[n_dlts]) == NULL && lookup_ndo_printer(dlts[n_dlts]) == NULL) (void) fprintf(stderr, " (printing not supported)"); putchar('\n'); } else { (void) fprintf(stderr, " DLT %d (printing not supported)\n", dlts[n_dlts]); } } free(dlts); exit(0); }
/** * returns the L2 protocol (IP, ARP, etc) * or 0 for error */ uint16_t get_l2protocol(const u_char *pktdata, const int datalen, const int datalink) { eth_hdr_t *eth_hdr; vlan_hdr_t *vlan_hdr; hdlc_hdr_t *hdlc_hdr; sll_hdr_t *sll_hdr; uint16_t ether_type; assert(pktdata); assert(datalen); switch (datalink) { case DLT_RAW: return ETHERTYPE_IP; break; case DLT_EN10MB: eth_hdr = (eth_hdr_t *)pktdata; ether_type = ntohs(eth_hdr->ether_type); switch (ether_type) { case ETHERTYPE_VLAN: /* 802.1q */ vlan_hdr = (vlan_hdr_t *)pktdata; return ntohs(vlan_hdr->vlan_len); default: return ether_type; /* yes, return it in host byte order */ } break; case DLT_C_HDLC: hdlc_hdr = (hdlc_hdr_t *)pktdata; return hdlc_hdr->protocol; break; case DLT_LINUX_SLL: sll_hdr = (sll_hdr_t *)pktdata; return sll_hdr->sll_protocol; break; default: errx(-1, "Unable to process unsupported DLT type: %s (0x%x)", pcap_datalink_val_to_description(datalink), datalink); } return 0; }
static void tcpeek_init_pcap(void) { char *ifname, errmsg[PCAP_ERRBUF_SIZE], expression[] = "tcp or icmp"; struct bpf_program bpf; if(strisempty(g.option.ifname)) { ifname = pcap_lookupdev(errmsg); if(!ifname) { error_abort("%s", errmsg); } strncpy(g.option.ifname, ifname, sizeof(g.option.ifname) - 1); } g.pcap.pcap = pcap_create(g.option.ifname, errmsg); if(!g.pcap.pcap) { error_abort("%s", errmsg); } if(pcap_set_buffer_size(g.pcap.pcap, g.option.buffer * 1024 * 1024) != 0) { error_abort("%s", "can not set buffer size"); } if(pcap_set_snaplen(g.pcap.pcap, DEFAULT_PCAP_SNAPLEN) != 0) { error_abort("%s", "can not set snaplen"); } if(pcap_set_promisc(g.pcap.pcap, g.option.promisc) != 0) { error_abort("%s", "can not set promiscuous mode"); } if(pcap_set_timeout(g.pcap.pcap, 1) != 0) { error_abort("%s", "can not set timeout"); } if(pcap_activate(g.pcap.pcap) != 0) { error_abort("%s", pcap_geterr(g.pcap.pcap)); } if(pcap_compile(g.pcap.pcap, &bpf, expression, 0, 0) == -1) { error_abort("%s '%s'", pcap_geterr(g.pcap.pcap), expression); } if(pcap_setfilter(g.pcap.pcap, &bpf) == -1){ error_abort("%s", pcap_geterr(g.pcap.pcap)); } pcap_freecode(&bpf); g.pcap.snapshot = pcap_snapshot(g.pcap.pcap); g.pcap.datalink = pcap_datalink(g.pcap.pcap); if(g.pcap.datalink != DLT_EN10MB && g.pcap.datalink != DLT_LINUX_SLL) { error_abort("not support datalink %s (%s)", pcap_datalink_val_to_name(g.pcap.datalink), pcap_datalink_val_to_description(g.pcap.datalink) ); } }
/** * returns the length in number of bytes of the L2 header, or -1 on error */ int get_l2len(const u_char *pktdata, const int datalen, const int datalink) { eth_hdr_t *eth_hdr; assert(pktdata); assert(datalen); switch (datalink) { case DLT_RAW: /* pktdata IS the ip header! */ return 0; break; case DLT_EN10MB: eth_hdr = (struct tcpr_ethernet_hdr *)pktdata; switch (ntohs(eth_hdr->ether_type)) { case ETHERTYPE_VLAN: return 18; break; default: return 14; break; } break; case DLT_C_HDLC: return CISCO_HDLC_LEN; break; case DLT_LINUX_SLL: return SLL_HDR_LEN; break; default: errx(-1, "Unable to process unsupported DLT type: %s (0x%x)", pcap_datalink_val_to_description(datalink), datalink); break; } return -1; /* we shouldn't get here */ }
int main ( int argc , char *argv[] ) { /* parameters parsing */ int c; /* pcap */ char errbuf[PCAP_ERRBUF_SIZE]; struct bpf_program fp; char filter_exp[] = "ip and tcp"; char *source = 0; char *filter = filter_exp; const unsigned char *packet = 0; struct pcap_pkthdr header; /* packet dissection */ struct ip *ip; unsigned int error; /* extra */ unsigned int ipf,tcps; fprintf( stderr, "\n###########################" ); fprintf( stderr, "\n# libntoh Example #" ); fprintf( stderr, "\n# ----------------------- #" ); fprintf( stderr, "\n# Written by Chema Garcia #" ); fprintf( stderr, "\n# ----------------------- #" ); fprintf( stderr, "\n# http://safetybits.net #" ); fprintf( stderr, "\n# [email protected] #" ); fprintf( stderr, "\n###########################\n" ); fprintf( stderr, "\n[i] libntoh version: %s\n", ntoh_version() ); if ( argc < 3 ) { fprintf( stderr, "\n[+] Usage: %s <options>\n", argv[0] ); fprintf( stderr, "\n+ Options:" ); fprintf( stderr, "\n\t-i | --iface <val> -----> Interface to read packets from" ); fprintf( stderr, "\n\t-f | --file <val> ------> File path to read packets from" ); fprintf( stderr, "\n\t-F | --filter <val> ----> Capture filter (default: \"ip and tcp\")" ); fprintf( stderr, "\n\t-c | --client ----------> Receive client data"); fprintf( stderr, "\n\t-s | --server ----------> Receive server data\n\n"); exit( 1 ); } /* check parameters */ while ( 1 ) { int option_index = 0; static struct option long_options[] = { { "iface" , 1 , 0 , 'i' } , { "file" , 1 , 0 , 'f' } , { "filter" , 1 , 0 , 'F' } , { "client" , 0 , 0 , 'c' }, { "server" , 0 , 0 , 's' }, { 0 , 0 , 0 , 0 } }; if ( ( c = getopt_long( argc, argv, "i:f:F:cs", long_options, &option_index ) ) < 0 ) break; switch ( c ) { case 'i': source = optarg; handle = pcap_open_live( optarg, 65535, 1, 0, errbuf ); break; case 'f': source = optarg; handle = pcap_open_offline( optarg, errbuf ); break; case 'F': filter = optarg; break; case 'c': receive |= RECV_CLIENT; break; case 's': receive |= RECV_SERVER; break; } } if ( !receive ) receive = (RECV_CLIENT | RECV_SERVER); if ( !handle ) { fprintf( stderr, "\n[e] Error loading %s: %s\n", source, errbuf ); exit( -1 ); } if ( pcap_compile( handle, &fp, filter, 0, 0 ) < 0 ) { fprintf( stderr, "\n[e] Error compiling filter \"%s\": %s\n\n", filter, pcap_geterr( handle ) ); pcap_close( handle ); exit( -2 ); } if ( pcap_setfilter( handle, &fp ) < 0 ) { fprintf( stderr, "\n[e] Cannot set filter \"%s\": %s\n\n", filter, pcap_geterr( handle ) ); pcap_close( handle ); exit( -3 ); } pcap_freecode( &fp ); /* verify datalink */ if ( pcap_datalink( handle ) != DLT_EN10MB ) { fprintf ( stderr , "\n[e] libntoh is independent from link layer, but this example only works with ethernet link layer\n"); pcap_close ( handle ); exit ( -4 ); } fprintf( stderr, "\n[i] Source: %s / %s", source, pcap_datalink_val_to_description( pcap_datalink( handle ) ) ); fprintf( stderr, "\n[i] Filter: %s", filter ); fprintf( stderr, "\n[i] Receive data from client: "); if ( receive & RECV_CLIENT ) fprintf( stderr , "Yes"); else fprintf( stderr , "No"); fprintf( stderr, "\n[i] Receive data from server: "); if ( receive & RECV_SERVER ) fprintf( stderr , "Yes"); else fprintf( stderr , "No"); signal( SIGINT, &shandler ); signal( SIGTERM, &shandler ); /*******************************************/ /** libntoh initialization process starts **/ /*******************************************/ ntoh_init (); if ( ! (tcp_session = ntoh_tcp_new_session ( 0 , 0 , &error ) ) ) { fprintf ( stderr , "\n[e] Error %d creating TCP session: %s" , error , ntoh_get_errdesc ( error ) ); exit ( -5 ); } fprintf ( stderr , "\n[i] Max. TCP streams allowed: %d" , ntoh_tcp_get_size ( tcp_session ) ); if ( ! (ipv4_session = ntoh_ipv4_new_session ( 0 , 0 , &error )) ) { ntoh_tcp_free_session ( tcp_session ); fprintf ( stderr , "\n[e] Error %d creating IPv4 session: %s" , error , ntoh_get_errdesc ( error ) ); exit ( -6 ); } fprintf ( stderr , "\n[i] Max. IPv4 flows allowed: %d\n\n" , ntoh_ipv4_get_size ( ipv4_session ) ); /* capture starts */ while ( ( packet = pcap_next( handle, &header ) ) != 0 ) { /* get packet headers */ ip = (struct ip*) ( packet + sizeof ( struct ether_header ) ); if ( (ip->ip_hl * 4 ) < sizeof(struct ip) ) continue; /* it is an IPv4 fragment */ if ( NTOH_IPV4_IS_FRAGMENT(ip->ip_off) ) send_ipv4_fragment ( ip , &ipv4_callback ); /* or a TCP segment */ else if ( ip->ip_p == IPPROTO_TCP ) send_tcp_segment ( ip , &tcp_callback ); } tcps = ntoh_tcp_count_streams( tcp_session ); ipf = ntoh_ipv4_count_flows ( ipv4_session ); /* no streams left */ if ( ipf + tcps > 0 ) { fprintf( stderr, "\n\n[+] There are currently %i stored TCP stream(s) and %i IPv4 flow(s). You can wait them to get closed or press CTRL+C\n" , tcps , ipf ); pause(); } shandler( 0 ); //dummy return return 0; }
void capture_init(char *interface) { char device[20]; //char device[]="wlan0"; strcpy(device,interface); char errbuf[PCAP_ERRBUF_SIZE]; /* error buffer */ unsigned char dev_macAddress[17]; char *filter_exp; unsigned char *dev; filter_exp= (char *)malloc (200); int check_monitor_mode; // strcat(filter_exp,"ether src "); //char filter_exp[] = "ether src 00:1e:2a:52:ec:9c"; /* filter expression [3] */ struct bpf_program fp; /* compiled filter program (expression) */ bpf_u_int32 mask; /* subnet mask */ bpf_u_int32 net; /* ip */ // int num_packets = 1000; /* number of packets to capture */ int num_packets = 0; /* INFINITY */ int data_linkValue; //print_app_banner(); dev =(unsigned char *)device; /* if (mkfifo(INCOME_PIPE, 0777) !=0 ) { PRINT_DEBUG("MKFIFO Failed \n"); exit(EXIT_FAILURE); } */ /* has to run without return check to work as blocking call */ /** It blocks until the other communication side opens the pipe */ income_pipe_fd = open(INCOME_PIPE, O_WRONLY); if (income_pipe_fd == -1) { PRINT_DEBUG("Income Pipe failure \n"); exit(EXIT_FAILURE); } /* Build the filter expression based on the mac address of the passed * device name */ //getDevice_MACAddress(dev_macAddress,dev); //strcat(filter_exp,dev_macAddress); //strcat(filter_exp," not arp and not tcp"); //strcat(filter_exp," and udp and"); strcat(filter_exp,"dst host 127.0.0.1"); /* get network number and mask associated with capture device */ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf); net = 0; mask = 0; } /* print capture info */ printf("Device: %s\n", dev); printf("Number of packets: %d\n", num_packets); printf("Filter expression: %s\n", filter_exp); /* open capture device */ capture_handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf); if (capture_handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); exit(EXIT_FAILURE); } /* make sure we're capturing on an Ethernet device [2] */ data_linkValue = pcap_datalink(capture_handle); if (data_linkValue != DLT_EN10MB) { fprintf(stderr, "%s is not an Ethernet\n", dev); exit(EXIT_FAILURE); } printf("Datalink layer Description: %s \n",pcap_datalink_val_to_description(data_linkValue)); /* compile the filter expression */ if (pcap_compile(capture_handle, &fp, filter_exp, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(capture_handle)); exit(EXIT_FAILURE); } /* apply the compiled filter */ if (pcap_setfilter(capture_handle, &fp) == -1) { fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(capture_handle)); exit(EXIT_FAILURE); } check_monitor_mode = pcap_can_set_rfmon(capture_handle); if (check_monitor_mode ) {PRINT_DEBUG("\n Monitor mode can be set\n"); } else if (check_monitor_mode ==0 ) { PRINT_DEBUG("\n Monitor mode could not be set\n"); } else PRINT_DEBUG("\n check_monior_mode value is %d \n",check_monitor_mode); /* now we can set our callback function */ pcap_loop(capture_handle, num_packets, got_packet,(u_char *) NULL); /* cleanup */ pcap_freecode(&fp); free(filter_exp); } // end of capture_init
void add_iface(char *iface) { char errbuf[PCAP_ERRBUF_SIZE]; char const *filter; struct iface_config *ifc; int rc; if (cfg.v4_flag) filter = ip4_filter; else if (cfg.v6_flag) filter = ip6_filter; else filter = def_filter; ifc = (struct iface_config *) calloc(1, sizeof(struct iface_config)); ifc->name = iface; ifc->pcap_handle = pcap_open_live(iface, SNAP_LEN, cfg.promisc_flag, 1000, errbuf); if (ifc->pcap_handle == NULL) { log_msg(LOG_WARNING, "Skipping interface %s, %s", iface, errbuf); goto error; } rc = pcap_datalink(ifc->pcap_handle); if (rc != DLT_EN10MB) { log_msg(LOG_WARNING, "Skipping interface %s, invalid data link layer %s (%s).", iface, pcap_datalink_val_to_name(rc), pcap_datalink_val_to_description(rc)); goto error_pcap; } rc = pcap_compile(ifc->pcap_handle, &ifc->pcap_filter, filter, 0, 0); if (rc == -1) { log_msg(LOG_WARNING, "Skipping interface %s, %s", iface, pcap_geterr(ifc->pcap_handle)); goto error_pcap; } rc = pcap_setfilter(ifc->pcap_handle, &ifc->pcap_filter); if (rc == -1) { log_msg(LOG_WARNING, "Skipping iface %s, %s", iface, pcap_geterr(ifc->pcap_handle)); goto error_filter; } rc = pcap_fileno(ifc->pcap_handle); #if HAVE_LIBEVENT2 ifc->event = event_new(cfg.eb, rc, EV_READ|EV_PERSIST, read_cb, ifc); if(!ifc->event) log_msg(LOG_ERR, "%s: event_new(...)", __FUNCTION__); event_add(ifc->event, NULL); #else event_set(&ifc->event, rc, EV_READ|EV_PERSIST, read_cb, ifc); event_add(&ifc->event, NULL); #endif if (cfg.hashsize < 1 || cfg.hashsize > 65536) log_msg(LOG_ERR, "%s: hash size (%d) must be >= 1 and <= 65536", __FUNCTION__, cfg.hashsize); if (cfg.ratelimit) { ifc->cache = calloc(cfg.hashsize, sizeof(*ifc->cache)); if (!ifc->cache) log_msg(LOG_ERR, "%s: unable to allocate memory for hash cache", __FUNCTION__); } ifc->next = cfg.interfaces; cfg.interfaces = ifc; log_msg(LOG_DEBUG, "Opened interface %s (%s)", iface, pcap_datalink_val_to_description(pcap_datalink(ifc->pcap_handle))); return; error_filter: pcap_freecode(&ifc->pcap_filter); error_pcap: pcap_close(ifc->pcap_handle); error: free(ifc); }
void capture_init() { char device[]="wlan0"; char errbuf[PCAP_ERRBUF_SIZE]; /* error buffer */ unsigned char dev_macAddress[17]; char *filter_exp; unsigned char *dev; filter_exp= (char *)malloc (200); strcat(filter_exp,"ether src "); //char filter_exp[] = "ether src 00:1e:2a:52:ec:9c"; /* filter expression [3] */ struct bpf_program fp; /* compiled filter program (expression) */ bpf_u_int32 mask; /* subnet mask */ bpf_u_int32 net; /* ip */ int num_packets = 10; /* number of packets to capture */ int data_linkValue; //print_app_banner(); dev =(unsigned char *)device; /* Build the filter expression based on the mac address of the passed * device name */ getDevice_MACAddress(dev_macAddress,dev); strcat(filter_exp,dev_macAddress); strcat(filter_exp," and not arp"); strcat(filter_exp," and dst host 192.168.1.28"); /* get network number and mask associated with capture device */ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf); net = 0; mask = 0; } /* print capture info */ printf("Device: %s\n", dev); printf("Number of packets: %d\n", num_packets); printf("Filter expression: %s\n", filter_exp); /* open capture device */ capture_handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf); if (capture_handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); exit(EXIT_FAILURE); } /* make sure we're capturing on an Ethernet device [2] */ data_linkValue = pcap_datalink(capture_handle); if (data_linkValue != DLT_EN10MB) { fprintf(stderr, "%s is not an Ethernet\n", dev); exit(EXIT_FAILURE); } printf("Datalink layer Description: %s \n",pcap_datalink_val_to_description(data_linkValue)); /* compile the filter expression */ if (pcap_compile(capture_handle, &fp, filter_exp, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(capture_handle)); exit(EXIT_FAILURE); } /* apply the compiled filter */ if (pcap_setfilter(capture_handle, &fp) == -1) { fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(capture_handle)); exit(EXIT_FAILURE); } /* now we can set our callback function */ pcap_loop(capture_handle, num_packets, got_packet_udp, NULL); /* cleanup */ pcap_freecode(&fp); free(filter_exp); }
struct dns_packet * get_next_packet(struct dns_packet *decoded, pcap_parser_file * input) { /* Misc. variables */ char fqdn[MAX_NAME + 1]; unsigned int fqdn_length; /* pcap-related variables */ const uint8_t *packet; /* The actual packet */ struct pcap_pkthdr header; /* The header that pcap gives us */ const struct sniff_ethernet *ethernet; /* The ethernet header */ unsigned short ethertype; const struct sniff_ipv4 *ipv4; /* The IP header */ const struct sniff_ipv6 *ipv6; const struct sniff_udp *udp; /* The UDP header */ const struct sniff_dns *dns; u_int size_ip; u_int size_layer2; unsigned short ip_version; uint32_t family; const uint8_t *qsection; uint8_t labelsize; uint16_t add_type; uint16_t edns_size; uint16_t extended_rcode_and_version; uint16_t zpart; const uint8_t *sectionptr; const uint8_t *where_am_i; /* Cursor in packet */ bool end_of_name; unsigned int size_header; bool end_of_headers, fragmented; uint8_t next_v6_header; const struct sniff_eh *eh; /* The IPv6 extension header, if present */ const struct sniff_frag *frag; assert(decoded->qname != NULL); /* Grab next packet */ decoded->rank = input->packetnum; next_packet: packet = (uint8_t *) pcap_next(input->handle, &header); if (packet == NULL) { /* End of file */ return NULL; } input->packetnum++; decoded->length = header.len; decoded->captured_length = header.caplen; decoded->date = header.ts; if (input->firstpacket.tv_sec == 0 && input->firstpacket.tv_usec == 0) { input->firstpacket = header.ts; } input->lastpacket = header.ts; if (input->datalink == DLT_EN10MB) { size_layer2 = SIZE_ETHERNET; ethernet = (struct sniff_ethernet *) (packet); ethertype = ntohs(ethernet->ether_type); if (ethertype == VLAN_ETHERTYPE) { packet += 4; ethernet = (struct sniff_ethernet *) (packet); ethertype = ntohs(ethernet->ether_type); } if (ethertype == IPv6_ETHERTYPE) { ip_version = 6; } else if (ethertype == IPv4_ETHERTYPE) { ip_version = 4; } else { /* Ignore other Ethernet types */ goto next_packet; } } else if (input->datalink == DLT_LOOP) { size_layer2 = SIZE_LOOP; family = (ntohl(*((uint32_t *) packet))); if (family == PF_INET6) { ip_version = 6; } else if (family == PF_INET) { ip_version = 4; } else { /* Ignore other packet types */ goto next_packet; } } else { fatal("Unsupported data link type %s (%i)\n", pcap_datalink_val_to_description(input->datalink), input->datalink); } if (ip_version == 6) { ipv6 = (struct sniff_ipv6 *) (packet + size_layer2); size_ip = SIZE_IPv6; assert(IPV6_VERSION(ipv6) == 6); next_v6_header = ipv6->ip_nxt; size_header = 0; where_am_i = where_am_i + SIZE_IPv6; end_of_headers = false; fragmented = false; while (!end_of_headers) { /* Extension headers defined in RFC 2460, section 4 */ if (next_v6_header == 0 || next_v6_header == 43 || next_v6_header == 50 || next_v6_header == 51 || next_v6_header == 60) { eh = (struct sniff_eh *) (where_am_i); next_v6_header = eh->eh_next; size_header = eh->eh_length; } /* Fragment */ else if (next_v6_header == 44) { fragmented = 1; frag = (struct sniff_frag *) (where_am_i); next_v6_header = frag->frag_next; size_header = SIZE_FRAGMENT_HDR; } else { end_of_headers = true; } where_am_i = where_am_i + size_header; size_ip += size_header; if ((size_layer2 + size_ip) > decoded->captured_length) { if (verbose) { fprintf(stdout, "Warning: ignoring packet #%li because IPv6 headers too large\n", input->packetnum); } goto next_packet; } } if (fragmented && FRAG_OFFSET(frag) == 0) { goto next_packet; } } else if (ip_version == 4) { ipv4 = (struct sniff_ipv4 *) (packet + size_layer2); size_ip = IP_HL(ipv4) * 4; assert(IPV4_VERSION(ipv4) == 4); } else { /* Should never happen */ assert(0); } if ((ip_version == 6 && next_v6_header == UDP) || (ip_version == 4 && ipv4->ip_p == UDP)) { if (ip_version == 6) { assert(decoded->src != NULL); assert(decoded->dst != NULL); inet_ntop(AF_INET6, &ipv6->ip_src, decoded->src, INET6_ADDRSTRLEN); inet_ntop(AF_INET6, &ipv6->ip_dst, decoded->dst, INET6_ADDRSTRLEN); } else if (ip_version == 4) { assert(decoded->src != NULL); assert(decoded->dst != NULL); inet_ntop(AF_INET, &ipv4->ip_src, decoded->src, INET_ADDRSTRLEN); inet_ntop(AF_INET, &ipv4->ip_dst, decoded->dst, INET_ADDRSTRLEN); } else { goto next_packet; } udp = (struct sniff_udp *) (packet + size_layer2 + size_ip); decoded->src_port = (u_short) ntohs(udp->sport); decoded->dst_port = (u_short) ntohs(udp->dport); if (decoded->src_port == DNS_PORT || decoded->dst_port == DNS_PORT) { if (maxpackets > 0 && input->dnspacketnum >= maxpackets) { return NULL; } dns = (struct sniff_dns *) (packet + size_layer2 + size_ip + SIZE_UDP); decoded->query = DNS_QR(dns) == 0 ? true : false; decoded->query_id = dns->query_id; decoded->opcode = DNS_OPCODE(dns); decoded->returncode = DNS_RCODE(dns); decoded->aa = DNS_AA(dns) ? true : false; decoded->tc = DNS_TC(dns) ? true : false; decoded->rd = DNS_RD(dns) ? true : false; decoded->ra = DNS_RA(dns) ? true : false; decoded->ancount = ntohs(dns->ancount); decoded->nscount = ntohs(dns->nscount); decoded->arcount = ntohs(dns->arcount); qsection = (uint8_t *) (packet + size_layer2 + size_ip + SIZE_UDP + SIZE_DNS); fqdn[0] = '\0'; end_of_name = false; for (sectionptr = qsection; !end_of_name;) { CHECK_SECTIONPTR(1); labelsize = (uint8_t) * sectionptr; if (labelsize == 0) { sectionptr++; end_of_name = true; } else if (labelsize > 63) { /* It can be an error/attack or it can be compression (RFC 1035, * section 4.1.4). Today, we ignore packets with compression (we * just parse the question section, anyway). * * * * * * * * * TODO */ if (verbose) { fprintf(stdout, "Warning: ignoring packet #%li because labelsize > 63\n", input->packetnum); } goto next_packet; } else { CHECK_SECTIONPTR(labelsize); if (strlen(fqdn) == 0) { strncpy(fqdn, (char *) sectionptr + 1, labelsize); fqdn_length = labelsize; } else { fqdn_length = strlen(fqdn); if (fqdn_length + labelsize > MAX_NAME) { if (verbose) { fprintf(stdout, "Warning: ignoring packet #%li because malformed (FQDN length is already %i and label size is %i bytes)\n", input->packetnum, fqdn_length, labelsize); }; goto next_packet; } strncat(fqdn, ".", 1); strncat(fqdn, (char *) sectionptr + 1, labelsize); fqdn_length += (labelsize + 1); } if (fqdn_length > MAX_NAME) { if (verbose) { fprintf(stdout, "Warning: ignoring packet #%li because FQDN length > %i\n", input->packetnum, MAX_NAME); } goto next_packet; } fqdn[fqdn_length] = '\0'; sectionptr = sectionptr + labelsize + 1; CHECK_SECTIONPTR(0); } } CHECK_SECTIONPTR(2); strcpy(decoded->qname, fqdn); #ifdef PICKY_WITH_ALIGNMENT decoded->qtype = unaligned_uint16(sectionptr); #else decoded->qtype = ntohs(*((uint16_t *) sectionptr)); #endif sectionptr += 2; CHECK_SECTIONPTR(2); #ifdef PICKY_WITH_ALIGNMENT decoded->qclass = unaligned_uint16(sectionptr); #else decoded->qclass = ntohs(*((uint16_t *) sectionptr)); #endif sectionptr += 2; decoded->edns0 = false; if (decoded->query) { edns_size = 0; if (dns->ancount == 0 && dns->nscount == 0) { /* Probably by far the most common case in queries... */ if (dns->arcount != 0) { /* There is an additional section. * Probably the OPT * * * * * * * * * * * * * of EDNS */ CHECK_SECTIONPTR(1); labelsize = (uint8_t) * sectionptr; if (labelsize == 0) { /* Yes, EDNS0 */ sectionptr += 1; CHECK_SECTIONPTR(2); #ifdef PICKY_WITH_ALIGNMENT add_type = unaligned_uint16(sectionptr); #else add_type = ntohs(*((uint16_t *) sectionptr)); #endif sectionptr += 2; CHECK_SECTIONPTR(2); if (add_type == OPT) { #ifdef PICKY_WITH_ALIGNMENT edns_size = unaligned_uint16(sectionptr); #else edns_size = ntohs(*((uint16_t *) sectionptr)); #endif decoded->edns0 = true; /* RFC 2671 */ sectionptr += 2; CHECK_SECTIONPTR(2); #ifdef PICKY_WITH_ALIGNMENT extended_rcode_and_version = unaligned_uint16(sectionptr); #else extended_rcode_and_version = ntohs(*((uint16_t *) sectionptr)); #endif sectionptr += 2; CHECK_SECTIONPTR(2); #ifdef PICKY_WITH_ALIGNMENT zpart = unaligned_uint16(sectionptr); #else zpart = ntohs(*((uint16_t *) sectionptr)); #endif /* RFC 3225 */ decoded->do_dnssec = DNS_DO_DNSSEC(zpart) ? true : false; } sectionptr += 2; /* TODO: dissect the RDATA to find things like the option code (such as 3 for NSID) http://www.iana.org/assignments/dns-parameters */ } } } } if (decoded->edns0) { decoded->edns0_size = (unsigned int) edns_size; } input->dnspacketnum++; return decoded; } } goto next_packet; }
int main(int argc,char **argv){ char errbuf[PCAP_ERRBUF_SIZE]; //256 char *device; int c,verbose=0; int num; int ret; bpf_u_int32 netp,maskp; struct in_addr netaddr; struct bpf_program fp; //char *filter=""; //char *filter="wlan src c0:cb:38:87:f9:bb and wlan dst 00:1e:65:d1:16:fa"; char *filter="wlan host 00:1e:65:d1:16:fa"; file=fopen(PATH,"w"); if(file==NULL) { printf("open file error\n"); return -1; } fprintf(file,"%s\n","#seqnum:timestamps:rssi"); while((c=getopt(argc,argv,"i:v"))!=-1){ switch(c){ case 'i': device=optarg; break; case 'v': verbose=1; break; } } signal(SIGINT,ctrl_c); if(device==NULL){ if((device=pcap_lookupdev(errbuf))==NULL) { fprintf(stderr,"lookupdev:%s\n",errbuf); return -1; } } handle=pcap_open_live(device,BUFSIZ,1,0,errbuf); if(handle==NULL) { fprintf(stderr,"open_live:%s\n",errbuf); return -1; } if(verbose){ printf("using device:%s\n",device); num=pcap_datalink(handle); printf("%s\n",pcap_datalink_val_to_name(num)); printf("%s\n",pcap_datalink_val_to_description(num)); } //used when broadcast /*if(pcap_lookupnet(device,&netp,&maskp,errbuf)==-1) { fprintf(stderr,"lookupnet:%s\n",errbuf); return -1; } netaddr.s_addr=netp; printf("addr:%s\n",inet_ntoa(netaddr));*/ if(pcap_compile(handle,&fp,filter,0,0)==-1) { printf("pcap_compile:%s\n",pcap_geterr(handle)); return -1; } if(pcap_setfilter(handle,&fp)==-1) { printf("pcap_setfilter:%s\n",pcap_geterr(handle)); return -1; } pcap_freecode(&fp); if((ret=pcap_loop(handle,-1,packet_process,NULL))<0) { if(ret==-1) { printf("pcap_loop:%s\n",pcap_geterr(handle)); return -1; } } //printf("r_sum:%d,s_sum:%d\n",r_sum,s_sum); pcap_close(handle); return 0; }
int main (int argc , char *argv[]) { signal( SIGINT, &shandler ); signal( SIGTERM, &shandler ); signal( SIGSEGV, &shandler ); write(2, "\n\t\t######################################", 41); write(2, "\n\t\t# Dump HTTP Sigs #", 41); write(2, "\n\t\t# ---------------------------------- #", 41); write(2, "\n\t\t# Written by Ernest Richards #", 41); write(2, "\n\t\t# Based on code from Chema Garcia #", 41); write(2, "\n\t\t# ---------------------------------- #", 41); write(2, "\n\t\t# Github.com/ernesto341/ais-research #", 41); write(2, "\n\t\t######################################\n", 42); write(2, "\n\t\tX ----- Active ----- X\n\n", 43); if (DEBUG) { sprintf(buf, "\n[i] libntoh version: %s\n", ntoh_version()); write(2, buf, strlen(buf)); } if ( argc < 3 ) { sprintf(buf, "\n[+] Usage: %s <options>\n", argv[0]); write(2, buf, strlen(buf)); write(2, "\n+ Options:", 11); // 28 write(2, "\n\t-i | --iface <val> -----> Interface to read packets from", 58); write(2, "\n\t-f | --file <val> ------> File path to read packets from", 58); write(2, "\n\t-F | --filter <val> ----> Capture filter (must contain \"tcp\" or \"ip\")", 71); write(2, "\n\t-c | --client ----------> Receive client data only", 52); write(2, "\n\t-s | --server ----------> Receive server data only\n\n", 54); exit(1); } /* parameters parsing */ int32_t c = 0; /* pcap */ char errbuf[PCAP_ERRBUF_SIZE]; struct bpf_program fp; char filter_exp[] = "ip"; char *source = 0; char *filter = filter_exp; const unsigned char *packet = 0; struct pcap_pkthdr header; /* packet dissection */ struct ip *ip; uint32_t error = 0; /* extra */ uint32_t ipf, tcps; /* check parameters */ while ( c >= 0 ) { int32_t option_index = 0; static struct option long_options[] = { { "iface" , 1 , 0 , 'i' }, { "file" , 1 , 0 , 'f' }, { "filter" , 1 , 0 , 'F' }, { "client" , 0 , 0 , 'c' }, { "server" , 0 , 0 , 's' }, { 0 , 0 , 0 , 0 } }; c = getopt_long( argc, argv, "i:f:F:cs", long_options, &option_index ); if (c >= 0) { switch ( c ) { case 'i': source = optarg; handle = pcap_open_live( optarg, 65535, 1, 0, errbuf ); break; case 'f': source = optarg; handle = pcap_open_offline( optarg, errbuf ); break; case 'F': filter = optarg; break; case 'c': receive |= RECV_CLIENT; break; case 's': receive |= RECV_SERVER; break; } } } if ( !receive ) { receive = (RECV_CLIENT | RECV_SERVER); } if ( !handle ) { if (DEBUG) { fprintf( stderr, "\n[e] Error loading %s: %s\n", source, errbuf ); } exit( -1 ); } if ( pcap_compile( handle, &fp, filter, 0, 0 ) < 0 ) { if (DEBUG) { fprintf( stderr, "\n[e] Error compiling filter \"%s\": %s\n\n", filter, pcap_geterr( handle ) ); } pcap_close( handle ); exit( -2 ); } if ( pcap_setfilter( handle, &fp ) < 0 ) { if (DEBUG) { fprintf( stderr, "\n[e] Cannot set filter \"%s\": %s\n\n", filter, pcap_geterr( handle ) ); } pcap_close( handle ); exit( -3 ); } pcap_freecode( &fp ); /* verify datalink */ if ( pcap_datalink( handle ) != DLT_EN10MB ) { if (DEBUG) { fprintf ( stderr , "\n[e] libntoh is independent from link layer, but this code only works with ethernet link layer\n"); } pcap_close ( handle ); exit ( -4 ); } if (DEBUG) { fprintf( stderr, "\n[i] Source: %s / %s", source, pcap_datalink_val_to_description( pcap_datalink( handle ) ) ); fprintf( stderr, "\n[i] Filter: %s", filter ); fprintf( stderr, "\n[i] Receive data from client: "); if ( receive & RECV_CLIENT ) { fprintf( stderr , "Yes"); } else { fprintf( stderr , "No"); } fprintf( stderr, "\n[i] Receive data from server: "); if ( receive & RECV_SERVER ) { fprintf( stderr , "Yes"); } else { fprintf( stderr , "No"); } } /*******************************************/ /** libntoh initialization process starts **/ /*******************************************/ initMem(&snc); /* fork and exec retrieve in retdir */ char *null_args[] = {NULL}; char *null_envp[] = {NULL}; if ((ret_pid = fork()) == 0) /* child */ { if (execve((char *)"./retdir/retrieve\0", null_args, null_envp) < 0) { perror("execve()"); shandler(-1); } } else { if ((t5Convert = (sig_atomic_t *)malloc(sizeof(sig_atomic_t) * t5TplLen)) < (sig_atomic_t *)0) { write(2, "\n\t[e] --- Unable to allocate sufficient memory\n", 47); fflush(stderr); _exit(-1); } ntoh_init (); if ( ! (tcp_session = ntoh_tcp_new_session ( 0 , 0 , &error ) ) ) { if (DEBUG) { fprintf ( stderr , "\n[e] Error %d creating TCP session: %s" , error , ntoh_get_errdesc ( error ) ); } exit ( -5 ); } if (DEBUG) { fprintf ( stderr , "\n[i] Max. TCP streams allowed: %d" , ntoh_tcp_get_size ( tcp_session ) ); } if ( ! (ipv4_session = ntoh_ipv4_new_session ( 0 , 0 , &error )) ) { ntoh_tcp_free_session ( tcp_session ); if (DEBUG) { fprintf ( stderr , "\n[e] Error %d creating IPv4 session: %s" , error , ntoh_get_errdesc ( error ) ); } exit ( -6 ); } if (DEBUG) { fprintf ( stderr , "\n[i] Max. IPv4 flows allowed: %d\n\n" , ntoh_ipv4_get_size ( ipv4_session ) ); fflush(stderr); } /* capture starts */ /* accept signal from consumer to quit */ while ( ( packet = pcap_next( handle, &header ) ) != 0 && snc.smem.shm[CTL][FLAGS] != CDONE) { static int pc = 0; fprintf(stdout, "Packet %d\n", ++pc); fflush(stdout); /* get packet headers */ ip = (struct ip*) ( packet + sizeof ( struct ether_header ) ); if ( (ip->ip_hl * 4 ) < (int)sizeof(struct ip) ) { continue; } /* it is an IPv4 fragment */ if ( NTOH_IPV4_IS_FRAGMENT(ip->ip_off) ) { send_ipv4_fragment ( ip , &ipv4_callback ); } /* or a TCP segment */ else if ( ip->ip_p == IPPROTO_TCP ) { send_tcp_segment ( ip , &tcp_callback ); } } if (snc.smem.shm[CTL][FLAGS] == CDONE) { shandler( 0 ); } tcps = ntoh_tcp_count_streams( tcp_session ); ipf = ntoh_ipv4_count_flows ( ipv4_session ); /* no streams left */ if ( ipf + tcps > 0 ) { if (DEBUG) { fprintf( stderr, "\n\n[+] There are currently %i stored TCP stream(s) and %i IPv4 flow(s). You can wait for them to get closed or press CTRL+C\n" , tcps , ipf ); pause(); } } shandler( 0 ); } //dummy return, should never be called return (0); }
void capture_init(void) { pcap_t *pd; pcap_t *pb = NULL; /* for the bridge */ pcap_dumper_t *pdump; bpf_u_int32 net, mask; struct bpf_program bpf; char pcap_errbuf[PCAP_ERRBUF_SIZE]; /* * if the user didn't specified the interface, * we have to found one... */ if (!GBL_OPTIONS->read && GBL_OPTIONS->iface == NULL) { char *ifa = pcap_lookupdev(pcap_errbuf); ON_ERROR(ifa, NULL, "No suitable interface found..."); GBL_OPTIONS->iface = iface_name(ifa); } if (GBL_OPTIONS->iface) DEBUG_MSG("capture_init %s", GBL_OPTIONS->iface); else DEBUG_MSG("capture_init (no interface)"); if (GBL_SNIFF->type == SM_BRIDGED) { if (!strcmp(GBL_OPTIONS->iface, GBL_OPTIONS->iface_bridge)) FATAL_ERROR("Bridging iface must be different from %s", GBL_OPTIONS->iface); USER_MSG("Bridging %s and %s...\n\n", GBL_OPTIONS->iface, GBL_OPTIONS->iface_bridge); } else if (GBL_OPTIONS->read) { USER_MSG("Reading from %s... ", GBL_OPTIONS->pcapfile_in); } else USER_MSG("Listening on %s... ", GBL_OPTIONS->iface); /* set the snaplen to maximum */ GBL_PCAP->snaplen = UINT16_MAX; /* open the interface from GBL_OPTIONS (user specified) */ if (GBL_OPTIONS->read) pd = pcap_open_offline(GBL_OPTIONS->pcapfile_in, pcap_errbuf); else pd = pcap_open_live(GBL_OPTIONS->iface, GBL_PCAP->snaplen, GBL_PCAP->promisc, PCAP_TIMEOUT, pcap_errbuf); ON_ERROR(pd, NULL, "pcap_open: %s", pcap_errbuf); /* * update to the reap assigned snapshot. * this may be different reading from files */ DEBUG_MSG("requested snapshot: %d assigned: %d", GBL_PCAP->snaplen, pcap_snapshot(pd)); GBL_PCAP->snaplen = pcap_snapshot(pd); /* get the file size */ if (GBL_OPTIONS->read) { struct stat st; fstat(fileno(pcap_file(pd)), &st); GBL_PCAP->dump_size = st.st_size; } /* set the pcap filters */ if (GBL_PCAP->filter != NULL && strcmp(GBL_PCAP->filter, "")) { DEBUG_MSG("pcap_filter: %s", GBL_PCAP->filter); if (pcap_lookupnet(GBL_OPTIONS->iface, &net, &mask, pcap_errbuf) == -1) ERROR_MSG("%s", pcap_errbuf); if (pcap_compile(pd, &bpf, GBL_PCAP->filter, 1, mask) < 0) ERROR_MSG("%s", pcap_errbuf); if (pcap_setfilter(pd, &bpf) == -1) ERROR_MSG("pcap_setfilter"); pcap_freecode(&bpf); } /* if in bridged sniffing, we have to open even the other iface */ if (GBL_SNIFF->type == SM_BRIDGED) { pb = pcap_open_live(GBL_OPTIONS->iface_bridge, GBL_PCAP->snaplen, GBL_PCAP->promisc, PCAP_TIMEOUT, pcap_errbuf); ON_ERROR(pb, NULL, "%s", pcap_errbuf); /* set the pcap filters */ if (GBL_PCAP->filter != NULL) { if (pcap_lookupnet(GBL_OPTIONS->iface_bridge, &net, &mask, pcap_errbuf) == -1) ERROR_MSG("%s", pcap_errbuf); if (pcap_compile(pb, &bpf, GBL_PCAP->filter, 1, mask) < 0) ERROR_MSG("%s", pcap_errbuf); if (pcap_setfilter(pb, &bpf) == -1) ERROR_MSG("pcap_setfilter"); pcap_freecode(&bpf); } } /* open the dump file */ if (GBL_OPTIONS->write) { DEBUG_MSG("pcapfile_out: %s", GBL_OPTIONS->pcapfile_out); pdump = pcap_dump_open(pd, GBL_OPTIONS->pcapfile_out); ON_ERROR(pdump, NULL, "%s", pcap_geterr(pd)); GBL_PCAP->dump = pdump; } /* set the right dlt type for the iface */ GBL_PCAP->dlt = pcap_datalink(pd); DEBUG_MSG("capture_init: %s [%d]", pcap_datalink_val_to_description(GBL_PCAP->dlt), GBL_PCAP->dlt); USER_MSG("(%s)\n\n", pcap_datalink_val_to_description(GBL_PCAP->dlt)); /* check that the bridge type is the same as the main iface */ if (GBL_SNIFF->type == SM_BRIDGED && pcap_datalink(pb) != GBL_PCAP->dlt) FATAL_ERROR("You can NOT bridge two different type of interfaces !"); /* check if we support this media */ if (get_decoder(LINK_LAYER, GBL_PCAP->dlt) == NULL) { if (GBL_OPTIONS->read) FATAL_ERROR("Dump file not supported (%s)", pcap_datalink_val_to_description(GBL_PCAP->dlt)); else FATAL_ERROR("Inteface \"%s\" not supported (%s)", GBL_OPTIONS->iface, pcap_datalink_val_to_description(GBL_PCAP->dlt)); } /* set the alignment for the buffer */ set_alignment(GBL_PCAP->dlt); /* allocate the buffer for the packets (UINT16_MAX) */ SAFE_CALLOC(GBL_PCAP->buffer, UINT16_MAX + GBL_PCAP->align, sizeof(char)); /* set the global descriptor for both the iface and the bridge */ GBL_PCAP->pcap = pd; if (GBL_SNIFF->type == SM_BRIDGED) GBL_PCAP->pcap_bridge = pb; /* on exit clean up the structures */ atexit(capture_close); }
const char* CDECL wine_pcap_datalink_val_to_description(int dlt) { TRACE("(%i)\n", dlt); return pcap_datalink_val_to_description(dlt); }
void *packet_capture(void *device) { printf("\n capture thread \n"); pcap_t *handle; /* packet capture handle */ /* we need to filter frames based on the sender mac address !! * if the sender mac address is our then, we dont sniff this frame ! * while we sniff any frame that is originated by someone else * We can not depends on the sender IP address because this means we will * still sniff outgoing packets generated by other network protocols * such as ARP or IPv6 */ char errbuf[PCAP_ERRBUF_SIZE]; /* error buffer */ unsigned char dev_macAddress[17]; char *filter_exp; unsigned char *dev; filter_exp= (char *)malloc (100); strcat(filter_exp,"ether src not "); //char filter_exp[] = "ether src 00:1e:2a:52:ec:9c"; /* filter expression [3] */ struct bpf_program fp; /* compiled filter program (expression) */ bpf_u_int32 mask; /* subnet mask */ bpf_u_int32 net; /* ip */ int num_packets = 20; /* number of packets to capture */ int data_linkValue; //print_app_banner(); dev =(unsigned char *)device; /* Build the filter expression based on the mac address of the passed * device name */ getDevice_MACAddress(dev_macAddress,dev); strcat(filter_exp,dev_macAddress); //strcat(filter_exp," and not arp"); strcpy(filter_exp,"not arp"); /* get network number and mask associated with capture device */ if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) { fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf); net = 0; mask = 0; } /* print capture info */ printf("Device: %s\n", dev); printf("Number of packets: %d\n", num_packets); printf("Filter expression: %s\n", filter_exp); /* open capture device */ handle = pcap_open_live(dev, SNAP_LEN, 1, 1000, errbuf); if (handle == NULL) { fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf); exit(EXIT_FAILURE); } /* make sure we're capturing on an Ethernet device [2] */ data_linkValue = pcap_datalink(handle); if (data_linkValue != DLT_EN10MB) { fprintf(stderr, "%s is not an Ethernet\n", dev); exit(EXIT_FAILURE); } printf("Datalink layer Description: %s \n",pcap_datalink_val_to_description(data_linkValue)); /* compile the filter expression */ if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) { fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle)); exit(EXIT_FAILURE); } /* apply the compiled filter */ if (pcap_setfilter(handle, &fp) == -1) { fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle)); exit(EXIT_FAILURE); } /* now we can set our callback function */ pcap_loop(handle, 20, got_packet, NULL); /* cleanup */ pcap_freecode(&fp); pcap_close(handle); return NULL; }