Esempio n. 1
0
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;
	}
}
Esempio n. 2
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
}
Esempio n. 3
0
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
}
Esempio n. 4
0
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);
	}
}
Esempio n. 5
0
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
}
Esempio n. 6
0
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
}
Esempio n. 7
0
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 ;
}
Esempio n. 8
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 {
Esempio n. 9
0
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;
  }
}