tcpdump mailing list archives

Re: Missing packet fields in big endian with ath9k


From: Guy Harris <guy () alum mit edu>
Date: Sun, 28 Apr 2013 16:24:22 -0700

And you can probably unroll the iteration loop into something such as

/* use appropriate 8-bit/16-bit/32-bit unsigned types here */
struct ieee80211_radiotap_header {
        u_int8_t        it_version;     /* set to 0 */
        u_int8_t        it_pad;
        u_int16_t       it_len;         /* entire length */
        u_int32_t       it_present;     /* fields present */
} __attribute__((__packed__));

/* Presence bits */
#define RADIOTAP_TSFT                   0
#define RADIOTAP_FLAGS                  1
#define RADIOTAP_RATE                   2
#define RADIOTAP_CHANNEL                3
#define RADIOTAP_FHSS                   4
#define RADIOTAP_ANTENNA_SIGNAL         5
#define RADIOTAP_ANTENNA_NOISE          6
#define RADIOTAP_LOCK_QUALITY           7
#define RADIOTAP_TX_ATTENUATION         8
#define RADIOTAP_DB_TX_ATTENUATION      9
#define RADIOTAP_DBM_TX_POWER           10
#define RADIOTAP_ANTENNA                11
#define RADIOTAP_DB_ANTENNA_SIGNAL      12
/* We don't care about anything after this */

#define ALIGN2(p)       ((p) += ((intptr_t)(p) & 0x1))

                ...

        struct ieee80211_radiotap_header *first = (struct ieee80211_radiotap_header*) (data);
        int rssi = RSSI_UNKNOWN;        /* pick an out of band value here */

        int radio_len3 = get_unaligned_le16(&first->it_len);
                
                ...

        u_int8_t *p = data + sizeof (struct ieee80211_radiotap_header);
        u_int32_t presence_bits = get_unaligned_le32(&first->it_present);
#define IS_PRESENT(field)       (presence_bits & (0x1 << (field)))
        if (IS_PRESENT(RADIOTAP_TSFT)) {
                /* Requires 8-byte alignment, but header is 8 bytes long */
                p += 8;
        }
        if (IS_PRESENT(RADIOTAP_FLAGS)) {
                /* 1-byte value */
                p += 1; /
        }
        if (IS_PRESENT(RADIOTAP_RATE)) {
                /* 1-byte value */
                p += 2;
        }
        if (IS_PRESENT(RADIOTAP_CHANNEL)) {
                /* 2 2-byte values */
                ALIGN2(p);
                p += 4;
        }
        if (IS_PRESENT(RADIOTAP_FHSS)) {
                /* 2 1-byte values */
                p += 2;
        }
        if (IS_PRESENT(RADIOTAP_ANTENNA_SIGNAL)) {
                /* 1-bit value */
                /*
                 * This is a *SIGNED* value, so it could be positive or negative.
                 * If you want a value guaranteed to be positive, add 128 to it.
                 */
                rssi = *p;
                finish up;      /* no need to look for RADIOTAP_DB_ANTENNA_SIGNAL */
        }
        if (IS_PRESENT(RADIOTAP_ANTENNA_NOISE)) {
                /* 1-byte value */
                p += 1;
        }
        if (IS_PRESENT(RADIOTAP_LOCK_QUALITY)) {
                /* 2-byte value */
                ALIGN2(p);
                p += 2;
        }
        if (IS_PRESENT(RADIOTAP_TX_ATTENUATION)) {
                /* 2-byte value */
                ALIGN2(p);
                p += 2;
        }
        if (IS_PRESENT(RADIOTAP_DB_TX_ATTENUATION)) {
                /* 2-byte value */
                ALIGN2(p);
                p += 2;
        }
        if (IS_PRESENT(RADIOTAP_DBM_TX_POWER)) {
                /* 1-byte value */
                p += 1;
        }
        if (IS_PRESENT(RADIOTAP_ANTENNA)) {
                /* 1-byte value */
                p += 1;
        }
        if (IS_PRESENT(RADIOTAP_DB_ANTENNA_SIGNAL)) {
                /* 1-bit value */
                /*
                 * This is an *UNSIGNED* value, so it is *always* positive.
                 */
                rssi = *p;
        }
        finish up;      /* either we have the RSSI or we don't */
_______________________________________________
tcpdump-workers mailing list
tcpdump-workers () lists tcpdump org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers


Current thread: