Exemple #1
0
/* Validates a packet's reported FCS value */
static int check_fcs(const unsigned char *packet, size_t len)
{
	if(!has_rt_header()) return 1;

	uint32_t offset = 0, match = 0;
	uint32_t fcs = 0, fcs_calc = 0;
	struct radio_tap_header *rt_header = NULL;

	if(len > 4)
	{

		/* FCS is not calculated over the radio tap header */
		if(len >= sizeof(*rt_header))
		{
			uint32_t presentflags, flags;
			if(!rt_get_presentflags(packet, len, &presentflags, &offset))
				goto skip;
			if(!(presentflags & (1U << IEEE80211_RADIOTAP_FLAGS)))
				goto skip;
			offset = rt_get_flag_offset(presentflags, IEEE80211_RADIOTAP_FLAGS, offset);
			if(offset < len) {
				memcpy(&flags, packet + offset, 4);
				flags = end_le32toh(flags);
				if(flags & IEEE80211_RADIOTAP_F_BADFCS)
					return 0;
				if(!(flags & IEEE80211_RADIOTAP_F_FCS))
					return 1;
			}

			skip:
			rt_header = (struct radio_tap_header *) packet;
			offset = end_le16toh(rt_header->len);

		}

		/* Get the packet's reported FCS (last 4 bytes of the packet) */
		fcs = end_le32toh(*(uint32_t*)(packet + (len-4)));


		if(len > offset)
		{
			/* FCS is the inverse of the CRC32 checksum of the data packet minus the frame's FCS and radio tap header (if any) */
			fcs_calc = ~crc32((char *) packet+offset, (len-offset-4));

			if(fcs_calc == fcs)
			{
				match = 1;
			}
		}
	}

	return match;

}
/* 
 * Returns a pointer to the radio tap header. If there is no radio tap header,
 * it returns a pointer to a dummy radio tap header.
 */
const u_char *radio_header(const u_char *packet, size_t len)
{
    if(has_rt_header())
    {
        return packet;
    }
    else
    {
        return (u_char *) FAKE_RADIO_TAP_HEADER;
    }

}
Exemple #3
0
/* 
 * Returns a pointer to the radio tap header. If there is no radio tap header,
 * it returns a pointer to a dummy radio tap header.
 */
