예제 #1
0
파일: sfrf.c 프로젝트: DeepnessLab/moly
/* Test a an event against the threshold database. Events without thresholding
 * objects are automatically loggable.
 *
 * @param pContext     Threshold table pointer
 * @param gid  Generator Id from the event
 * @param sid  Signature Id from the event
 * @param sip     Event/Packet Src IP address
 * @param dip     Event/Packet Dst IP address
 * @param curTime Current Event/Packet time
 * @param op operation of type SFRF_COUNT_OPERATION
 *
 * @return  -1 if packet is within dos_threshold and therefore action is allowed.
 *         >=0 if packet violates a dos_threshold and therefore new_action should
 *             replace rule action. new_action value is returned.
 */
int SFRF_TestThreshold(
    RateFilterConfig *config,
    unsigned gid,
    unsigned sid,
    snort_ip_p sip,
    snort_ip_p dip,
    time_t curTime,
    SFRF_COUNT_OPERATION op
) {
    SFGHASH  *genHash;
    tSFRFSidNode* pSidNode;
    tSFRFConfigNode* cfgNode;
    int newStatus = -1;
    int status = -1;
    tSFRFGenHashKey key;
    tSfPolicyId policy_id = getRuntimePolicy();

#ifdef SFRF_DEBUG
    printf("--%d-%d-%d: %s() entering\n", 0, gid, sid, __func__);
    fflush(stdout);
#endif

    if ( gid >= SFRF_MAX_GENID )
        return status; /* bogus gid */

    // Some events (like 'TCP connection closed' raised by preprocessor may
    // not have any configured threshold but may impact thresholds for other
    // events (like 'TCP connection opened'
    _updateDependentThresholds(config, gid, sid, sip, dip, curTime);

    /*
     *  Get the hash table for this gid
     */
    genHash = config->genHash [ gid ];
    if ( !genHash )
    {
#ifdef SFRF_DEBUG
        printf("--SFRF_DEBUG: %d-%d-%d: no hash table entry for gid\n", 0, gid, sid);
        fflush(stdout);
#endif
        return status;
    }

    /*
     * Check for any Permanent sid objects for this gid
     */
    key.sid = sid;
    key.policyId = policy_id;

    pSidNode = (tSFRFSidNode*)sfghash_find( genHash, (void*)&key );
    if ( !pSidNode )
    {
#ifdef SFRF_DEBUG
        printf("--SFRF_DEBUG: %d-%d-%d: no DOS THD object\n", 0, gid, sid);
        fflush(stdout);
#endif
        return status;
    }

    /* No List of Threshold objects - bail and log it */
    if ( !pSidNode->configNodeList )
    {
#ifdef SFRF_DEBUG
        printf("--SFRF_DEBUG: %d-%d-%d: No user configuration\n",
                0, gid, sid);
        fflush(stdout);
#endif
        return status;
    }

    /* For each permanent thresholding object, test/add/update the config object */
    /* We maintain a list of thd objects for each gid+sid */
    /* each object has it's own unique thd_id */
    for ( cfgNode  = (tSFRFConfigNode*)sflist_first(pSidNode->configNodeList);
          cfgNode != 0;
          cfgNode  = (tSFRFConfigNode*)sflist_next(pSidNode->configNodeList) )
    {
        switch (cfgNode->tracking)
        {
            case SFRF_TRACK_BY_SRC:
                if ( SFRF_AppliesTo(cfgNode, sip) )
                {
                    newStatus = SFRF_TestObject(cfgNode, sip, curTime, op);
                }
                break;

            case SFRF_TRACK_BY_DST:
                if ( SFRF_AppliesTo(cfgNode, dip) )
                {
                    newStatus = SFRF_TestObject(cfgNode, dip, curTime, op);
                }
                break;

            case SFRF_TRACK_BY_RULE:
                {
                    snort_ip cleared;
                    IP_CLEAR(cleared);
                    newStatus = SFRF_TestObject(cfgNode, IP_ARG(cleared), curTime, op);
                }
                break;

            default:
                // error case
                break;
        }

#ifdef SFRF_DEBUG
        printf("--SFRF_DEBUG: %d-%d-%d: Time %d, rate limit blocked: %d\n",
                cfgNode->tid, gid, sid, (unsigned)curTime, newStatus);
        fflush(stdout);
#endif

        // rate limit is reached
        if ( newStatus >= 0 && (status == -1) )
        {
            status = newStatus;
        }
    }

    // rate limit not reached
    return status;
}
예제 #2
0
파일: stream_expect.c 프로젝트: eqmcc/snort
/**Either expect or expect future session.
 *
 * Preprocessors may add sessions to be expected altogether or to be associated with some data. For example,
 * FTP preprocessor may add data channel that should be expected. Alternatively, FTP preprocessor may add
 * session with appId FTP-DATA.
 *
 * It is assumed that only one of cliPort or srvPort should be known (!0). This violation of this assumption
 * will cause hash collision that will cause some session to be not expected and expected. This will occur only
 * rarely and therefore acceptable design optimization.
 *
 * Also, appId is assumed to be consistent between different preprocessors. Each session can be assigned only
 * one AppId. When new appId mismatches existing appId, new appId and associated data is not stored.
 *
 * @param cliIP - client IP address. All preprocessors must have consistent view of client side of a session.
 * @param cliPort - client port number
 * @param srvIP - server IP address. All preprocessors must have consisten view of server side of a session.
 * @param srcPort - server port number
 * @param protocol - IPPROTO_TCP or IPPROTO_UDP.
 * @param direction - direction of session. Assumed that direction value for session being expected or expected will
 * remain same across different calls to this function.
 * @param expiry - session expiry in seconds.
 */
int StreamExpectAddChannel(snort_ip_p cliIP, uint16_t cliPort,
                           snort_ip_p srvIP, uint16_t srvPort,
                           uint8_t protocol, time_t now, char direction, uint8_t flags,
                           uint32_t timeout, int16_t appId, uint32_t preprocId,
                           void *appData, void (*appDataFreeFn)(void*))
{
    ExpectHashKey hashKey;
    SFXHASH_NODE *hash_node;
    ExpectNode new_node;
    ExpectNode *node;
    ExpectedSessionDataList *data_list;
    ExpectedSessionData *data;
    int reversed_key;
    SFIP_RET rval;

    if (cliPort != UNKNOWN_PORT)
        srvPort = UNKNOWN_PORT;

#if defined(DEBUG_MSGS)
    {
        char src_ip[INET6_ADDRSTRLEN];
        char dst_ip[INET6_ADDRSTRLEN];

        sfip_ntop(cliIP, src_ip, sizeof(src_ip));
        sfip_ntop(srvIP, dst_ip, sizeof(dst_ip));
        DebugMessage(DEBUG_STREAM, "Creating expected %s-%u -> %s-%u %u appid %d  preproc %u\n", src_ip,
                     cliPort, dst_ip, srvPort, protocol, appId, preprocId);
    }
#endif

    /* Add the info to a tree that marks this channel as one to expect.
     * Only one of the port values may be UNKNOWN_PORT.
     * As a sanity check, the IP addresses may not be 0 or 255.255.255.255.
     */
    if ((cliPort == UNKNOWN_PORT) && (srvPort == UNKNOWN_PORT))
        return -1;

    if (cliIP->family == AF_INET)
    {
        if (!cliIP->ip.u6_addr32[0] || cliIP->ip.u6_addr32[0] == 0xFFFFFFFF ||
            !srvIP->ip.u6_addr32[0] || srvIP->ip.u6_addr32[0] == 0xFFFFFFFF)
        {
            return -1;
        }
    }
    else if (sfip_fast_eq6(cliIP, IP_ARG(zeroed)) || sfip_fast_eq6(srvIP, IP_ARG(zeroed)))
    {
        return -1;
    }

    rval = sfip_compare(cliIP, srvIP);
    if (rval == SFIP_LESSER || (rval == SFIP_EQUAL && cliPort < srvPort))
    {
        IP_COPY_VALUE(hashKey.ip1, cliIP);
        hashKey.port1 = cliPort;
        IP_COPY_VALUE(hashKey.ip2, srvIP);
        hashKey.port2 = srvPort;
        reversed_key = 0;
    }
    else
    {
        IP_COPY_VALUE(hashKey.ip1, srvIP);
        hashKey.port1 = srvPort;
        IP_COPY_VALUE(hashKey.ip2, cliIP);
        hashKey.port2 = cliPort;
        reversed_key = 1;
        DEBUG_WRAP(DebugMessage(DEBUG_STREAM, "reversed\n"););
    }
예제 #3
0
파일: ppm.c 프로젝트: GumpChan/blackcat
void ppm_pkt_log(ppm_cfg_t *ppm_cfg, Packet* p)
{
    int filterEvent = 0;
    if (!ppm_cfg->max_pkt_ticks)
        return;

    ppm_cfg->pkt_event_cnt++;

    if (ppm_cfg->pkt_log & PPM_LOG_ALERT)
    {
        OptTreeNode* potn;
        Event ev;

        /* make sure we have an otn already in our table for this event */
        potn = OtnLookup(snort_conf->otn_map, GENERATOR_PPM, PPM_EVENT_PACKET_ABORTED);
        if (potn == NULL)
        {
            /* have to make one */
            potn = GenerateSnortEventOtn(GENERATOR_PPM, /* GID */
                                         PPM_EVENT_PACKET_ABORTED, /* SID */
                                         1, /* Rev */
                                         0, /* classification */
                                         3, /* priority (low) */
                                         PPM_EVENT_PACKET_ABORTED_STR /* msg string */);

            if (potn == NULL)
                return;

            OtnLookupAdd(snort_conf->otn_map, potn);
        }

        SetEvent(&ev,
                 potn->sigInfo.generator, /* GID */
                 potn->sigInfo.id, /* SID */
                 potn->sigInfo.rev, /* Rev */
                 potn->sigInfo.class_id, /* classification */
                 potn->sigInfo.priority, /* priority (low) */
#if !defined(FEAT_OPEN_APPID)
                 0);
#else /* defined(FEAT_OPEN_APPID) */
                 0, NULL);
#endif /* defined(FEAT_OPEN_APPID) */

        if ( IPH_IS_VALID(p) )
        {
            filterEvent = sfthreshold_test(
                        potn->event_data.sig_generator,
                        potn->event_data.sig_id,
                        GET_SRC_IP(p), GET_DST_IP(p),
                        p->pkth->ts.tv_sec);
        }
        else
        {
            snort_ip cleared;
            IP_CLEAR(cleared);

            filterEvent = sfthreshold_test(
                        potn->event_data.sig_generator,
                        potn->event_data.sig_id,
                        IP_ARG(cleared), IP_ARG(cleared),
                        p->pkth->ts.tv_sec);
        }

        if(filterEvent < 0)
            filterEvent = 0;
        else
            AlertAction(p, potn, &ev);
    }
예제 #4
0
//
// Description:
//	Construct the ARP response packet to support ARP offload.
//
static void ConstructARPResponse(
	PADAPTER padapter,
	u8			*pframe,
	u32			*pLength,
	u8			*pIPAddress
	)
{
	struct rtw_ieee80211_hdr	*pwlanhdr;
	struct mlme_priv		*pmlmepriv = &padapter->mlmepriv;
	struct wlan_network		*cur_network = &pmlmepriv->cur_network;
	struct mlme_ext_priv	*pmlmeext = &(padapter->mlmeextpriv);
	struct mlme_ext_info	*pmlmeinfo = &(pmlmeext->mlmext_info);
	struct security_priv 	*psecuritypriv = &padapter->securitypriv;
	static u8				ARPLLCHeader[8] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06};

	u16		*fctrl;
	u32		pktlen;
	u8		*pARPRspPkt = pframe;
	//for TKIP Cal MIC
	u8		*payload = pframe;
	u8		EncryptionHeadOverhead = 0;

	pwlanhdr = (struct rtw_ieee80211_hdr*)pframe;

	fctrl = &pwlanhdr->frame_ctl;
	*(fctrl) = 0;

	//-------------------------------------------------------------------------
	// MAC Header.
	//-------------------------------------------------------------------------
	SetFrameType(fctrl, WIFI_DATA);
	//SetFrameSubType(fctrl, 0);
	SetToDs(fctrl);
	_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
	_rtw_memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
	_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);

	SetSeqNum(pwlanhdr, 0);
	SetDuration(pwlanhdr, 0);
	//SET_80211_HDR_FRAME_CONTROL(pARPRspPkt, 0);
	//SET_80211_HDR_TYPE_AND_SUBTYPE(pARPRspPkt, Type_Data);
	//SET_80211_HDR_TO_DS(pARPRspPkt, 1);
	//SET_80211_HDR_ADDRESS1(pARPRspPkt, pMgntInfo->Bssid);
	//SET_80211_HDR_ADDRESS2(pARPRspPkt, Adapter->CurrentAddress);
	//SET_80211_HDR_ADDRESS3(pARPRspPkt, pMgntInfo->Bssid);

	//SET_80211_HDR_DURATION(pARPRspPkt, 0);
	//SET_80211_HDR_FRAGMENT_SEQUENCE(pARPRspPkt, 0);
