static int extract_header_length(u_int16_t fc) { int len; switch (FC_TYPE(fc)) { case T_MGMT: return MGMT_HDRLEN; case T_CTRL: switch (FC_SUBTYPE(fc)) { case CTRL_PS_POLL: return CTRL_PS_POLL_HDRLEN; case CTRL_RTS: return CTRL_RTS_HDRLEN; case CTRL_CTS: return CTRL_CTS_HDRLEN; case CTRL_ACK: return CTRL_ACK_HDRLEN; case CTRL_CF_END: return CTRL_END_HDRLEN; case CTRL_END_ACK: return CTRL_END_ACK_HDRLEN; default: return 0; } case T_DATA: len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24; if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) len += 2; return len; default: printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc)); return 0; } }
void nids_pcap_handler(u_char * par, struct pcap_pkthdr *hdr, u_char * data) { u_char *data_aligned; #ifdef HAVE_LIBGTHREAD_2_0 struct cap_queue_item *qitem; #endif #ifdef DLT_IEEE802_11 unsigned short fc; int linkoffset_tweaked_by_prism_code = 0; #endif /* * Check for savagely closed TCP connections. Might * happen only when nids_params.tcp_workarounds is non-zero; * otherwise nids_tcp_timeouts is always NULL. */ if (NULL != nids_tcp_timeouts) tcp_check_timeouts(&hdr->ts); nids_last_pcap_header = hdr; nids_last_pcap_data = data; (void)par; /* warnings... */ switch (linktype) { case DLT_EN10MB: if (hdr->caplen < 14) return; /* Only handle IP packets and 802.1Q VLAN tagged packets below. */ if (data[12] == 8 && data[13] == 0) { /* Regular ethernet */ nids_linkoffset = 14; } else if (data[12] == 0x81 && data[13] == 0) { /* Skip 802.1Q VLAN and priority information */ nids_linkoffset = 18; } else /* non-ip frame */ return; break; #ifdef DLT_PRISM_HEADER #ifndef DLT_IEEE802_11 #error DLT_PRISM_HEADER is defined, but DLT_IEEE802_11 is not ??? #endif case DLT_PRISM_HEADER: nids_linkoffset = 144; //sizeof(prism2_hdr); linkoffset_tweaked_by_prism_code = 1; //now let DLT_IEEE802_11 do the rest #endif #ifdef DLT_IEEE802_11 case DLT_IEEE802_11: /* I don't know why frame control is always little endian, but it * works for tcpdump, so who am I to complain? (wam) */ if (!linkoffset_tweaked_by_prism_code) nids_linkoffset = 0; fc = EXTRACT_LE_16BITS(data + nids_linkoffset); if (FC_TYPE(fc) != T_DATA || FC_WEP(fc)) { return; } if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { /* a wireless distribution system packet will have another * MAC addr in the frame */ nids_linkoffset += 30; } else { nids_linkoffset += 24; } if (hdr->len < nids_linkoffset + LLC_FRAME_SIZE) return; if (ETHERTYPE_IP != EXTRACT_16BITS(data + nids_linkoffset + LLC_OFFSET_TO_TYPE_FIELD)) { /* EAP, LEAP, and other 802.11 enhancements can be * encapsulated within a data packet too. Look only at * encapsulated IP packets (Type field of the LLC frame). */ return; } nids_linkoffset += LLC_FRAME_SIZE; break; #endif default:; } if (hdr->caplen < nids_linkoffset) return; /* * sure, memcpy costs. But many EXTRACT_{SHORT, LONG} macros cost, too. * Anyway, libpcap tries to ensure proper layer 3 alignment (look for * handle->offset in pcap sources), so memcpy should not be called. */ #ifdef LBL_ALIGN if ((unsigned long) (data + nids_linkoffset) & 0x3) { data_aligned = alloca(hdr->caplen - nids_linkoffset + 4); data_aligned -= (unsigned long) data_aligned % 4; memcpy(data_aligned, data + nids_linkoffset, hdr->caplen - nids_linkoffset); } else #endif data_aligned = data + nids_linkoffset; #ifdef HAVE_LIBGTHREAD_2_0 if(nids_params.multiproc) { /* * Insert received fragment into the async capture queue. * We hope that the overhead of memcpy * will be saturated by the benefits of SMP - mcree */ qitem=malloc(sizeof(struct cap_queue_item)); if (qitem && (qitem->data=malloc(hdr->caplen - nids_linkoffset))) { qitem->caplen=hdr->caplen - nids_linkoffset; memcpy(qitem->data,data_aligned,qitem->caplen); g_async_queue_lock(cap_queue); /* ensure queue does not overflow */ if(g_async_queue_length_unlocked(cap_queue) > nids_params.queue_limit) { /* queue limit reached: drop packet - should we notify user via syslog? */ free(qitem->data); free(qitem); } else { /* insert packet to queue */ g_async_queue_push_unlocked(cap_queue,qitem); } g_async_queue_unlock(cap_queue); } } else { /* user requested simple passthru - no threading */ call_ip_frag_procs(data_aligned,hdr->caplen - nids_linkoffset, &hdr->ts); } #else call_ip_frag_procs(data_aligned,hdr->caplen - nids_linkoffset, &hdr->ts); #endif }
static void data_header_print(struct smartconfig *sc, uint16_t fc, const u_char * p, uint16_t channel) { #define ADDR1 (p + 4) #define ADDR2 (p + 10) #define ADDR3 (p + 16) #define ADDR4 (p + 24) const u_char *mcast = NULL; const u_char *source = NULL; u_char *source0 = (u_char *) & from_source_mac[0]; u_char *source1 = (u_char *) & from_source_mac[1]; u_char *source2 = (u_char *) & from_source_mac[2]; if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { mcast = ADDR1; source = ADDR3; } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { mcast = ADDR3; source = ADDR2; } else return; //data_frame_dump(mcast, 6); //data_frame_dump(source, 6); if (get_source_mac) { if (!memcmp(source0, source, 6)) { if (mcast[3] > MAX_SLINKMAC_LEN) return; if (!memcmp(mcast_key3, mcast, 4)) { if ((mcast[4] <= MAX_SSID_PSK_LEN) && (mcast[5] <= MAX_SSID_PSK_LEN)) { sc->ssid_len = mcast[4]; sc->psk_len = mcast[5]; } } else if (!memcmp(mcast_key3, mcast, 3)) { int index = mcast[3]; memcpy(sc->slm[index].mcast, mcast, 6); memcpy(sc->slm[index].source, source, 6); sc->slm[index].flag = 1; } check_sconf_integrity(sc); } } else { if (!memcmp(mcast_key0, mcast, 6)) { sc->channelfreq = channel; printf("channel0:%d\n", sc->channelfreq); memcpy(source0, source, 6); } if (!memcmp(mcast_key1, mcast, 6)) { sc->channelfreq = channel; printf("channel1:%d\n", sc->channelfreq); memcpy(source1, source, 6); } if (!memcmp(mcast_key2, mcast, 6)) { sc->channelfreq = channel; printf("channel2:%d\n", sc->channelfreq); memcpy(source2, source, 6); } check_from_source_mac(sc); } #undef ADDR1 #undef ADDR2 #undef ADDR3 #undef ADDR4 }
static void pcap_hand(u_char * par, struct pcap_pkthdr *hdr, u_char * data) { struct proc_node *i; u_char *data_aligned; int id=0; if(par) { id=*((unsigned int *)par); } #ifdef DLT_IEEE802_11 unsigned short fc; int linkoffset_tweaked_by_prism_code = 0; #endif nids_last_pcap_header = hdr; (void)par; /* warnings... */ switch (linktype[id]) { case DLT_EN10MB: if (hdr->caplen < 14) return; /* Only handle IP packets and 802.1Q VLAN tagged packets below. */ if (data[12] == 8 && data[13] == 0) { /* Regular ethernet */ linkoffset[id] = 14; } else if (data[12] == 0x81 && data[13] == 0) { /* Skip 802.1Q VLAN and priority information */ linkoffset[id] = 18; } else /* non-ip frame */ return; break; #ifdef DLT_PRISM_HEADER #ifndef DLT_IEEE802_11 #error DLT_PRISM_HEADER is defined, but DLT_IEEE802_11 is not ??? #endif case DLT_PRISM_HEADER: linkoffset[id] = 144; //sizeof(prism2_hdr); linkoffset_tweaked_by_prism_code = 1; //now let DLT_IEEE802_11 do the rest #endif #ifdef DLT_IEEE802_11 case DLT_IEEE802_11: /* I don't know why frame control is always little endian, but it * works for tcpdump, so who am I to complain? (wam) */ if (!linkoffset_tweaked_by_prism_code) linkoffset[id] = 0; fc = EXTRACT_LE_16BITS(data + linkoffset[id]); if (FC_TYPE(fc) != T_DATA || FC_WEP(fc)) { return; } if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { /* a wireless distribution system packet will have another * MAC addr in the frame */ linkoffset[id] += 30; } else { linkoffset[id] += 24; } if (hdr->len < linkoffset[id] + LLC_FRAME_SIZE) return; if (ETHERTYPE_IP != EXTRACT_16BITS(data + linkoffset[id] + LLC_OFFSET_TO_TYPE_FIELD)) { /* EAP, LEAP, and other 802.11 enhancements can be * encapsulated within a data packet too. Look only at * encapsulated IP packets (Type field of the LLC frame). */ return; } linkoffset[id] += LLC_FRAME_SIZE; break; #endif default:; } if (hdr->caplen < linkoffset[id]) return; /* * sure, memcpy costs. But many EXTRACT_{SHORT, LONG} macros cost, too. * Anyway, libpcap tries to ensure proper layer 3 alignment (look for * handle->offset in pcap sources), so memcpy should not be called. */ #ifdef LBL_ALIGN if ((unsigned long) (data + linkoffset[id]) & 0x3) { data_aligned = alloca(hdr->caplen - linkoffset[id] + 4); data_aligned -= (unsigned long) data_aligned % 4; memcpy(data_aligned, data + linkoffset[id], hdr->caplen - linkoffset[id]); } else #endif data_aligned = data + linkoffset[id]; for (i = ip_frag_procs[id]; i; i = i->next) { (i->item) (data_aligned, hdr->caplen - linkoffset[id],id); } }
static void data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, const u_int8_t **dstp) { u_int subtype = FC_SUBTYPE(fc); if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) || DATA_FRAME_IS_QOS(subtype)) { printf("CF "); if (DATA_FRAME_IS_CF_ACK(subtype)) { if (DATA_FRAME_IS_CF_POLL(subtype)) printf("Ack/Poll"); else printf("Ack"); } else { if (DATA_FRAME_IS_CF_POLL(subtype)) printf("Poll"); } if (DATA_FRAME_IS_QOS(subtype)) printf("+QoS"); printf(" "); } #define ADDR1 (p + 4) #define ADDR2 (p + 10) #define ADDR3 (p + 16) #define ADDR4 (p + 24) if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR2; if (dstp != NULL) *dstp = ADDR1; if (!eflag) return; printf("DA:%s SA:%s BSSID:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3)); } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR3; if (dstp != NULL) *dstp = ADDR1; if (!eflag) return; printf("DA:%s BSSID:%s SA:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3)); } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR2; if (dstp != NULL) *dstp = ADDR3; if (!eflag) return; printf("BSSID:%s SA:%s DA:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3)); } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR4; if (dstp != NULL) *dstp = ADDR3; if (!eflag) return; printf("RA:%s TA:%s DA:%s SA:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3), etheraddr_string(ADDR4)); } #undef ADDR1 #undef ADDR2 #undef ADDR3 #undef ADDR4 }
static void data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp, const u_int8_t **dstp) { switch (FC_SUBTYPE(fc)) { case DATA_DATA: case DATA_NODATA: break; case DATA_DATA_CF_ACK: case DATA_NODATA_CF_ACK: printf("CF Ack "); break; case DATA_DATA_CF_POLL: case DATA_NODATA_CF_POLL: printf("CF Poll "); break; case DATA_DATA_CF_ACK_POLL: case DATA_NODATA_CF_ACK_POLL: printf("CF Ack/Poll "); break; } #define ADDR1 (p + 4) #define ADDR2 (p + 10) #define ADDR3 (p + 16) #define ADDR4 (p + 24) if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR2; if (dstp != NULL) *dstp = ADDR1; if (!eflag) return; printf("DA:%s SA:%s BSSID:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3)); } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR3; if (dstp != NULL) *dstp = ADDR1; if (!eflag) return; printf("DA:%s BSSID:%s SA:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3)); } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR2; if (dstp != NULL) *dstp = ADDR3; if (!eflag) return; printf("BSSID:%s SA:%s DA:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3)); } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { if (srcp != NULL) *srcp = ADDR4; if (dstp != NULL) *dstp = ADDR3; if (!eflag) return; printf("RA:%s TA:%s DA:%s SA:%s ", etheraddr_string(ADDR1), etheraddr_string(ADDR2), etheraddr_string(ADDR3), etheraddr_string(ADDR4)); } #undef ADDR1 #undef ADDR2 #undef ADDR3 #undef ADDR4 }
int mac_header_parser(unsigned char * p, int pkt_len, int cap_len, int path_type, int radiotap_len) { unsigned char * p_start ; p_start = p; if (debug_mode) { if (path_type ==1 ) { p += radiotap_len ; // HOMESAW_TX_FRAME_HEADER; if (*(p+1)==0x0 && *(p) ==0x50) return 0; //mgmt frames transmitted by router if (*(p+1)==0x0 && *(p) ==0x84) return 0; //control frames transmitted by router if (*(p+1)==0x42 && *(p) ==0x8) return 0; //control frames transmitted by router if(*(p)==0xc0 && *(p+1)==0x0 ) return 0 ; //mgmt type but is 0c (deauth) //printf("\nin mp: mac header: %02x %02x %d \n", *p, *(p+1),pkt_len ); } else{ p += radiotap_len ; //HOMESAW_RX_FRAME_HEADER; } } p += radiotap_len ; //HOMESAW_RX/TX_FRAME_HEADER; memset(&clh,0,sizeof(struct control_layer_header)); memset(&mlh,0,sizeof(struct mgmt_beacon_layer_header)); memset(&mlh_t,0,sizeof(struct mgmt_layer_err_header)); memset(&dlh,0,sizeof(struct data_layer_header)); u_int16_t fc = EXTRACT_LE_16BITS(p); struct mgmt_header_t *mgmt_h =NULL; struct ctrl_ps_poll_t * c_poll = NULL ; struct ctrl_bar_t * c_bar =NULL; struct ctrl_rts_t * rts = NULL; struct ctrl_cts_t *cts= NULL; switch (FC_TYPE(fc)) { case MGT_FRAME: mgmt_h = (struct mgmt_header_t *) p; switch(FC_SUBTYPE(fc)){ case ST_BEACON: memcpy(mlh.src_mac,mgmt_h->sa,6); mlh.pkt_len=pkt_len; mlh.frame_control = fc ; mlh.seq_ctrl = pletohs(&(mgmt_h->seq_ctrl)); parse_beacon(p+MGT_FRAME_HDR_LEN, (unsigned int)cap_len, &mlh ); mgmt_beacon_count++; if(mgmt_beacon_count<512){ address_mgmt_beacon_table_update(&mgmt_beacon_address_table, p_start, &mlh); break; } default : memcpy(mlh_t.src_mac,mgmt_h->sa,6); mlh_t.pkt_len=pkt_len; mlh_t.frame_control = fc ; mlh_t.seq_ctrl = pletohs(&(mgmt_h->seq_ctrl)); //EXTRACT_LE_16BITS(mgmt_h->seq_ctrl); address_mgmt_common_table_update(&mgmt_common_address_table, p_start, &mlh_t); break ; } break ; case CONTROL_FRAME: clh.pkt_len= pkt_len; clh.frame_control =fc ; switch(FC_SUBTYPE(fc)){ case CTRL_BAR: c_bar = (struct ctrl_bar_t *)p; memcpy(clh.src_mac,c_bar->ra,6); address_control_table_update(&control_address_table , p_start, &clh); break ; case CTRL_PS_POLL : c_poll = (struct ctrl_ps_poll_t *)p; memcpy(clh.src_mac,c_poll->bssid,6); address_control_table_update(&control_address_table , p_start, &clh); break ; case CTRL_RTS : rts = (struct ctrl_rts_t *) p; memcpy(clh.src_mac,rts->ra,6); address_control_table_update(&control_address_table , p_start, &clh); if (debug_mode) { print_mac(rts->ta,"rts ta "); } break; /* Not used as all kinds of packets are not useful and then we were case CTRL_ACK : cts= (struct ctrl_cts_t * ) p; print_mac(cts->ra, "ack frames\n "); break ; case CTRL_END_ACK: cts= (struct ctrl_cts_t * ) p; print_mac(cts->ra, "end ack\n "); break ; case CTRL_CF_END: cts= (struct ctrl_cts_t *) p; print_mac(cts->ra, "cf end ack\n "); */ default : // Use the common structure of rest cts= (struct ctrl_cts_t * ) p; memcpy(clh.src_mac,cts->ra,6); address_control_table_update(&control_address_table, p_start, &clh); if (debug_mode) { print_mac(cts->ra, "default control err\n "); } break; } break ; case DATA_FRAME : { // printf("data frame \n"); struct ieee80211_hdr * sc = (struct ieee80211_hdr *)p; // printf("control sequence = %u \n", pletohs(&(sc->seq_ctrl)) ); dlh.pkt_len=pkt_len; dlh.frame_control =fc ; if (debug_mode) { if( DATA_FRAME_IS_NULL(FC_SUBTYPE(fc))){ printf("null type\n"); } else if (DATA_FRAME_IS_CF_ACK(FC_SUBTYPE(fc))){ printf("cf-type\n"); } else if (DATA_FRAME_IS_CF_POLL(FC_SUBTYPE(fc))){ printf("poll type\n"); } else if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))){ printf("qos type\n"); } if(IS_DATA_DATA(FC_SUBTYPE(fc))){ printf(" data-data\n"); }else if(IS_DATA_DATA_CF_ACK(FC_SUBTYPE(fc))){ printf("cf-ack\n"); }else if(IS_DATA_DATA_CF_POLL(FC_SUBTYPE(fc))){ printf("cf-poll\n"); }else if(IS_DATA_DATA_CF_ACK_POLL(FC_SUBTYPE(fc))){ printf("cf-poll-ack\n"); }else if(IS_DATA_NODATA(FC_SUBTYPE(fc))){ printf("no data\n"); }else if(IS_DATA_NODATA_CF_ACK(FC_SUBTYPE(fc))){ printf("nodata cf ack\n"); }else if(IS_DATA_NODATA_CF_POLL (FC_SUBTYPE(fc))){ printf("nodata cf poll\n"); }else if(IS_DATA_NODATA_CF_ACK_POLL (FC_SUBTYPE(fc))){ printf(" cf ack poll\n"); } printf("subtype:%02x \n",FC_SUBTYPE(fc)); printf("seq ctrl : %d \n", dlh.seq_ctrl ); } dlh.seq_ctrl = pletohs(&(sc->seq_ctrl)); int hdrlen = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24; if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) hdrlen += 2; // but there is 8 bytes offset after mac header of 26 bytes, thats for qos data packet #define ADDR1 (p + 4) #define ADDR2 (p + 10) #define ADDR3 (p + 16) if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { memcpy(dlh.src_mac,ADDR2,6); memcpy(dlh.dest_mac,ADDR1,6); #ifdef DEBUG print_mac(ADDR2,"1 addr2"); print_mac(ADDR1,"1 addr1"); #endif } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { if (radiotap_len ==HOMESAW_TX_FRAME_HEADER ) mac_address_map(&devices,ADDR1); memcpy(dlh.src_mac,ADDR3,6); memcpy(dlh.dest_mac,ADDR1,6); // printf("f in anon 2 \n"); if (debug_mode) { print_mac(ADDR3,"2 src"); print_mac(ADDR1,"2 dest"); } } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { memcpy(dlh.src_mac,ADDR2,6); memcpy(dlh.dest_mac,ADDR3,6); if (debug_mode) { print_mac(ADDR2,"3 src"); print_mac(ADDR3,"3 dest"); } } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { #define ADDR4 (p + 24) memcpy(dlh.src_mac,ADDR4,6); memcpy(dlh.dest_mac,ADDR3,6); if (debug_mode) { print_mac(ADDR4,"4 src"); print_mac(ADDR3,"4 dest"); } #undef ADDR4 } #undef ADDR1 #undef ADDR2 #undef ADDR3 address_data_table_update(&data_address_table ,p_start, &dlh,path_type, 0); // is_more flag: write tcp/udp headers to file #ifdef TRANSPORT_LAYER_CAPTURE transport_header_parser(fc,p_start,p+hdrlen,pkt_len,path_type,&dlh); #endif break ; } break; default : printf("imposs pkt ! pkt len is %d\n ",pkt_len); exit(EXIT_FAILURE); } return 0 ; }
int mac_header_err_parser(unsigned char *p, int pkt_len, int cap_len) { u_char * p_start = p ; p += HOMESAW_RX_FRAME_HEADER; struct mgmt_header_t *mgmt_h =NULL; memset(&clh,0,sizeof(struct control_layer_header)); memset(&mlh_t,0,sizeof(struct mgmt_layer_err_header)); memset(&dlh_t,0,sizeof(struct data_layer_err_header)); u_int16_t fc = EXTRACT_LE_16BITS(p); struct ctrl_ps_poll_t * c_poll = NULL ; struct ctrl_bar_t * c_bar =NULL; struct ctrl_rts_t * rts = NULL; struct ctrl_cts_t *cts= NULL; if (debug_mode) { printf("macheader err_parser: %02x %02x\n", *p, *(p+1)); } switch (FC_TYPE(fc)) { case MGT_FRAME: { mgmt_h = (struct mgmt_header_t *) p; memcpy(mlh_t.src_mac,mgmt_h->sa,6); mlh_t.frame_control = fc ; mlh_t.pkt_len= pkt_len; mlh_t.seq_ctrl = pletohs(&(mgmt_h->seq_ctrl)); //EXTRACT_LE_16BITS(mgmt_h->seq_ctrl); /*Copied the common portions */ address_mgmt_err_table_update(&mgmt_address_table_err, p_start, &mlh_t); } break ; case CONTROL_FRAME: { clh.frame_control = fc ; clh.pkt_len=pkt_len; switch(FC_SUBTYPE(fc)){ case CTRL_BAR: c_bar = (struct ctrl_bar_t *)p; memcpy(c_bar->ra,clh.src_mac,6); address_control_err_table_update(&control_address_table_err , p_start, &clh); break ; case CTRL_PS_POLL : c_poll = (struct ctrl_ps_poll_t *)p; memcpy(c_poll->bssid,clh.src_mac,6); address_control_err_table_update(&control_address_table_err , p_start, &clh); break ; case CTRL_RTS : rts = (struct ctrl_rts_t *) p; memcpy(clh.src_mac,rts->ra,6); address_control_err_table_update(&control_address_table_err , p_start, &clh); #ifdef DEBUG print_mac(rts->ra,"rts ra"); print_mac(rts->ta,"rts ta "); #endif break; default : // Use the common structure of rest cts= (struct ctrl_cts_t * ) p; memcpy(clh.src_mac,cts->ra,6); address_control_err_table_update(&control_address_table_err , p_start, &clh); #ifdef DEBUG print_mac(cts->ra, "ack "); #endif break; } } break ; case DATA_FRAME : { struct ieee80211_hdr * sc = (struct ieee80211_hdr *)p; // printf("control sequence = %u \n", pletohs(&(sc->seq_ctrl)) ); dlh_t.frame_control =fc ; dlh_t.pkt_len=pkt_len; dlh_t.seq_ctrl = pletohs(&(sc->seq_ctrl)); int hdrlen = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24; if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) hdrlen += 2; // but there is 8 bytes offset after mac header of 26 bytes, thats for qos data packet #define ADDR1 (p + 4) #define ADDR2 (p + 10) #define ADDR3 (p + 16) if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { memcpy(dlh_t.src_mac,ADDR2,6); memcpy(dlh_t.dest_mac,ADDR1,6); if (debug_mode ){ print_mac(ADDR2,"1 addr2"); print_mac(ADDR1,"1 addr1"); } } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { memcpy(dlh_t.src_mac,ADDR3,6); memcpy(dlh_t.dest_mac,ADDR1,6); // printf("f in anon 2 \n"); if (debug_mode ){ print_mac(ADDR3,"2 src"); print_mac(dlh_t.src_mac,"anon src"); print_mac(ADDR1,"2 dest"); print_mac(dlh_t.dest_mac, " anon dest"); } } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { memcpy(dlh_t.src_mac,ADDR2,6); memcpy(dlh_t.dest_mac,ADDR3,6); if (debug_mode ){ print_mac(ADDR2,"3 src"); print_mac(ADDR3,"3 dest"); } } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { #define ADDR4 (p + 24) memcpy(dlh_t.src_mac,ADDR4,6); memcpy(dlh_t.dest_mac,ADDR3,6); if (debug_mode ){ print_mac(ADDR4,"4 src"); print_mac(ADDR3,"4 dest"); } #undef ADDR4 } #undef ADDR1 #undef ADDR2 #undef ADDR3 address_data_err_table_update(&data_address_table_err ,p_start, &dlh_t); break ; } break; default : // TODO: XXX classify it as different kinds of packets depending on packet length and other features /* * CONTROL PKT SIZE : 14 + custom header *BEACON PKT SIZE : can be as large as (11n) 320 bytes. Atleast 100 bytes (a/g) 110 bytes *LAB BEACONS : 156-231 bytes ; check for fffffffff *PROBES SIZE : 101,149,219,225 , 204, 83 *DATA PKT SIZE : anything greater than 400 bytes is data packet *check the fields of FS,DS to get the mac address offset * Can be 55 size packets too ! */ if(pkt_len>400 ){ // DATA FRAME 48 byte RADIOTAP header struct ieee80211_hdr * sc = (struct ieee80211_hdr *)p; // printf("control sequence = %u \n", pletohs(&(sc->seq_ctrl)) ); dlh_t.frame_control =fc ; dlh_t.pkt_len=pkt_len; dlh_t.seq_ctrl = pletohs(&(sc->seq_ctrl)); int hdrlen = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24; if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) hdrlen += 2; // but there is 8 bytes offset after mac header of 26 bytes, thats for qos data packet #define ADDR1 (p + 4) #define ADDR2 (p + 10) #define ADDR3 (p + 16) if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) { memcpy(dlh_t.src_mac,ADDR2,6); memcpy(dlh_t.dest_mac,ADDR1,6); if (debug_mode) { print_mac(ADDR2,"1 addr2"); print_mac(ADDR1,"1 addr1"); } } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) { memcpy(dlh_t.src_mac,ADDR3,6); memcpy(dlh_t.dest_mac,ADDR1,6); // printf("f in anon 2 \n"); if (debug_mode) { print_mac(ADDR3,"2 src"); print_mac(dlh_t.src_mac,"anon src"); print_mac(ADDR1,"2 dest"); print_mac(dlh_t.dest_mac, " anon dest"); } } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) { memcpy(dlh_t.src_mac,ADDR2,6); memcpy(dlh_t.dest_mac,ADDR3,6); if (debug_mode) { print_mac(ADDR2,"3 src"); print_mac(ADDR3,"3 dest"); } } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { #define ADDR4 (p + 24) memcpy(dlh_t.src_mac,ADDR4,6); memcpy(dlh_t.dest_mac,ADDR3,6); if (debug_mode) { print_mac(ADDR4,"4 src"); print_mac(ADDR3,"4 dest"); } #undef ADDR4 } #undef ADDR1 #undef ADDR2 #undef ADDR3 //TODO: XXX Just update with this much info address_data_err_table_update(&data_address_table_err ,p_start, &dlh_t); }else if(pkt_len>110 && pkt_len <360){ // MGMT FRAME mgmt_h = (struct mgmt_header_t *) p; memcpy(mlh_t.src_mac,mgmt_h->sa,6); mlh_t.pkt_len=pkt_len; mlh_t.frame_control =fc ; mlh_t.seq_ctrl = pletohs(&(mgmt_h->seq_ctrl)); // EXTRACT_LE_16BITS(mgmt_h->seq_ctrl);//Copied the common portions address_mgmt_err_table_update(&mgmt_address_table_err, p_start, &mlh_t); } else if ( pkt_len <72){ //CONTROL FRAME : 48+14 : 62 bytes clh.frame_control = fc ; clh.pkt_len=pkt_len; switch FC_SUBTYPE(fc) { case CTRL_BAR: c_bar = (struct ctrl_bar_t *)p; memcpy(clh.src_mac,c_bar->ra,6); address_control_err_table_update(&control_address_table_err , p_start, &clh); break ; case CTRL_PS_POLL : c_poll = (struct ctrl_ps_poll_t *)p; memcpy(clh.src_mac,c_poll->bssid,6); address_control_err_table_update(&control_address_table_err , p_start, &clh); break ; case CTRL_RTS : rts = (struct ctrl_rts_t *) p; memcpy(clh.src_mac,rts->ra,6); address_control_err_table_update(&control_address_table_err , p_start, &clh); if (debug_mode) { print_mac(rts->ra,"rts ra"); print_mac(rts->ta,"rts ta "); } break; default : // Use the common structure of rest cts= (struct ctrl_cts_t * ) p; memcpy(clh.src_mac,cts->ra,6); address_control_err_table_update(&control_address_table_err , p_start, &clh); #ifdef DEBUG print_mac(cts->ra, "default control\n"); #endif break; } }else {
void HttpSniffer::got_packet(const struct pcap_pkthdr *header, const u_char *packet) { /* Declare pointers to packet headers */ const struct radiotap_header *radiotap; /* The Radiotap header */ const struct wifi_header *hdr80211; /* The 802.11 header */ const struct snap_llc_header *snap_llc; /* The SNAP LLC header */ const struct sniff_ethernet *ethernet; /* The Ethernet header [1] */ const struct sniff_ip *ip = NULL; /* The IP header */ const struct sniff_ip6 *ip6 = NULL; /* The IPv6 header */ const struct sniff_tcp *tcp; /* The TCP header */ const char *payload; /* Packet payload */ /* Declare header lengths */ int size_ip; /* Size of IP header in bytes */ int size_tcp; /* Size of TCP header */ int size_payload; /* Size of data in bytes */ int size_radiotap; /* Size of Radiotap header */ int size_80211; /* Size of 802.11 header */ /* Layer 3 header offset */ int l3hdr_off = SIZE_ETHERNET; /* Total IP packet length */ int ip_len; u_int16_t fc; u_short ether_type; string from; string to; WifiInfo wifi_info; /* 802.11 monitor support... */ if (m_wifimon) { /* Get Radiotap header length (variable) */ radiotap = (struct radiotap_header*)(packet); size_radiotap = radiotap->it_len; /* Calculate 802.11 header length (variable) */ hdr80211 = (struct wifi_header*)(packet + size_radiotap); fc = hdr80211->fc; if (FC_TYPE(fc) == T_DATA) { size_80211 = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24; if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) { size_80211 += 2; } } else { cerr << (boost::format("Ignoring non-data frame 0x%x\n") % fc); return; } /* Set Layer 3 header offset (snap_llc_header has standard length) */ l3hdr_off = size_80211 + size_radiotap + sizeof(struct snap_llc_header); /* Check ether_type */ snap_llc = (struct snap_llc_header*)(packet + size_80211 + size_radiotap); ether_type = ntohs(snap_llc->ether_type); if (ether_type != ETHERTYPE_IP) { cerr << (boost::format("Ignoring unknown ethernet packet with type 0x%x\n") % ether_type); return; } /* Check and set IP header size and total packet length */ ip = (struct sniff_ip*)(packet + l3hdr_off); size_ip = IP_HL(ip)*4; if (size_ip < 20) { /* Don't throw exception because on 802.11 monitor interfaces * we can have malformed packets, just skip it */ cerr << (boost::format("Bad IP length: %d\n") % size_ip); return; } ip_len = ntohs(ip->ip_len); wifi_info = WifiInfo(hdr80211, radiotap); } else { /* Define ethernet header */ ethernet = (struct sniff_ethernet*)(packet); /* Check ether_type */ ether_type = ntohs(ethernet->ether_type); switch (ether_type) { case ETHERTYPE_IP: /* Check and set IP header size and total packet length */ ip = (struct sniff_ip*)(packet + l3hdr_off); size_ip = IP_HL(ip)*4; if (size_ip < 20) throw runtime_error(str(boost::format("Invalid IPv4 header length: %u bytes") % size_ip)); ip_len = ntohs(ip->ip_len); break; case ETHERTYPE_IPV6: /* Check and set IP header size and total packet length */ // FIXME: Support IPv6 extension headers? ip6 = (struct sniff_ip6*)(packet + l3hdr_off); size_ip = 40; ip_len = ntohs(ip6->ip6_plen); break; default: cerr << (boost::format("Ignoring unknown ethernet packet with type %x\n") % ether_type); return; } } /* Ignore non tcp packets */ if (ip->ip_p != IPPROTO_TCP && ip6->ip6_nxt != IPPROTO_TCP) return; /* Check and set TCP header size */ tcp = (struct sniff_tcp*)(packet + l3hdr_off + size_ip); size_tcp = TH_OFF(tcp)*4; if (size_tcp < 20) { /* Don't throw exception because on 802.11 monitor interfaces * we can have malformed packets, just skip it */ if (!m_wifimon) throw runtime_error(str(boost::format("Invalid TCP header length: %u bytes") % size_tcp)); else cerr << (boost::format("Invalid TCP header length: %u bytes") % size_tcp); return; } /* Get source/dest */ if (ether_type == ETHERTYPE_IP) { from = str(boost::format("%s:%d") % inet_ntoa(ip->ip_src) % ntohs(tcp->th_sport)); to = str(boost::format("%s:%d") % inet_ntoa(ip->ip_dst) % ntohs(tcp->th_dport)); } else { char src_addr_buf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &ip6->ip6_src, src_addr_buf, sizeof(src_addr_buf)); char dst_addr_buf[INET6_ADDRSTRLEN]; inet_ntop(AF_INET6, &ip6->ip6_dst, dst_addr_buf, sizeof(src_addr_buf)); from = str(boost::format("[%s]:%d") % string(src_addr_buf) % ntohs(tcp->th_sport)); to = str(boost::format("[%s]:%d") % string(dst_addr_buf) % ntohs(tcp->th_dport)); } /* Define/compute tcp payload (segment) offset */ payload = (const char *)(packet + l3hdr_off + size_ip + size_tcp); /* Compute tcp payload (segment) size */ size_payload = ip_len - (size_ip + size_tcp); string key; key.append(from); key.append("-"); key.append(to); HttpPacket *http_packet = 0; PacketCacheMap::iterator iter; iter = m_pending_packets.find(key); if (iter == m_pending_packets.end()) { http_packet = new HttpPacket(from, to, wifi_info); } else { http_packet = iter->second; m_pending_packets.erase(iter); } if (http_packet->parse(payload, size_payload)) { if (http_packet->isComplete()) { m_callback(http_packet); delete http_packet; } else { m_pending_packets[key] = http_packet; } } else { delete http_packet; } }