unsigned char *radio_header(const unsigned char *packet, size_t len)
{
        if(has_rt_header())
        {
                return (void*)packet;
        }
        else
        {
                return FAKE_RADIO_TAP_HEADER;
        }

}
/* Extracts the signal strength field (if any) from the packet's radio tap header */
int8_t signal_strength(const u_char *packet, size_t len)
{
    int8_t ssi = 0;
    int offset = sizeof(struct radio_tap_header);
    struct radio_tap_header *header = NULL;

    if(has_rt_header() && (len > (sizeof(struct radio_tap_header) + TSFT_SIZE + FLAGS_SIZE + RATE_SIZE + CHANNEL_SIZE + FHSS_FLAG)))
    {
        header = (struct radio_tap_header *) packet;

        if((header->flags & SSI_FLAG) == SSI_FLAG)
        {
            if((header->flags & TSFT_FLAG) == TSFT_FLAG)
            {
                offset += TSFT_SIZE;
            }

            if((header->flags & FLAGS_FLAG) == FLAGS_FLAG)
            {
                offset += FLAGS_SIZE;
            }

            if((header->flags & RATE_FLAG) == RATE_FLAG)
            {
                offset += RATE_SIZE;
            }

            if((header->flags & CHANNEL_FLAG) == CHANNEL_FLAG)
            {
                offset += CHANNEL_SIZE;
            }

            if((header->flags & FHSS_FLAG) == FHSS_FLAG)
            {
                offset += FHSS_FLAG;
            } else {
                offset += 12;
            }

            if(offset < len)
            {
                ssi = (int8_t) packet[offset];
            }
            
            if (ssi > 100) {
                ssi = 100 - ssi;
            }
        }
    }

    return ssi;
}
Exemple #5
0
/* Extracts the signal strength field (if any) from the packet's radio tap header */
int8_t signal_strength(const unsigned char *packet, size_t len)
{
	if(has_rt_header() && (len > (sizeof(struct radio_tap_header))))
	{
		uint32_t offset, presentflags;
		if(!rt_get_presentflags(packet, len, &presentflags, &offset))
			return 0;
		if(!(presentflags & (1U << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)))
			return 0;
		offset = rt_get_flag_offset(presentflags, IEEE80211_RADIOTAP_DBM_ANTSIGNAL, offset);
		if (offset < len)
			return (int8_t) packet[offset];
	}

	return 0;
}
/* Validates a packet's reported FCS value */
int check_fcs(const u_char *packet, size_t len)
{
    int offset = 0, match = 0;
    uint32_t fcs = 0, fcs_calc = 0;
    struct radio_tap_header *rt_header = NULL;

    if(len > 4)
    {
        /* Get the packet's reported FCS (last 4 bytes of the packet) */
        memcpy((uint32_t *) &fcs, (packet + (len-4)), 4);

        /* FCS is not calculated over the radio tap header */
        if(has_rt_header())
        {
            rt_header = (struct radio_tap_header *) packet;
            
#ifdef __APPLE__
                        unsigned char *body = (unsigned char*) (rt_header+1);
                        uint32_t present = rt_header->flags;
                        uint8_t rflags = 0;
                        int i;
                        for (i = IEEE80211_RADIOTAP_TSFT; i <= IEEE80211_RADIOTAP_EXT; i++) {
                                if (!(present & (1 << i))) continue;
                                switch (i) {
                                            case IEEE80211_RADIOTAP_TSFT:
                                                body += sizeof(uint64_t);
                                                break;
                        
                                            case IEEE80211_RADIOTAP_FLAGS:
                                                rflags = *((uint8_t*)body);
                                                /* fall through */
                                            case IEEE80211_RADIOTAP_RATE:
                                                body += sizeof(uint8_t);
                                                break;
                        
                                            case IEEE80211_RADIOTAP_CHANNEL:
                                                body += sizeof(uint16_t)*2;
                                                break;
                        
                                            case IEEE80211_RADIOTAP_RX_FLAGS:
                                            case IEEE80211_RADIOTAP_FHSS:
                                                body += sizeof(uint16_t);
                                                break;
                        
                                            case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
                                            case IEEE80211_RADIOTAP_DBM_ANTNOISE:
                                            case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
                                            case IEEE80211_RADIOTAP_DB_ANTNOISE:
                                            case IEEE80211_RADIOTAP_ANTENNA:
                                                body++;
                                                break;
                        
                                            case 18: // IEEE80211_RADIOTAP_XCHANNEL
                                                body += sizeof(uint32_t);
                                                body += sizeof(uint16_t);
                                                body += sizeof(uint8_t);
                                                body += sizeof(uint8_t);
                                                break;
                                        
                                            case 19: // IEEE80211_RADIOTAP_MCS
                                                body += 3*sizeof(uint8_t);
                                                break;
                                        
                                            default:
                                                i = IEEE80211_RADIOTAP_EXT+1;
                                                break;
                                    }
                            }
                        #define IEEE80211_RADIOTAP_F_BADFCS 0x40
                        if (rflags & IEEE80211_RADIOTAP_F_BADFCS) {
                                // bad FCS, ignore
                                return 0;
                            }
                        if (!(rflags & IEEE80211_RADIOTAP_F_FCS)) {
                                // fcs not always present
                                return 1;
                            }
#endif
            
            offset += rt_header->len;
        }

        if(len > offset)
        {
            /* FCS is the inverse of the CRC32 checksum of the data packet minus the frame's FCS and radio tap header (if any) */
            fcs_calc = ~crc32((char *) packet+offset, (len-offset-4));

            if(fcs_calc == fcs)
            {
                match = 1;
            }
        }
    }

    return match;

}