Add radiotap support, which was not in release 3.8.3.

This commit is contained in:
dyoung 2004-09-28 00:01:02 +00:00
parent 88f1d7df8c
commit 79eff8033d
6 changed files with 635 additions and 14 deletions

144
dist/tcpdump/cpack.c vendored Normal file
View File

@ -0,0 +1,144 @@
/*-
* Copyright (c) 2003, 2004 David Young. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of David Young may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
* YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <tcpdump-stdinc.h>
#include "cpack.h"
#include "extract.h"
static u_int8_t *
cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment)
{
size_t misalignment = (size_t)(p - buf) % alignment;
if (misalignment == 0)
return p;
return p + (alignment - misalignment);
}
/* Advance to the next wordsize boundary. Return NULL if fewer than
* wordsize bytes remain in the buffer after the boundary. Otherwise,
* return a pointer to the boundary.
*/
static u_int8_t *
cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize)
{
u_int8_t *next;
/* Ensure alignment. */
next = cpack_next_boundary(cs->c_buf, cs->c_next, wordsize);
/* Too little space for wordsize bytes? */
if (next - cs->c_buf + wordsize > cs->c_len)
return NULL;
return next;
}
int
cpack_init(struct cpack_state *cs, u_int8_t *buf, size_t buflen)
{
memset(cs, 0, sizeof(*cs));
cs->c_buf = buf;
cs->c_len = buflen;
cs->c_next = cs->c_buf;
return 0;
}
/* Unpack a 64-bit unsigned integer. */
int
cpack_uint64(struct cpack_state *cs, u_int64_t *u)
{
u_int8_t *next;
if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL)
return -1;
*u = EXTRACT_LE_64BITS(next);
/* Move pointer past the u_int64_t. */
cs->c_next = next + sizeof(*u);
return 0;
}
/* Unpack a 32-bit unsigned integer. */
int
cpack_uint32(struct cpack_state *cs, u_int32_t *u)
{
u_int8_t *next;
if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL)
return -1;
*u = EXTRACT_LE_32BITS(next);
/* Move pointer past the u_int32_t. */
cs->c_next = next + sizeof(*u);
return 0;
}
/* Unpack a 16-bit unsigned integer. */
int
cpack_uint16(struct cpack_state *cs, u_int16_t *u)
{
u_int8_t *next;
if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL)
return -1;
*u = EXTRACT_LE_16BITS(next);
/* Move pointer past the u_int16_t. */
cs->c_next = next + sizeof(*u);
return 0;
}
/* Unpack an 8-bit unsigned integer. */
int
cpack_uint8(struct cpack_state *cs, u_int8_t *u)
{
/* No space left? */
if ((size_t)(cs->c_next - cs->c_buf) >= cs->c_len)
return -1;
*u = *cs->c_next;
/* Move pointer past the u_int8_t. */
cs->c_next++;
return 0;
}

51
dist/tcpdump/cpack.h vendored Normal file
View File