#ifdef CONFIG_WAPI_SUPPORT
	*pLength = sMacHdrLng;
#else
	*pLength = 24;
#endif


//YJ,del,120503
#if 0
	//-------------------------------------------------------------------------
	// Qos Header: leave space for it if necessary.
	//-------------------------------------------------------------------------
	if(pStaQos->CurrentQosMode > QOS_DISABLE)
	{
		SET_80211_HDR_QOS_EN(pARPRspPkt, 1);
		PlatformZeroMemory(&(Buffer[*pLength]), sQoSCtlLng);
		*pLength += sQoSCtlLng;
	}
#endif
	//-------------------------------------------------------------------------
	// Security Header: leave space for it if necessary.
	//-------------------------------------------------------------------------

	switch (psecuritypriv->dot11PrivacyAlgrthm)
	{
		case _WEP40_:
		case _WEP104_:
			EncryptionHeadOverhead = 4;
			break;
		case _TKIP_:
			EncryptionHeadOverhead = 8;
			break;
		case _AES_:
			EncryptionHeadOverhead = 8;
			break;
#ifdef CONFIG_WAPI_SUPPORT
		case _SMS4_:
			EncryptionHeadOverhead = 18;
			break;
#endif
		default:
			EncryptionHeadOverhead = 0;
	}

	if(EncryptionHeadOverhead > 0)
	{
		_rtw_memset(&(pframe[*pLength]), 0,EncryptionHeadOverhead);
		*pLength += EncryptionHeadOverhead;
		//SET_80211_HDR_WEP(pARPRspPkt, 1);  //Suggested by CCW.
		SetPrivacy(fctrl);
	}

	//-------------------------------------------------------------------------
	// Frame Body.
	//-------------------------------------------------------------------------
	pARPRspPkt =  (u8*)(pframe+ *pLength);
	// LLC header
	_rtw_memcpy(pARPRspPkt, ARPLLCHeader, 8);
	*pLength += 8;

	// ARP element
	pARPRspPkt += 8;
	SET_ARP_PKT_HW(pARPRspPkt, 0x0100);
	SET_ARP_PKT_PROTOCOL(pARPRspPkt, 0x0008);	// IP protocol
	SET_ARP_PKT_HW_ADDR_LEN(pARPRspPkt, 6);
	SET_ARP_PKT_PROTOCOL_ADDR_LEN(pARPRspPkt, 4);
	SET_ARP_PKT_OPERATION(pARPRspPkt, 0x0200); // ARP response
	SET_ARP_PKT_SENDER_MAC_ADDR(pARPRspPkt, myid(&(padapter->eeprompriv)));
	SET_ARP_PKT_SENDER_IP_ADDR(pARPRspPkt, pIPAddress);
	#ifdef CONFIG_ARP_KEEP_ALIVE
	if (rtw_gw_addr_query(padapter)==0) {
		SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, pmlmepriv->gw_mac_addr);
		SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pmlmepriv->gw_ip);
	}
	else
#endif
	{
		SET_ARP_PKT_TARGET_MAC_ADDR(pARPRspPkt, get_my_bssid(&(pmlmeinfo->network)));
		SET_ARP_PKT_TARGET_IP_ADDR(pARPRspPkt, pIPAddress);
		DBG_871X("%s Target Mac Addr:" MAC_FMT "\n", __FUNCTION__, MAC_ARG(get_my_bssid(&(pmlmeinfo->network))));
		DBG_871X("%s Target IP Addr" IP_FMT "\n", __FUNCTION__, IP_ARG(pIPAddress));
	}
	*pLength += 28;
	if (psecuritypriv->dot11PrivacyAlgrthm == _TKIP_)
	{
		u8	mic[8];
		struct mic_data	micdata;
		struct sta_info	*psta = NULL;
		u8	priority[4]={0x0,0x0,0x0,0x0};
		u8	null_key[16]={0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};

		DBG_871X("%s(): Add MIC\n",__FUNCTION__);

		psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network)));
		if (psta != NULL) {
			if(_rtw_memcmp(&psta->dot11tkiptxmickey.skey[0],null_key, 16)==_TRUE){
				DBG_871X("%s(): STA dot11tkiptxmickey==0\n",__FUNCTION__);
			}
			//start to calculate the mic code
			rtw_secmicsetkey(&micdata, &psta->dot11tkiptxmickey.skey[0]);
		}

		rtw_secmicappend(&micdata, pwlanhdr->addr3, 6);  //DA

		rtw_secmicappend(&micdata, pwlanhdr->addr2, 6); //SA

		priority[0]=0;
		rtw_secmicappend(&micdata, &priority[0], 4);

		rtw_secmicappend(&micdata, payload, 36); //payload length = 8 + 28

		rtw_secgetmic(&micdata,&(mic[0]));

		pARPRspPkt += 28;
		_rtw_memcpy(pARPRspPkt, &(mic[0]),8);

		*pLength += 8;
	}
}
예제 #5
0
static int Reputation_Lookup(uint16_t type, const uint8_t *data, uint32_t length, void **new_config,
        char *statusBuf, int statusBufLen)
{
    snort_ip addr;
    IPrepInfo *repInfo = NULL;
    char *tokstr, *save, *data_copy;
    CSMessageDataHeader *msg_hdr = (CSMessageDataHeader *)data;

    statusBuf[0] = 0;

    if (length <= sizeof(*msg_hdr))
    {
        return -1;
    }
    length -= sizeof(*msg_hdr);
    if (length != (uint32_t)ntohs(msg_hdr->length))
    {
        return -1;
    }

    data += sizeof(*msg_hdr);
    data_copy = malloc(length + 1);
    if (data_copy == NULL)
    {
        return -1;
    }
    memcpy(data_copy, data, length);
    data_copy[length] = 0;

    tokstr = strtok_r(data_copy, " \t\n", &save);
    if (tokstr == NULL)
    {
        free(data_copy);
        return -1;
    }

    /* Convert tokstr to sfip type */
    if (sfip_pton(tokstr, IP_ARG(addr)))
    {
        free(data_copy);
        return -1;
    }

    /* Get the reputation info */
    repInfo = ReputationLookup(IP_ARG(addr));
    if (!repInfo)
    {
        snprintf(statusBuf, statusBufLen,
            "Reputation Info: Error doing lookup");
        free(data_copy);
        return -1;
    }

    /* Are we looking to obtain the decision? */
    tokstr = strtok_r(NULL, " \t\n", &save);
    if (tokstr)
    {
        uint32_t listid;
        char *decision;
#ifdef DAQ_PKTHDR_UNKNOWN
        int zone = atoi(tokstr);
#endif

        SFSnortPacket p;
#ifdef DAQ_PKTHDR_UNKNOWN
        DAQ_PktHdr_t hdr;
        p.pkt_header = &hdr;
        hdr.ingress_group = zone;
#else
        p.pkt_header = NULL;
#endif

        switch (GetReputation(repInfo, &p, &listid))
        {
            case DECISION_NULL:
            decision = "DECISION_NULL";
            break;

            case BLACKLISTED:
            decision = "BLACKLISTED";
            break;

            case WHITELISTED_UNBLACK:
            decision = "WHITELISTED UNBLACK";
            break;

            case MONITORED:
            decision = "MONITORED";
            break;

            case WHITELISTED_TRUST:
            decision = "WHITELISTED TRUST";
            break;

            default:
            decision = "UNKNOWN";
            break;
        }

        snprintf(statusBuf, statusBufLen,
            "Reputation Info: %s in list %d"
#ifdef DAQ_PKTHDR_UNKNOWN
            " from zone %d"
#endif
            ,decision, listid
#ifdef DAQ_PKTHDR_UNKNOWN
            ,zone
#endif
            );
    }
    else
    {
        ReputationRepInfo(repInfo,
            (uint8_t *)reputation_eval_config->iplist,
            statusBuf, statusBufLen);
    }

    free(data_copy);
    return 0;
}
예제 #6
0
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;

}