/* callback() pcap callback */ void callback(unsigned char *string, const struct pcap_pkthdr *framehdr, const unsigned char buf[]) { time_t timestamp = framehdr->ts.tv_sec; int usecs = framehdr->ts.tv_usec; int max_offset = framehdr->caplen; iphdr ip; tcphdr tcp; /* make sure the frame is long enough */ if (max_offset < 14 + 20 + 20) return; /* make sure it's ethernet */ if (ex16(buf,12) != 0x0800) return; /* IP */ ip.offset = 14; if (IP_VERSION(buf,ip.offset) != 4) return; ip.proto = IP_PROTOCOL(buf,ip.offset); ip.src = IP_SRC(buf,ip.offset); ip.dst = IP_DST(buf,ip.offset); ip.data_offset = ip.offset + IP_SIZEOF_HDR(buf,ip.offset); if (max_offset > IP_TOTALLENGTH(buf,ip.offset) + ip.offset) ip.max_offset = IP_TOTALLENGTH(buf,ip.offset) + ip.offset; else ip.max_offset = max_offset; /* UDP */ if (ip.proto != 17 ) return; tcp.offset = ip.data_offset; tcp.dst = TCP_DST(buf,tcp.offset); tcp.src = TCP_SRC(buf,tcp.offset); tcp.data_offset = tcp.offset + 8; #ifdef DO_DUMP pcap_dump(NULL, framehdr, (buf)); #endif examine(timestamp, usecs, &ip, &tcp, buf); return; }
int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame) { struct recv_priv *precvpriv; _queue *pfree_recv_queue; _pkt *skb; struct mlme_priv*pmlmepriv = &padapter->mlmepriv; struct rx_pkt_attrib *pattrib; if(NULL == precv_frame) goto _recv_indicatepkt_drop; DBG_COUNTER(padapter->rx_logs.os_indicate); pattrib = &precv_frame->u.hdr.attrib; precvpriv = &(padapter->recvpriv); pfree_recv_queue = &(precvpriv->free_recv_queue); #ifdef CONFIG_DRVEXT_MODULE if (drvext_rx_handler(padapter, precv_frame->u.hdr.rx_data, precv_frame->u.hdr.len) == _SUCCESS) { goto _recv_indicatepkt_drop; } #endif #ifdef CONFIG_WAPI_SUPPORT if (rtw_wapi_check_for_drop(padapter,precv_frame)) { WAPI_TRACE(WAPI_ERR, "%s(): Rx Reorder Drop case!!\n", __FUNCTION__); goto _recv_indicatepkt_drop; } #endif skb = precv_frame->u.hdr.pkt; if(skb == NULL) { RT_TRACE(_module_recv_osdep_c_,_drv_err_,("rtw_recv_indicatepkt():skb==NULL something wrong!!!!\n")); goto _recv_indicatepkt_drop; } RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():skb != NULL !!!\n")); RT_TRACE(_module_recv_osdep_c_,_drv_info_,("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head=%p precv_frame->hdr.rx_data=%p\n", precv_frame->u.hdr.rx_head, precv_frame->u.hdr.rx_data)); RT_TRACE(_module_recv_osdep_c_,_drv_info_,("precv_frame->hdr.rx_tail=%p precv_frame->u.hdr.rx_end=%p precv_frame->hdr.len=%d \n", precv_frame->u.hdr.rx_tail, precv_frame->u.hdr.rx_end, precv_frame->u.hdr.len)); skb->data = precv_frame->u.hdr.rx_data; skb_set_tail_pointer(skb, precv_frame->u.hdr.len); skb->len = precv_frame->u.hdr.len; RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n skb->head=%p skb->data=%p skb->tail=%p skb->end=%p skb->len=%d\n", skb->head, skb->data, skb_tail_pointer(skb), skb_end_pointer(skb), skb->len)); if (pattrib->eth_type == 0x888e) DBG_871X_LEVEL(_drv_always_, "recv eapol packet\n"); #ifdef CONFIG_AUTO_AP_MODE #if 1 //for testing #if 1 if (0x8899 == pattrib->eth_type) { rtw_os_ksocket_send(padapter, precv_frame); //goto _recv_indicatepkt_drop; } #else if (0x8899 == pattrib->eth_type) { rtw_auto_ap_mode_rx(padapter, precv_frame); goto _recv_indicatepkt_end; } #endif #endif #endif //CONFIG_AUTO_AP_MODE /* TODO: move to core */ { _pkt *pkt = skb; struct ethhdr *etherhdr = (struct ethhdr *)pkt->data; struct sta_info *sta = precv_frame->u.hdr.psta; if (!sta) goto bypass_session_tracker; if (ntohs(etherhdr->h_proto) == ETH_P_IP) { u8 *ip = pkt->data + 14; if (GET_IPV4_PROTOCOL(ip) == 0x06 /* TCP */ && rtw_st_ctl_chk_reg_s_proto(&sta->st_ctl, 0x06) == _TRUE ) { u8 *tcp = ip + GET_IPV4_IHL(ip) * 4; if (rtw_st_ctl_chk_reg_rule(&sta->st_ctl, padapter, IPV4_DST(ip), TCP_DST(tcp), IPV4_SRC(ip), TCP_SRC(tcp)) == _TRUE) { if (GET_TCP_SYN(tcp) && GET_TCP_ACK(tcp)) { session_tracker_add_cmd(padapter, sta , IPV4_DST(ip), TCP_DST(tcp) , IPV4_SRC(ip), TCP_SRC(tcp)); if (DBG_SESSION_TRACKER) DBG_871X(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" SYN-ACK\n" , FUNC_ADPT_ARG(padapter) , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp)) , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp))); } if (GET_TCP_FIN(tcp)) { session_tracker_del_cmd(padapter, sta , IPV4_DST(ip), TCP_DST(tcp) , IPV4_SRC(ip), TCP_SRC(tcp)); if (DBG_SESSION_TRACKER) DBG_871X(FUNC_ADPT_FMT" local:"IP_FMT":"PORT_FMT", remote:"IP_FMT":"PORT_FMT" FIN\n" , FUNC_ADPT_ARG(padapter) , IP_ARG(IPV4_DST(ip)), PORT_ARG(TCP_DST(tcp)) , IP_ARG(IPV4_SRC(ip)), PORT_ARG(TCP_SRC(tcp))); } } } } bypass_session_tracker: ; } rtw_os_recv_indicate_pkt(padapter, skb, pattrib); _recv_indicatepkt_end: precv_frame->u.hdr.pkt = NULL; // pointers to NULL before rtw_free_recvframe() rtw_free_recvframe(precv_frame, pfree_recv_queue); RT_TRACE(_module_recv_osdep_c_,_drv_info_,("\n rtw_recv_indicatepkt :after rtw_os_recv_indicate_pkt!!!!\n")); return _SUCCESS; _recv_indicatepkt_drop: //enqueue back to free_recv_queue if(precv_frame) rtw_free_recvframe(precv_frame, pfree_recv_queue); DBG_COUNTER(padapter->rx_logs.os_indicate_err); return _FAIL; }