@ -0,0 +1,51 @@
/*-
* Copyright (c) 2003, 2004 David Young. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of David Young may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
* YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef _CPACK_H
#define _CPACK_H
struct cpack_state {
u_int8_t *c_buf;
u_int8_t *c_next;
size_t c_len;
};
int cpack_init(struct cpack_state *, u_int8_t *, size_t);
int cpack_uint8(struct cpack_state *, u_int8_t *);
int cpack_uint16(struct cpack_state *, u_int16_t *);
int cpack_uint32(struct cpack_state *, u_int32_t *);
int cpack_uint64(struct cpack_state *, u_int64_t *);
#define cpack_int8(__s, __p) cpack_uint8((__s), (u_int8_t*)(__p))
#define cpack_int16(__s, __p) cpack_uint16((__s), (u_int16_t*)(__p))
#define cpack_int32(__s, __p) cpack_uint32((__s), (u_int32_t*)(__p))
#define cpack_int64(__s, __p) cpack_uint64((__s), (u_int64_t*)(__p))
#endif /* _CPACK_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: extract.h,v 1.1.1.3 2004/09/27 17:06:44 dyoung Exp $ */
/* $NetBSD: extract.h,v 1.2 2004/09/28 00:01:02 dyoung Exp $ */
/*
* Copyright (c) 1992, 1993, 1994, 1995, 1996
@ -23,8 +23,9 @@
* @(#) Header: /tcpdump/master/tcpdump/extract.h,v 1.19 2002/12/11 07:13:51 guy Exp (LBL)
*/
/* Network to host order macros */
/*
* Macros to extract possibly-unaligned big-endian integral values.
*/
#ifdef LBL_ALIGN
/*
* The processor doesn't natively handle unaligned loads.
@ -56,6 +57,10 @@ typedef struct {
((u_int16_t)ntohs(((const unaligned_u_int16_t *)(p))->val))
#define EXTRACT_32BITS(p) \
((u_int32_t)ntohl(((const unaligned_u_int32_t *)(p))->val))
#define EXTRACT_64BITS(p) \
((u_int64_t)(((u_int64_t)ntohl(((const unaligned_u_int32_t *)(p) + 0)->val)) << 32 | \
((u_int64_t)ntohl(((const unaligned_u_int32_t *)(p) + 1)->val)) << 0))
#else /* HAVE___ATTRIBUTE__ */
/*
* We don't have __attribute__, so do unaligned loads of big-endian
@ -70,6 +75,15 @@ typedef struct {
(u_int32_t)*((const u_int8_t *)(p) + 1) << 16 | \
(u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | \
(u_int32_t)*((const u_int8_t *)(p) + 3)))
#define EXTRACT_LE_64BITS(p) \
((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 0) << 56 | \
(u_int64_t)*((const u_int8_t *)(p) + 1) << 48 | \
(u_int64_t)*((const u_int8_t *)(p) + 2) << 40 | \
(u_int64_t)*((const u_int8_t *)(p) + 3) << 32 | \
(u_int64_t)*((const u_int8_t *)(p) + 4) << 24 | \
(u_int64_t)*((const u_int8_t *)(p) + 5) << 16 | \
(u_int64_t)*((const u_int8_t *)(p) + 6) << 8 | \
(u_int64_t)*((const u_int8_t *)(p) + 7)))
#endif /* HAVE___ATTRIBUTE__ */
#else /* LBL_ALIGN */
/*
@ -80,6 +94,9 @@ typedef struct {
((u_int16_t)ntohs(*(const u_int16_t *)(p)))
#define EXTRACT_32BITS(p) \
((u_int32_t)ntohl(*(const u_int32_t *)(p)))
#define EXTRACT_64BITS(p) \
((u_int64_t)(((u_int64_t)ntohl(*((const u_int32_t *)(p) + 0))) << 32 | \
((u_int64_t)ntohl(*((const u_int32_t *)(p) + 1))) << 0))
#endif /* LBL_ALIGN */
#define EXTRACT_24BITS(p) \
@ -87,8 +104,10 @@ typedef struct {
(u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \
(u_int32_t)*((const u_int8_t *)(p) + 2)))
/* Little endian protocol host order macros */
/*
* Macros to extract possibly-unaligned little-endian integral values.
* XXX - do loads on little-endian machines that support unaligned loads?
*/
#define EXTRACT_LE_8BITS(p) (*(p))
#define EXTRACT_LE_16BITS(p) \
((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 1) << 8 | \
@ -98,3 +117,12 @@ typedef struct {
(u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \
(u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \
(u_int32_t)*((const u_int8_t *)(p) + 0)))
#define EXTRACT_LE_64BITS(p) \
((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 7) << 56 | \
(u_int64_t)*((const u_int8_t *)(p) + 6) << 48 | \
(u_int64_t)*((const u_int8_t *)(p) + 5) << 40 | \
(u_int64_t)*((const u_int8_t *)(p) + 4) << 32 | \
(u_int64_t)*((const u_int8_t *)(p) + 3) << 24 | \
(u_int64_t)*((const u_int8_t *)(p) + 2) << 16 | \
(u_int64_t)*((const u_int8_t *)(p) + 1) << 8 | \
(u_int64_t)*((const u_int8_t *)(p) + 0)))

201
dist/tcpdump/ieee802_11_radio.h vendored Normal file
View File

@ -0,0 +1,201 @@
/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.1 2003/09/05 22:19:32 sam Exp $ */
/* $NetBSD: ieee802_11_radio.h,v 1.1 2004/09/28 00:01:02 dyoung Exp $ */
/* $Header: /cvsroot/src/dist/tcpdump/Attic/ieee802_11_radio.h,v 1.1 2004/09/28 00:01:02 dyoung Exp $ */
/*-
* Copyright (c) 2003, 2004 David Young. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of David Young may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
* YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#ifndef _NET_IF_IEEE80211RADIOTAP_H_
#define _NET_IF_IEEE80211RADIOTAP_H_
/* A generic radio capture format is desirable. There is one for
* Linux, but it is neither rigidly defined (there were not even
* units given for some fields) nor easily extensible.
*
* I suggest the following extensible radio capture format. It is
* based on a bitmap indicating which fields are present.
*
* I am trying to describe precisely what the application programmer
* should expect in the following, and for that reason I tell the
* units and origin of each measurement (where it applies), or else I
* use sufficiently weaselly language ("is a monotonically nondecreasing
* function of...") that I cannot set false expectations for lawyerly
* readers.
*/
#ifdef _KERNEL
#ifndef DLT_IEEE802_11_RADIO
#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus WLAN header */
#endif
#endif /* _KERNEL */
/* The radio capture header precedes the 802.11 header. */
struct ieee80211_radiotap_header {
u_int8_t it_version; /* Version 0. Only increases
* for drastic changes,
* introduction of compatible
* new fields does not count.
*/
u_int8_t it_pad;
u_int16_t it_len; /* length of the whole
* header in bytes, including
* it_version, it_pad,
* it_len, and data fields.
*/
u_int32_t it_present; /* A bitmap telling which
* fields are present. Set bit 31
* (0x80000000) to extend the
* bitmap by another 32 bits.
* Additional extensions are made
* by setting bit 31.
*/
} __attribute__((__packed__));
/* Name Data type Units
* ---- --------- -----
*
* IEEE80211_RADIOTAP_TSFT u_int64_t microseconds
*
* Value in microseconds of the MAC's 64-bit 802.11 Time
* Synchronization Function timer when the first bit of the
* MPDU arrived at the MAC. For received frames, only.
*
* IEEE80211_RADIOTAP_CHANNEL 2 x u_int16_t MHz, bitmap
*
* Tx/Rx frequency in MHz, followed by flags (see below).
*
* IEEE80211_RADIOTAP_FHSS u_int16_t see below
*
* For frequency-hopping radios, the hop set (first byte)
* and pattern (second byte).
*
* IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s
*
* Tx/Rx data rate
*
* IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from
* one milliwatt (dBm)
*
* RF signal power at the antenna, decibel difference from
* one milliwatt.
*
* IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from
* one milliwatt (dBm)
*
* RF noise power at the antenna, decibel difference from one
* milliwatt.
*
* IEEE80211_RADIOTAP_DB_ANTSIGNAL u_int8_t decibel (dB)
*
* RF signal power at the antenna, decibel difference from an
* arbitrary, fixed reference.
*
* IEEE80211_RADIOTAP_DB_ANTNOISE u_int8_t decibel (dB)
*
* RF noise power at the antenna, decibel difference from an
* arbitrary, fixed reference point.
*
* IEEE80211_RADIOTAP_BARKER_CODE_LOCK u_int16_t unitless
*
* Quality of Barker code lock. Unitless. Monotonically
* nondecreasing with "better" lock strength. Called "Signal
* Quality" in datasheets. (Is there a standard way to measure
* this?)
*
* IEEE80211_RADIOTAP_TX_ATTENUATION u_int16_t unitless
*
* Transmit power expressed as unitless distance from max
* power set at factory calibration. 0 is max power.
* Monotonically nondecreasing with lower power levels.
*
* IEEE80211_RADIOTAP_DB_TX_ATTENUATION u_int16_t decibels (dB)
*
* Transmit power expressed as decibel distance from max power
* set at factory calibration. 0 is max power. Monotonically
* nondecreasing with lower power levels.
*
* IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from
* one milliwatt (dBm)
*
* Transmit power expressed as dBm (decibels from a 1 milliwatt
* reference). This is the absolute power level measured at
* the antenna port.
*
* IEEE80211_RADIOTAP_FLAGS u_int8_t bitmap
*
* Properties of transmitted and received frames. See flags
* defined below.
*
* IEEE80211_RADIOTAP_ANTENNA u_int8_t antenna index
*
* Unitless indication of the Rx/Tx antenna for this packet.
* The first antenna is antenna 0.
*/
enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_TSFT = 0,
IEEE80211_RADIOTAP_FLAGS = 1,
IEEE80211_RADIOTAP_RATE = 2,
IEEE80211_RADIOTAP_CHANNEL = 3,
IEEE80211_RADIOTAP_FHSS = 4,
IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
IEEE80211_RADIOTAP_ANTENNA = 11,
IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
IEEE80211_RADIOTAP_EXT = 31
};
#ifndef _KERNEL
/* Channel flags. */
#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
#endif /* !_KERNEL */
/* For IEEE80211_RADIOTAP_FLAGS */
#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
* during CFP
*/
#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
* with short
* preamble
*/
#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
* with WEP encryption
*/
#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
* with fragmentation
*/
#endif /* _NET_IF_IEEE80211RADIOTAP_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: print-802_11.c,v 1.7 2004/09/27 23:04:24 dyoung Exp $ */
/* $NetBSD: print-802_11.c,v 1.8 2004/09/28 00:01:02 dyoung Exp $ */
/*
* Copyright (c) 2001
@ -28,7 +28,7 @@
static const char rcsid[] _U_ =
"@(#) Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.22.2.6 2003/12/10 09:52:33 guy Exp (LBL)";
#else
__RCSID("$NetBSD: print-802_11.c,v 1.7 2004/09/27 23:04:24 dyoung Exp $");
__RCSID("$NetBSD: print-802_11.c,v 1.8 2004/09/28 00:01:02 dyoung Exp $");
#endif
#endif
@ -48,15 +48,20 @@ __RCSID("$NetBSD: print-802_11.c,v 1.7 2004/09/27 23:04:24 dyoung Exp $");
#include "extract.h"
#include "ieee802_11.h"
#include "cpack.h"
#include "ieee802_11.h"
#include "ieee802_11_radio.h"
#define PRINT_RATE(_sep, _r, _suf) \
printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
#define PRINT_RATES(p) \
do { \
int z; \
const char *sep = " ["; \
for (z = 0; z < p.rates.length ; z++) { \
printf("%s%2.1f", sep, (.5 * (p.rates.rate[z] & 0x7f))); \
if (p.rates.rate[z] & 0x80) printf("*"); \
PRINT_RATE(sep, p.rates.rate[z], \
(p.rates.rate[z] & 0x80 ? "*" : "")); \
sep = " "; \
} \
if (p.rates.length != 0) \
@ -917,7 +922,7 @@ ieee802_11_print(const u_char *p, u_int length, u_int caplen)
/*
* This is the top level routine of the printer. 'p' points
* to the 802.11 header of the packet, 'h->ts' is the timestamp,
* 'h->length' is the length of the packet off the wire, and 'h->caplen'
* 'h->len' is the length of the packet off the wire, and 'h->caplen'
* is the number of bytes actually captured.
*/
u_int
@ -926,8 +931,200 @@ ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
return ieee802_11_print(p, h->len, h->caplen);
}
static int
print_radiotap_field(struct cpack_state *s, u_int32_t bit)
{
union {
int8_t i8;
u_int8_t u8;
int16_t i16;
u_int16_t u16;
u_int32_t u32;
u_int64_t u64;
} u, u2;
int rc;
switch (bit) {
case IEEE80211_RADIOTAP_FLAGS:
case IEEE80211_RADIOTAP_RATE:
case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
case IEEE80211_RADIOTAP_DB_ANTNOISE:
case IEEE80211_RADIOTAP_ANTENNA:
rc = cpack_uint8(s, &u.u8);
break;
case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
case IEEE80211_RADIOTAP_DBM_ANTNOISE:
rc = cpack_int8(s, &u.i8);
break;
case IEEE80211_RADIOTAP_CHANNEL:
rc = cpack_uint16(s, &u.u16);
if (rc != 0)
break;
rc = cpack_uint16(s, &u2.u16);
break;
case IEEE80211_RADIOTAP_FHSS:
case IEEE80211_RADIOTAP_LOCK_QUALITY:
case IEEE80211_RADIOTAP_TX_ATTENUATION:
rc = cpack_uint16(s, &u.u16);
break;
case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
rc = cpack_uint8(s, &u.u8);
break;
case IEEE80211_RADIOTAP_DBM_TX_POWER:
rc = cpack_uint8(s, &u.i8);
break;
case IEEE80211_RADIOTAP_TSFT:
rc = cpack_uint64(s, &u.u64);
break;
default:
/* this bit indicates a field whose
* size we do not know, so we cannot
* proceed.
*/
printf("[0x%08x] ", bit);
return -1;
}
if (rc != 0) {
printf("[|802.11]");
return rc;
}
switch (bit) {
case IEEE80211_RADIOTAP_CHANNEL:
printf("%u MHz ", u.u16);
if (u2.u16 != 0)
printf("(0x%04x) ", u2.u16);
break;
case IEEE80211_RADIOTAP_FHSS:
printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
break;
case IEEE80211_RADIOTAP_RATE:
PRINT_RATE("", u.u8, " Mb/s ");
break;
case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
printf("%ddB signal ", u.i8);
break;
case IEEE80211_RADIOTAP_DBM_ANTNOISE:
printf("%ddB noise ", u.i8);
break;
case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
printf("%ddB signal ", u.u8);
break;
case IEEE80211_RADIOTAP_DB_ANTNOISE:
printf("%ddB noise ", u.u8);
break;
case IEEE80211_RADIOTAP_LOCK_QUALITY:
printf("%u sq ", u.u16);
break;
case IEEE80211_RADIOTAP_TX_ATTENUATION:
printf("%d tx power ", -(int)u.u16);
break;
case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
printf("%ddB tx power ", -(int)u.u8);
break;
case IEEE80211_RADIOTAP_DBM_TX_POWER:
printf("%ddBm tx power ", u.i8);
break;
case IEEE80211_RADIOTAP_FLAGS:
if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
printf("cfp ");
if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
printf("short preamble ");
if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
printf("wep ");
if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
printf("fragmented ");
break;
case IEEE80211_RADIOTAP_ANTENNA:
printf("antenna %d ", u.u8);
break;
case IEEE80211_RADIOTAP_TSFT:
printf("%" PRIu64 "us tsft ", u.u64);
break;
}
return 0;
}
static u_int
ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
{
#define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
#define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
#define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
#define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
#define BITNO_2(x) (((x) & 2) ? 1 : 0)
#define BIT(n) (1 << n)
#define IS_EXTENDED(__p) \
(EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
struct cpack_state cpacker;
struct ieee80211_radiotap_header *hdr;
u_int32_t present, next_present;
u_int32_t *presentp, *last_presentp;
enum ieee80211_radiotap_type bit;
int bit0;
const u_char *iter;
u_int len;
if (caplen < sizeof(*hdr)) {
printf("[|802.11]");
return caplen;
}
hdr = (struct ieee80211_radiotap_header *)p;
len = EXTRACT_LE_16BITS(&hdr->it_len);
if (caplen < len) {
printf("[|802.11]");
return caplen;
}
for (last_presentp = &hdr->it_present;
IS_EXTENDED(last_presentp) &&
(u_char*)(last_presentp + 1) <= p + len;
last_presentp++);
/* are there more bitmap extensions than bytes in header? */
if (IS_EXTENDED(last_presentp)) {
printf("[|802.11]");
return caplen;
}
iter = (u_char*)(last_presentp + 1);
if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
/* XXX */
printf("[|802.11]");
return caplen;
}
for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
presentp++, bit0 += 32) {
for (present = EXTRACT_LE_32BITS(presentp); present;
present = next_present) {
/* clear the least significant bit that is set */
next_present = present & (present - 1);
/* extract the least significant bit that is set */
bit = bit0 + BITNO_32(present ^ next_present);
if (print_radiotap_field(&cpacker, bit) != 0)
goto out;
}
}
out:
return len + ieee802_11_print(p + len, length - len, caplen - len);
#undef BITNO_32
#undef BITNO_16
#undef BITNO_8
#undef BITNO_4
#undef BITNO_2
#undef BIT
}
static u_int
ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
{
u_int32_t caphdr_len;
@ -979,7 +1176,7 @@ prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
}
if (EXTRACT_32BITS(p) == WLANCAP_MAGIC_COOKIE_V1)
return ieee802_11_radio_print(p, length, caplen);
return ieee802_11_avs_radio_print(p, length, caplen);
if (caplen < PRISM_HDR_LEN) {
printf("[|802.11]");

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.35 2004/09/27 23:04:50 dyoung Exp $
# $NetBSD: Makefile,v 1.36 2004/09/28 00:01:02 dyoung Exp $
.include <bsd.own.mk>
@ -8,7 +8,7 @@ SRCDIR= ${NETBSDSRCDIR}/dist/tcpdump
PROG= tcpdump
MAN= tcpdump.8
SRCS= addrtoname.c gmpls.c gmt2local.c machdep.c oui.c parsenfsfh.c \
SRCS= addrtoname.c cpack.c gmpls.c gmt2local.c machdep.c oui.c parsenfsfh.c \
print-802_11.c print-ah.c print-aodv.c print-ap1394.c print-arcnet.c \
print-arp.c \
print-ascii.c print-atalk.c print-atm.c print-bfd.c print-bgp.c \