summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/tcpdump/Makefile3
-rw-r--r--usr.sbin/tcpdump/interface.h10
-rw-r--r--usr.sbin/tcpdump/print-802_11.c627
-rw-r--r--usr.sbin/tcpdump/tcpdump.c21
-rw-r--r--usr.sbin/tcpdump/util.c36
5 files changed, 689 insertions, 8 deletions
diff --git a/usr.sbin/tcpdump/Makefile b/usr.sbin/tcpdump/Makefile
index 4ba390f2b92..989805fa24b 100644
--- a/usr.sbin/tcpdump/Makefile
+++ b/usr.sbin/tcpdump/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.46 2004/04/28 02:17:03 mcbride Exp $
+# $OpenBSD: Makefile,v 1.47 2005/03/07 16:13:38 reyk Exp $
#
# Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
# The Regents of the University of California. All rights reserved.
@@ -46,6 +46,7 @@ SRCS= tcpdump.c addrtoname.c privsep.c privsep_fdpass.c privsep_pcap.c \
print-etherip.c print-lwres.c print-cdp.c print-pflog.c \
print-pfsync.c pf_print_state.c \
print-udpencap.c print-carp.c \
+ print-802_11.c \
gmt2local.c savestr.c setsignal.c
# TCP OS Fingerprinting
diff --git a/usr.sbin/tcpdump/interface.h b/usr.sbin/tcpdump/interface.h
index 7d0ca560229..cf87a9441aa 100644
--- a/usr.sbin/tcpdump/interface.h
+++ b/usr.sbin/tcpdump/interface.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: interface.h,v 1.47 2004/09/16 11:29:51 markus Exp $ */
+/* $OpenBSD: interface.h,v 1.48 2005/03/07 16:13:38 reyk Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -20,7 +20,7 @@
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * @(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/interface.h,v 1.47 2004/09/16 11:29:51 markus Exp $ (LBL)
+ * @(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/interface.h,v 1.48 2005/03/07 16:13:38 reyk Exp $ (LBL)
*/
#ifndef tcpdump_interface_h
@@ -79,6 +79,7 @@ extern int packettype; /* as specified by -T */
#define DEFAULT_SNAPLEN 96
#endif /* INET6 */
#define SACK_SNAPLEN 94
+#define RADIOTAP_SNAPLEN (DEFAULT_SNAPLEN + 64)
#ifndef BIG_ENDIAN
#define BIG_ENDIAN 4321
@@ -159,6 +160,7 @@ extern const char *tok2str(const struct tok *, const char *, int);
extern char *dnaddr_string(u_short);
extern void safeputs(const char *);
extern void safeputchar(int);
+extern void printb(char *, unsigned short, char *);
extern void wrapup(int);
@@ -211,6 +213,10 @@ extern void ppp_ether_if_print(u_char *, const struct pcap_pkthdr *,
const u_char *);
extern void gre_print(const u_char *, u_int);
extern void icmp_print(const u_char *, const u_char *);
+extern void ieee802_11_if_print(u_char *, const struct pcap_pkthdr *,
+ const u_char *);
+extern void ieee802_11_radio_if_print(u_char *, const struct pcap_pkthdr *,
+ const u_char *);
extern void igrp_print(const u_char *, u_int, const u_char *);
extern void ip_print(const u_char *, u_int);
extern void ipx_print(const u_char *, u_int);
diff --git a/usr.sbin/tcpdump/print-802_11.c b/usr.sbin/tcpdump/print-802_11.c
new file mode 100644
index 00000000000..f259b43274e
--- /dev/null
+++ b/usr.sbin/tcpdump/print-802_11.c
@@ -0,0 +1,627 @@
+/* $OpenBSD: print-802_11.c,v 1.1 2005/03/07 16:13:38 reyk Exp $ */
+
+/*
+ * Copyright (c) 2005 Reyk Floeter <reyk@vantronix.net>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/if_ether.h>
+
+#include <net80211/ieee80211.h>
+#include <net80211/ieee80211_radiotap.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+
+const char *ieee80211_mgt_subtype_name[] = {
+ "association request",
+ "association response",
+ "reassociation request",
+ "reassociation response",
+ "probe request",
+ "probe response",
+ "reserved#6",
+ "reserved#7",
+ "beacon",
+ "atim",
+ "disassociation",
+ "authentication",
+ "deauthentication",
+ "reserved#13",
+ "reserved#14",
+ "reserved#15"
+};
+
+int ieee80211_hdr(struct ieee80211_frame *);
+void ieee80211_print_element(u_int8_t *, u_int);
+void ieee80211_print_essid(u_int8_t *, u_int);
+int ieee80211_elements(struct ieee80211_frame *, u_int);
+int ieee80211_frame(struct ieee80211_frame *, u_int);
+int ieee80211_print(struct ieee80211_frame *, u_int);
+u_int ieee80211_any2ieee(u_int, u_int);
+
+#define TCARR(a) TCHECK2(*a, sizeof(a))
+
+int
+ieee80211_hdr(struct ieee80211_frame *wh)
+{
+ struct ieee80211_frame_addr4 *w4;
+
+ switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
+ case IEEE80211_FC1_DIR_NODS:
+ TCARR(wh->i_addr2);
+ printf("%s", etheraddr_string(wh->i_addr2));
+ TCARR(wh->i_addr1);
+ printf(" > %s", etheraddr_string(wh->i_addr1));
+ TCARR(wh->i_addr3);
+ printf(", bssid %s", etheraddr_string(wh->i_addr3));
+ break;
+ case IEEE80211_FC1_DIR_TODS:
+ TCARR(wh->i_addr2);
+ printf("%s", etheraddr_string(wh->i_addr2));
+ TCARR(wh->i_addr3);
+ printf(" > %s", etheraddr_string(wh->i_addr3));
+ TCARR(wh->i_addr1);
+ printf(", bssid %s, > DS", etheraddr_string(wh->i_addr1));
+ break;
+ case IEEE80211_FC1_DIR_FROMDS:
+ TCARR(wh->i_addr3);
+ printf("%s", etheraddr_string(wh->i_addr3));
+ TCARR(wh->i_addr1);
+ printf(" > %s", etheraddr_string(wh->i_addr1));
+ TCARR(wh->i_addr2);
+ printf(", bssid %s, DS >", etheraddr_string(wh->i_addr2));
+ break;
+ case IEEE80211_FC1_DIR_DSTODS:
+ w4 = (struct ieee80211_frame_addr4 *) wh;
+ TCARR(w4->i_addr4);
+ printf("%s", etheraddr_string(w4->i_addr4));
+ TCARR(w4->i_addr3);
+ printf(" > %s", etheraddr_string(w4->i_addr3));
+ TCARR(w4->i_addr2);
+ printf(", bssid %s", etheraddr_string(w4->i_addr2));
+ TCARR(w4->i_addr1);
+ printf(" > %s, DS > DS", etheraddr_string(w4->i_addr1));
+ break;
+ }
+ if (vflag) {
+ TCARR(wh->i_seq);
+ printf(" (seq %u): ", letoh16(*(u_int16_t *)&wh->i_seq[0]));
+ } else
+ printf(": ");
+
+ return (0);
+
+ trunc:
+ /* Truncated elements in frame */
+ return (1);
+}
+
+/* Caller checks len */
+void
+ieee80211_print_element(u_int8_t *data, u_int len)
+{
+ int i;
+ u_int8_t *p;
+
+ printf(" 0x");
+ for (i = 0, p = data; i < len; i++, p++) {
+ printf("%02x", *p);
+ }
+}
+
+/* Caller checks len */
+void
+ieee80211_print_essid(u_int8_t *essid, u_int len)
+{
+ int i;
+ u_int8_t *p;
+
+ if (len > IEEE80211_NWID_LEN)
+ len = IEEE80211_NWID_LEN;
+
+ /* determine printable or not */
+ for (i = 0, p = essid; i < len; i++, p++) {
+ if (*p < ' ' || *p > 0x7e)
+ break;
+ }
+ if (i == len) {
+ printf(" (");
+ for (i = 0, p = essid; i < len; i++, p++)
+ putchar(*p);
+ putchar(')');
+ } else {
+ ieee80211_print_element(essid, len);
+ }
+}
+
+int
+ieee80211_elements(struct ieee80211_frame *wh, u_int flen)
+{
+ u_int8_t *buf, *frm;
+ u_int8_t *tstamp, *bintval, *capinfo;
+ int i;
+
+ buf = (u_int8_t *)wh;
+ frm = (u_int8_t *)&wh[1];
+
+ tstamp = frm;
+ TCHECK2(*tstamp, 8);
+ frm += 8;
+
+ if (vflag > 1)
+ printf(", timestamp %llu", letoh64(*(u_int64_t *)tstamp));
+
+ bintval = frm;
+ TCHECK2(*bintval, 2);
+ frm += 2;
+
+ if (vflag > 1)
+ printf(", interval %u", letoh16(*(u_int16_t *)bintval));
+
+ capinfo = frm;
+ TCHECK2(*capinfo, 2);
+ frm += 2;
+
+ if (vflag)
+ printb(", caps", letoh16(*(u_int16_t *)capinfo),
+ IEEE80211_CAPINFO_BITS);
+
+ while (TTEST2(*frm, 2)) {
+ u_int len = frm[1];
+ u_int8_t *data = frm + 2;
+
+ if (!TTEST2(*data, len))
+ break;
+
+#define ELEM_CHECK(l) if (len != l) break
+
+ switch (*frm) {
+ case IEEE80211_ELEMID_SSID:
+ printf(", ssid");
+ ieee80211_print_essid(data, len);
+ break;
+ case IEEE80211_ELEMID_RATES:
+ printf(", rates");
+ if (!vflag)
+ break;
+ for (i = len; i > 0; i--, data++)
+ printf(" %uM",
+ (data[0] & IEEE80211_RATE_VAL) / 2);
+ break;
+ case IEEE80211_ELEMID_FHPARMS:
+ ELEM_CHECK(5);
+ printf(", fh (dwell %u, chan %u, index %u)",
+ (data[1] << 8) | data[0],
+ (data[2] - 1) * 80 + data[3], /* FH_CHAN */
+ data[4]);
+ break;
+ case IEEE80211_ELEMID_DSPARMS:
+ ELEM_CHECK(1);
+ printf(", ds");
+ if (vflag)
+ printf(" (chan %u)", data[0]);
+ break;
+ case IEEE80211_ELEMID_CFPARMS:
+ printf(", cf");
+ if (vflag)
+ ieee80211_print_element(data, len);
+ break;
+ case IEEE80211_ELEMID_TIM:
+ printf(", tim");
+ if (vflag)
+ ieee80211_print_element(data, len);
+ break;
+ case IEEE80211_ELEMID_IBSSPARMS:
+ printf(", ibss");
+ if (vflag)
+ ieee80211_print_element(data, len);
+ break;
+ case IEEE80211_ELEMID_COUNTRY:
+ printf(", country");
+ for (i = len; i > 0; i--, data++)
+ printf(" %u", data[0]);
+ break;
+ case IEEE80211_ELEMID_CHALLENGE:
+ printf(", challenge");
+ if (vflag)
+ ieee80211_print_element(data, len);
+ break;
+ case IEEE80211_ELEMID_ERP:
+ printf(", erp");
+ if (vflag)
+ ieee80211_print_element(data, len);
+ break;
+ case IEEE80211_ELEMID_RSN:
+ printf(", rsn");
+ if (vflag)
+ ieee80211_print_element(data, len);
+ break;
+ case IEEE80211_ELEMID_XRATES:
+ printf(", xrates");
+ if (!vflag)
+ break;
+ for (i = len; i > 0; i--, data++)
+ printf(" %uM",
+ (data[0] & IEEE80211_RATE_VAL) / 2);
+ break;
+ case IEEE80211_ELEMID_TPC:
+ printf(", tpc");
+ if (vflag)
+ ieee80211_print_element(data, len);
+ break;
+ case IEEE80211_ELEMID_CCKM:
+ printf(", cckm");
+ if (vflag)
+ ieee80211_print_element(data, len);
+ break;
+ case IEEE80211_ELEMID_VENDOR:
+ printf(", vendor");
+ if (vflag)
+ ieee80211_print_element(data, len);
+ break;
+ default:
+ printf(", %u:%u", (u_int) *frm, len);
+ if (vflag)
+ ieee80211_print_element(data, len);
+ break;
+ }
+ frm += len + 2;
+
+ if (frm >= snapend)
+ break;
+ }
+
+#undef ELEM_CHECK
+
+ return (0);
+
+ trunc:
+ /* Truncated elements in frame */
+ return (1);
+}
+
+int
+ieee80211_frame(struct ieee80211_frame *wh, u_int len)
+{
+ u_int8_t subtype, type, *frm;
+
+ TCARR(wh->i_fc);
+
+ type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+ subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
+
+ frm = (u_int8_t *)&wh[1];
+
+ switch (type) {
+ case IEEE80211_FC0_TYPE_DATA:
+ printf(": data");
+ break;
+ case IEEE80211_FC0_TYPE_MGT:
+ printf(": %s", ieee80211_mgt_subtype_name[
+ subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]);
+ switch (subtype) {
+ case IEEE80211_FC0_SUBTYPE_BEACON:
+ case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
+ if (ieee80211_elements(wh, len) != 0)
+ goto trunc;
+ break;
+ case IEEE80211_FC0_SUBTYPE_AUTH:
+ TCHECK2(*frm, 2); /* Auth Algorithm */
+ switch (IEEE80211_AUTH_ALGORITHM(frm)) {
+ case IEEE80211_AUTH_ALG_OPEN:
+ TCHECK2(*frm, 4); /* Auth Transaction */
+ switch (IEEE80211_AUTH_TRANSACTION(frm)) {
+ case IEEE80211_AUTH_OPEN_REQUEST:
+ printf(" request");
+ break;
+ case IEEE80211_AUTH_OPEN_RESPONSE:
+ printf(" response");
+ break;
+ }
+ break;
+ case IEEE80211_AUTH_ALG_SHARED:
+ TCHECK2(*frm, 4); /* Auth Transaction */
+ switch (IEEE80211_AUTH_TRANSACTION(frm)) {
+ case IEEE80211_AUTH_SHARED_REQUEST:
+ printf(" request");
+ break;
+ case IEEE80211_AUTH_SHARED_CHALLENGE:
+ printf(" challenge");
+ break;
+ case IEEE80211_AUTH_SHARED_RESPONSE:
+ printf(" response");
+ break;
+ case IEEE80211_AUTH_SHARED_PASS:
+ printf(" pass");
+ break;
+ }
+ break;
+ case IEEE80211_AUTH_ALG_LEAP:
+ printf(" (leap)");
+ break;
+ }
+ break;
+ }
+ break;
+ default:
+ printf(": type#%d", type);
+ break;
+ }
+
+ if (wh->i_fc[1] & IEEE80211_FC1_WEP)
+ printf(", WEP");
+
+ return (0);
+
+ trunc:
+ /* Truncated 802.11 frame */
+ return (1);
+}
+
+u_int
+ieee80211_any2ieee(u_int freq, u_int flags)
+{
+ if (flags & IEEE80211_CHAN_2GHZ) {
+ if (freq == 2484)
+ return 14;
+ if (freq < 2484)
+ return (freq - 2407) / 5;
+ else
+ return 15 + ((freq - 2512) / 20);
+ } else if (flags & IEEE80211_CHAN_5GHZ) {
+ return (freq - 5000) / 5;
+ } else {
+ /* Assume channel is already an IEEE number */
+ return (freq);
+ }
+}
+
+int
+ieee80211_print(struct ieee80211_frame *wh, u_int len)
+{
+ if (eflag)
+ if (ieee80211_hdr(wh))
+ return (1);
+
+ printf("802.11");
+
+ return (ieee80211_frame(wh, len));
+}
+
+void
+ieee802_11_if_print(u_char *user, const struct pcap_pkthdr *h,
+ const u_char *p)
+{
+ struct ieee80211_frame *wh = (struct ieee80211_frame*)p;
+
+ ts_print(&h->ts);
+
+ packetp = p;
+ snapend = p + h->caplen;
+
+ if (ieee80211_print(wh, (u_int)h->caplen) != 0)
+ printf("[|802.11]");
+
+ if (xflag)
+ default_print(p, (u_int)h->caplen);
+
+ putchar('\n');
+
+ return;
+}
+
+void
+ieee802_11_radio_if_print(u_char *user, const struct pcap_pkthdr *h,
+ const u_char *p)
+{
+ struct ieee80211_radiotap_header *rh =
+ (struct ieee80211_radiotap_header*)p;
+ struct ieee80211_frame *wh;
+ u_int8_t *t;
+ u_int32_t present;
+ u_int len, rh_len;
+
+ ts_print(&h->ts);
+
+ packetp = p;
+ snapend = p + h->caplen;
+
+ TCHECK(*rh);
+
+ len = h->caplen;
+ rh_len = letoh16(rh->it_len);
+ if (rh->it_version != 0) {
+ printf("[?radiotap + 802.11 v:%u]\n", rh->it_version);
+ goto out;
+ }
+
+ wh = (struct ieee80211_frame *)(p + rh_len);
+ if (len <= rh_len || ieee80211_print(wh, len - rh_len))
+ printf("[|802.11]");
+
+ t = (u_int8_t*)p + sizeof(struct ieee80211_radiotap_header);
+
+ if ((present = letoh32(rh->it_present)) == 0)
+ goto out;
+
+ printf(", <radiotap v%u", rh->it_version);
+
+#define RADIOTAP(_x) \
+ (present & (1 << IEEE80211_RADIOTAP_##_x))
+
+ if (RADIOTAP(TSFT)) {
+ TCHECK2(*t, 8);
+ if (vflag > 1)
+ printf(", tsf %llu", letoh64(*(u_int64_t*)t));
+ t += 8;
+ }
+
+ if (RADIOTAP(FLAGS)) {
+ TCHECK2(*t, 1);
+ u_int8_t flags = *(u_int8_t*)t;
+ if (flags & IEEE80211_RADIOTAP_F_CFP)
+ printf(", CFP");
+ if (flags & IEEE80211_RADIOTAP_F_SHORTPRE)
+ printf(", SHORTPRE");
+ if (flags & IEEE80211_RADIOTAP_F_WEP)
+ printf(", WEP");
+ if (flags & IEEE80211_RADIOTAP_F_FRAG)
+ printf(", FRAG");
+ t += 1;
+ }
+
+ if (RADIOTAP(RATE)) {
+ TCHECK2(*t, 1);
+ if (vflag)
+ printf(", %uMbit/s", (*(u_int8_t*)t) / 2);
+ t += 1;
+ }
+
+ if (RADIOTAP(CHANNEL)) {
+ u_int16_t freq, flags;
+ TCHECK2(*t, 2);
+
+ freq = letoh16(*(u_int16_t*)t);
+ t += 2;
+ TCHECK2(*t, 2);
+ flags = letoh16(*(u_int16_t*)t);
+ t += 2;
+
+ printf(", chan %u", ieee80211_any2ieee(freq, flags));
+
+ if (flags & IEEE80211_CHAN_DYN &&
+ flags & IEEE80211_CHAN_2GHZ)
+ printf(", 11g");
+ else if (flags & IEEE80211_CHAN_CCK &&
+ flags & IEEE80211_CHAN_2GHZ)
+ printf(", 11b");
+ else if (flags & IEEE80211_CHAN_OFDM &&
+ flags & IEEE80211_CHAN_2GHZ)
+ printf(", 11G");
+ else if (flags & IEEE80211_CHAN_OFDM &&
+ flags & IEEE80211_CHAN_5GHZ)
+ printf(", 11a");
+
+ if (flags & IEEE80211_CHAN_TURBO)
+ printf(", TURBO");
+ if (flags & IEEE80211_CHAN_XR)
+ printf(", XR");
+ }
+
+ if (RADIOTAP(FHSS)) {
+ TCHECK2(*t, 2);
+ printf(", fhss %u/%u", *(u_int8_t*)t, *(u_int8_t*)t + 1);
+ t += 2;
+ }
+
+ if (RADIOTAP(DBM_ANTSIGNAL)) {
+ TCHECK(*t);
+ printf(", sig %ddBm", *(int8_t*)t);
+ t += 1;
+ }
+
+ if (RADIOTAP(DBM_ANTNOISE)) {
+ TCHECK(*t);
+ printf(", noise %ddBm", *(int8_t*)t);
+ t += 1;
+ }
+
+ if (RADIOTAP(LOCK_QUALITY)) {
+ TCHECK2(*t, 2);
+ if (vflag)
+ printf(", quality %u", letoh16(*(u_int16_t*)t));
+ t += 2;
+ }
+
+ if (RADIOTAP(TX_ATTENUATION)) {
+ TCHECK2(*t, 2);
+ if (vflag)
+ printf(", txatt %u",
+ letoh16(*(u_int16_t*)t));
+ t += 2;
+ }
+
+ if (RADIOTAP(DB_TX_ATTENUATION)) {
+ TCHECK2(*t, 2);
+ if (vflag)
+ printf(", txatt %udB",
+ letoh16(*(u_int16_t*)t));
+ t += 2;
+ }
+
+ if (RADIOTAP(DBM_TX_POWER)) {
+ TCHECK(*t);
+ printf(", txpower %ddBm", *(int8_t*)t);
+ t += 1;
+ }
+
+ if (RADIOTAP(ANTENNA)) {
+ TCHECK(*t);
+ if (vflag)
+ printf(", antenna %u", *(u_int8_t*)t);
+ t += 1;
+ }
+
+ if (RADIOTAP(DB_ANTSIGNAL)) {
+ TCHECK(*t);
+ printf(", signal %udB", *(u_int8_t*)t);
+ t += 1;
+ }
+
+ if (RADIOTAP(DB_ANTNOISE)) {
+ TCHECK(*t);
+ printf(", noise %udB", *(u_int8_t*)t);
+ t += 1;
+ }
+
+ if (RADIOTAP(FCS)) {
+ TCHECK2(*t, 4);
+ if (vflag)
+ printf(", fcs %08x", letoh32(*(u_int32_t*)t));
+ t += 4;
+ }
+
+#undef RADIOTAP
+
+ putchar('>');
+
+ goto out;
+
+ trunc:
+ /* Truncated frame */
+ printf("[|radiotap + 802.11]");
+
+ out:
+ if (xflag)
+ default_print(p, h->caplen);
+
+ putchar('\n');
+
+ return;
+}
diff --git a/usr.sbin/tcpdump/tcpdump.c b/usr.sbin/tcpdump/tcpdump.c
index c7a3b8c413a..473d7acb582 100644
--- a/usr.sbin/tcpdump/tcpdump.c
+++ b/usr.sbin/tcpdump/tcpdump.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcpdump.c,v 1.41 2005/03/06 21:05:49 jmc Exp $ */
+/* $OpenBSD: tcpdump.c,v 1.42 2005/03/07 16:13:38 reyk Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -26,7 +26,7 @@ static const char copyright[] =
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] =
- "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/tcpdump.c,v 1.41 2005/03/06 21:05:49 jmc Exp $ (LBL)";
+ "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/tcpdump.c,v 1.42 2005/03/07 16:13:38 reyk Exp $ (LBL)";
#endif
/*
@@ -98,7 +98,7 @@ RETSIGTYPE cleanup(int);
extern __dead void usage(void);
/* Length of saved portion of packet. */
-int snaplen = DEFAULT_SNAPLEN;
+int snaplen = 0;
struct printer {
pcap_handler f;
@@ -126,6 +126,8 @@ static struct printer printers[] = {
{ pflog_old_if_print, DLT_OLD_PFLOG },
{ pfsync_if_print, DLT_PFSYNC },
{ ppp_ether_if_print, DLT_PPP_ETHER },
+ { ieee802_11_if_print, DLT_IEEE802_11 },
+ { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO },
{ NULL, 0 },
};
@@ -185,7 +187,9 @@ const struct pcap_linktype {
{ DLT_OLD_PFLOG, "OLD_PFLOG" },
{ DLT_PFSYNC, "PFSYNC" },
{ DLT_PPP_ETHER, "PPP_ETHER" },
+ { DLT_IEEE802_11, "IEEE802_11" },
{ DLT_PFLOG, "PFLOG" },
+ { DLT_IEEE802_11_RADIO, "IEEE802_11_RADIO" },
{ 0, NULL }
};
@@ -440,6 +444,17 @@ main(int argc, char **argv)
/* NOTREACHED */
}
+ if (snaplen == 0) {
+ switch (dlt) {
+ case DLT_IEEE802_11_RADIO:
+ snaplen = RADIOTAP_SNAPLEN;
+ break;
+ default:
+ snaplen = DEFAULT_SNAPLEN;
+ break;
+ }
+ }
+
if (aflag && nflag)
error("-a and -n options are incompatible");
diff --git a/usr.sbin/tcpdump/util.c b/usr.sbin/tcpdump/util.c
index b22a3f3e6b1..759272f6e20 100644
--- a/usr.sbin/tcpdump/util.c
+++ b/usr.sbin/tcpdump/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.18 2004/07/28 09:37:26 markus Exp $ */
+/* $OpenBSD: util.c,v 1.19 2005/03/07 16:13:38 reyk Exp $ */
/*
* Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
@@ -23,7 +23,7 @@
#ifndef lint
static const char rcsid[] =
- "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/util.c,v 1.18 2004/07/28 09:37:26 markus Exp $ (LBL)";
+ "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/util.c,v 1.19 2005/03/07 16:13:38 reyk Exp $ (LBL)";
#endif
#include <sys/types.h>
@@ -327,3 +327,35 @@ safeputchar(int c)
else
printf("\\%03o", c & 0xff);
}
+
+/*
+ * Print a value a la the %b format of the kernel's printf
+ * (from sbin/ifconfig/ifconfig.c)
+ */
+void
+printb(char *s, unsigned short v, char *bits)
+{
+ int i, any = 0;
+ char c;
+
+ if (bits && *bits == 8)
+ printf("%s=%o", s, v);
+ else
+ printf("%s=%x", s, v);
+ bits++;
+ if (bits) {
+ putchar('<');
+ while ((i = *bits++)) {
+ if (v & (1 << (i-1))) {
+ if (any)
+ putchar(',');
+ any = 1;
+ for (; (c = *bits) > 32; bits++)
+ putchar(c);
+ } else
+ for (; *bits > 32; bits++)
+ ;
+ }
+ putchar('>');
+ }
+}