Since some people emailed me asking to see the stuff I had done, I'll post it
here.
If anybody would need a wireless packet dump to play with, I can send it
off-list.
diff -burN tcpdump-3.6.2/Makefile.in tcpdump-3.6.2.cdl/Makefile.in
--- tcpdump-3.6.2/Makefile.in Thu Dec 21 05:43:20 2000
+++ tcpdump-3.6.2.cdl/Makefile.in Tue Apr 10 16:28:59 2001
@@ -68,7 +68,7 @@
CSRC = tcpdump.c \
print-arp.c print-atalk.c print-atm.c print-bootp.c \
print-decnet.c print-domain.c print-dvmrp.c print-egp.c \
- print-ether.c print-fddi.c print-gre.c print-icmp.c print-igmp.c \
+ print-802_11.c print-ether.c print-fddi.c print-gre.c print-icmp.c
+print-igmp.c \
print-igrp.c print-ip.c print-ipx.c print-isoclns.c print-krb.c \
print-llc.c print-nfs.c print-ntp.c print-null.c print-ospf.c \
print-pim.c print-ppp.c print-raw.c print-rip.c print-sl.c \
diff -burN tcpdump-3.6.2/ieee802_11.h tcpdump-3.6.2.cdl/ieee802_11.h
--- tcpdump-3.6.2/ieee802_11.h Wed Dec 31 19:00:00 1969
+++ tcpdump-3.6.2.cdl/ieee802_11.h Wed Jun 6 11:35:47 2001
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2001
+ * Fortress Technologies
+ * Charlie Lenahan ( [EMAIL PROTECTED] )
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+
+#define T_MGMT 0x0 /* management */
+#define T_CTRL 0x1 /* control */
+#define T_DATA 0x2 /* data */
+#define T_RESV 0x3 /* reserved */
+
+#define ST_ASSOC_REQUEST 0x0
+#define ST_ASSOC_RESPONSE 0x1
+#define ST_REASSOC_REQUEST 0x2
+#define ST_REASSOC_RESPONSE 0x3
+#define ST_PROBE_REQUEST 0x4
+#define ST_PROBE_RESPONSE 0x5
+/* RESERVED 0x6 */
+/* RESERVED 0x7 */
+#define ST_BEACON 0x8
+#define ST_ATIM 0x9
+#define ST_DISASSOC 0xA
+#define ST_AUTH 0xB
+#define ST_DEAUTH 0xC
+/* RESERVED 0xD */
+/* RESERVED 0xE */
+/* RESERVED 0xF */
+
+
+#define CTRL_PS_POLL 0xA
+#define CTRL_RTS 0xB
+#define CTRL_CTS 0xC
+#define CTRL_ACK 0xD
+#define CTRL_CF_END 0xE
+#define CTRL_END_ACK 0xF
+
+struct frame_control_t {
+ u_int16_t version:2;
+ u_int16_t type:2;
+ u_int16_t subtype:4;
+ u_int16_t to_ds:1;
+ u_int16_t from_ds:1;
+ u_int16_t more_flag:1;
+ u_int16_t retry:1;
+ u_int16_t power_mgmt:1;
+ u_int16_t more_data:1;
+ u_int16_t wep:1;
+ u_int16_t order:1;
+};
+
+struct mgmt_header_t {
+ struct frame_control_t fc;
+ u_int16_t duration;
+ u_int8_t da[6];
+ u_int8_t sa[6];
+ u_int8_t bssid[6];
+ u_int8_t seq_ctrl;
+};
+
+struct capability_t {
+ u_int16_t ess:1;
+ u_int16_t ibss:1;
+ u_int16_t cfp:1;
+ u_int16_t cfp_req:1;
+ u_int16_t privacy:1;
+ u_int16_t reserved:11;
+} ;
+
+struct ssid_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_char ssid[33]; /* 32 + 1 for null */
+} ;
+
+struct rates_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int8_t rate[8];
+};
+
+struct challenge_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int8_t text[254]; /* 1-253 + 1 for null */
+};
+struct fh_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int16_t dwell_time;
+ u_int8_t hop_set;
+ u_int8_t hop_pattern;
+ u_int8_t hop_index;
+};
+
+struct ds_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int8_t channel;
+};
+
+struct cf_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int8_t count;
+ u_int8_t period;
+ u_int16_t max_duration;
+ u_int16_t dur_remaing;
+};
+
+struct tim_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int8_t count;
+ u_int8_t period;
+ u_int8_t bitmap_control;
+ u_int8_t bitmap[251];
+};
+
+#define E_SSID 0
+#define E_RATES 1
+#define E_FH 2
+#define E_DS 3
+#define E_CF 4
+#define E_TIM 5
+#define E_IBSS 6
+/* reserved 7 */
+/* reserved 8 */
+/* reserved 9 */
+/* reserved 10 */
+/* reserved 11 */
+/* reserved 12 */
+/* reserved 13 */
+/* reserved 14 */
+/* reserved 15 */
+/* reserved 16 */
+
+#define E_CHALLENGE 16
+/* reserved 17 */
+/* reserved 18 */
+/* reserved 19 */
+/* reserved 16 */
+/* reserved 16 */
+
+
+struct mgmt_body_t {
+ u_int8_t timestamp[8];
+ u_int16_t beacon_interval;
+ u_int16_t listen_interval;
+ u_int16_t status_code;
+ u_int16_t aid;
+ u_char ap[6];
+ u_int16_t reason_code;
+ u_int16_t auth_alg;
+ u_int16_t auth_trans_seq_num;
+ struct challenge_t challenge;
+ struct capability_t capability_info;
+ struct ssid_t ssid;
+ struct rates_t rates;
+ struct ds_t ds;
+ struct cf_t cf;
+ struct fh_t fh;
+ struct tim_t tim;
+};
+
+struct ctrl_rts_t {
+ struct frame_control_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int8_t ta[6];
+ u_int32_t fcs;
+};
+
+struct ctrl_cts_t {
+ struct frame_control_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int32_t fcs;
+};
+
+struct ctrl_ack_t {
+ struct frame_control_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int32_t fcs;
+};
+
+struct ctrl_ps_poll_t {
+ struct frame_control_t fc;
+ u_int16_t aid;
+ u_int8_t bssid[6];
+ u_int8_t ta[6];
+ u_int32_t fcs;
+};
+
+struct ctrl_end_t {
+ struct frame_control_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int8_t bssid[6];
+ u_int32_t fcs;
+};
+
+struct ctrl_end_ack_t {
+ struct frame_control_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int8_t bssid[6];
+ u_int32_t fcs;
+};
+
+struct iv_t {
+ u_int32_t iv:24;
+ u_int32_t pad:6;
+ u_int32_t keyid:2;
+};
diff -burN tcpdump-3.6.2/interface.h tcpdump-3.6.2.cdl/interface.h
--- tcpdump-3.6.2/interface.h Tue Jan 2 17:47:06 2001
+++ tcpdump-3.6.2.cdl/interface.h Tue Apr 10 16:28:59 2001
@@ -196,6 +196,8 @@
extern void default_print_unaligned(const u_char *, u_int);
extern void dvmrp_print(const u_char *, u_int);
extern void egp_print(const u_char *, u_int, const u_char *);
+extern void ieee802_11_if_print(u_char *, const struct pcap_pkthdr *,
+ const u_char *);
extern void ether_if_print(u_char *, const struct pcap_pkthdr *,
const u_char *);
extern void token_if_print(u_char *, const struct pcap_pkthdr *,
diff -burN tcpdump-3.6.2/print-802_11.c tcpdump-3.6.2.cdl/print-802_11.c
--- tcpdump-3.6.2/print-802_11.c Wed Dec 31 19:00:00 1969
+++ tcpdump-3.6.2.cdl/print-802_11.c Wed Jun 6 11:38:33 2001
@@ -0,0 +1,733 @@
+/*
+ * Copyright (c) 2001
+ * Fortress Technologies, Inc. All rights reserved.
+ * Charlie Lenahan ([EMAIL PROTECTED])
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] =
+ "@(#) $Header: $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+struct mbuf;
+struct rtentry;
+
+#include <netinet/in.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#include "extract.h"
+
+#include "ieee802_11.h"
+
+const u_char *packetp;
+const u_char *snapend;
+
+#define RATEStoBUF(p,buf) { int z=0; for (z=0 ; z < p.rates.length ; z++) \
+ sprintf(buf,"%s %2.1f",buf, (.5 *
+(p.rates.rate[z] & 0x7f))); }
+
+static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
+static const char *type_text[]={"MGMT","CTRL","DATA"};
+static const char *subtype_text[]={"Assoc Request","Assoc Response","ReAssoc
+Request","ReAssoc Response",
+ "Probe Request","Probe Response","RESERVED","RESERVED",
+ "Beacon","ATIM","DISASSOC","Auth",
+ "DeAuth","RESERVED","RESERVED"};
+
+
+static const char *status_text[]={"Succesful", /* 0 */
+ "Unspecified failure", /* 1 */
+ "Reserved", /* 2 */
+ "Reserved", /* 3 */
+ "Reserved", /* 4 */
+ "Reserved", /* 5 */
+ "Reserved", /* 6 */
+ "Reserved", /* 7 */
+ "Reserved", /* 8 */
+ "Reserved", /* 9 */
+ "Cannot Support all requested capabilities in the
+Capability Information field", /* 10 */
+ "Reassociation denied due to inability to confirm that
+association exists", /* 11 */
+ "Association denied due to reason outside the scope of
+the standard", /* 12 */
+ "Responding station does not support the specified
+authentication algorithm ", /* 13 */
+ "Received an Authentication frame with authentication
+transaction " \
+ "sequence number out of expected sequence",
+ /* 14 */
+ "Authentication rejected because of challenge
+failure", /* 15 */
+ "Authentication rejected due to timeout waiting for
+next frame in sequence", /* 16 */
+ "Association denied because AP is unable to handle
+additional associated stations", /* 17 */
+ "Association denied due to requesting station not
+supporting all of the " \
+ "data rates in BSSBasicRateSet parameter",
+ /* 18 */
+ NULL };
+
+static const char *reason_text[]= { "Reserved", /* 0 */
+ "Unspecified reason", /* 1 */
+ "Previous authentication no longer valid", /* 2 */
+ "Deauthenticated because sending station is leaving
+(or has left) IBSS or ESS", /* 3 */
+ "Disassociated due to inactivity", /* 4 */
+ "Disassociated because AP is unable to handle all
+currently associated stations", /* 5 */
+ "Class 2 frame receivedfrom nonauthenticated station",
+/* 6 */
+ "Class 3 frame received from nonassociated station",
+/* 7 */
+ "Disassociated because sending station is leaving (or
+has left) BSS", /* 8 */
+ "Station requesting (re)association is not
+authenticated with responding station", /* 9 */
+ NULL };
+
+static void wep_print(const u_char *p,u_int length)
+{
+ struct iv_t iv;
+
+ memcpy(&iv,p,4);
+
+ printf("Data IV:%3x Pad %x KeyID %x",iv.iv, iv.pad, iv.keyid );
+
+ return;
+
+}
+
+
+static void parse_elements(struct mgmt_body_t *pbody,const u_char *p,int offset)
+{
+ while ( *(p+offset) != 0xff )
+ {
+ switch (*(p+offset))
+ {
+ case E_SSID:
+ memcpy(&(pbody->ssid),p+offset,2); offset += 2;
+ if (pbody->ssid.length > 0)
+ {
+
+memcpy(&(pbody->ssid.ssid),p+offset,pbody->ssid.length); offset += pbody->ssid.length;
+ pbody->ssid.ssid[pbody->ssid.length]='\0';
+ }
+ break;
+ case E_CHALLENGE:
+ memcpy(&(pbody->challenge),p+offset,2); offset += 2;
+ if (pbody->challenge.length > 0)
+ {
+
+memcpy(&(pbody->challenge.text),p+offset,pbody->challenge.length); offset +=
+pbody->challenge.length;
+
+pbody->challenge.text[pbody->challenge.length]='\0';
+ }
+ break;
+
+ case E_RATES:
+ memcpy(&(pbody->rates),p+offset,2); offset += 2;
+ if (pbody->rates.length > 0)
+
+memcpy(&(pbody->rates.rate),p+offset,pbody->rates.length); offset +=
+pbody->rates.length;
+ break;
+ case E_DS:
+ memcpy(&(pbody->ds),p+offset,3); offset +=3;
+ break;
+ case E_CF:
+ memcpy(&(pbody->cf),p+offset,8); offset +=8;
+ break;
+ case E_TIM:
+ memcpy(&(pbody->tim),p+offset,2); offset +=2;
+ memcpy(&(pbody->tim.count),p+offset,3); offset +=3;
+
+ if ((pbody->tim.length -3) > 0)
+ {
+
+memcpy((pbody->tim.bitmap),p+(pbody->tim.length -3),(pbody->tim.length -3));
+ offset += pbody->tim.length -3;
+ }
+
+ break;
+ default:
+// printf("(1) unhandled element_id (%d) ", *(p+offset)
+);
+ offset+= *(p+offset+1) + 2;
+ break;
+ }
+ }
+}
+
+/*********************************************************************************
+ * Print Handle functions for the managemnt frame types
+ *********************************************************************************/
+
+static void handle_beacon(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ struct mgmt_body_t pbody;
+ int offset=0;
+ int z=0;
+ char buf[128];
+
+ memset(buf,0,128);
+ memset(&pbody,0,sizeof(struct mgmt_body_t));
+
+ memcpy(&pbody.timestamp,p,8); offset += 8;
+ memcpy(&pbody.beacon_interval,p+offset,2); offset += 2;
+ memcpy(&pbody.capability_info,p+offset,2); offset += 2;
+
+ parse_elements(&pbody,p,offset);
+
+ RATEStoBUF(pbody,buf);
+
+ printf("%s (%s) [%s Mbit] %s CH: %x %s",subtype_text[ pmh->fc.subtype ],
+ pbody.ssid.ssid,buf,pbody.capability_info.ess ? "ESS" : "IBSS"
+,pbody.ds.channel,
+ pbody.capability_info.privacy ? ", PRIVACY" : "" );
+
+ return ;
+}
+
+static void handle_assoc_request(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ struct mgmt_body_t pbody;
+ int offset=0;
+ int z=0;
+ char buf[128];
+
+ memset(buf,0,128);
+ memset(&pbody,0,sizeof(struct mgmt_body_t));
+
+ memcpy(&pbody.capability_info,p,2); offset += 2;
+ memcpy(&pbody.listen_interval,p+offset,2); offset += 2;
+
+ parse_elements(&pbody,p,offset);
+
+ RATEStoBUF(pbody,buf);
+
+ printf("%s (%s) [%s Mbit] ",subtype_text[ pmh->fc.subtype ],
+pbody.ssid.ssid,buf);
+ return;
+}
+
+static void handle_assoc_response(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ struct mgmt_body_t pbody;
+ int offset=0;
+
+ memset(&pbody,0,sizeof(struct mgmt_body_t));
+
+ memcpy(&pbody.capability_info,p,2); offset += 2;
+ memcpy(&pbody.status_code,p+offset,2); offset += 2;
+ memcpy(&pbody.aid,p+offset,2); offset += 2;
+
+ parse_elements(&pbody,p,offset);
+
+ printf("%s AID(%x) :%s: %s ",subtype_text[ pmh->fc.subtype ],
+ ((u_int16_t)( pbody.aid << 2 )) >> 2 ,
+ pbody.capability_info.privacy ? " PRIVACY " : "" ,
+ (pbody.status_code < 19 ? status_text[pbody.status_code] : "n/a") );
+
+ return;
+}
+
+
+static void handle_reassoc_request(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ struct mgmt_body_t pbody;
+ int offset=0;
+
+ memset(&pbody,0,sizeof(struct mgmt_body_t));
+
+ memcpy(&pbody.capability_info,p,2); offset += 2;
+ memcpy(&pbody.listen_interval,p+offset,2); offset += 2;
+ memcpy(&pbody.ap,p+offset,6); offset += 6;
+
+ parse_elements(&pbody,p,offset);
+
+ printf("%s (%s) AP : %s",subtype_text[ pmh->fc.subtype ], pbody.ssid.ssid,
+etheraddr_string( pbody.ap ));
+
+ return;
+}
+
+static void handle_reassoc_response(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ /* Same as a Association Reponse */
+ return handle_assoc_response(pmh,p);
+}
+
+static void handle_probe_request(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ struct mgmt_body_t pbody;
+ int offset=0;
+ char buf[128];
+ memset(buf,0,128);
+
+ memset(&pbody,0,sizeof(struct mgmt_body_t));
+
+ parse_elements(&pbody,p,offset);
+
+ RATEStoBUF(pbody,buf);
+
+ printf("%s (%s) [%s Mbit] ",subtype_text[ pmh->fc.subtype ],
+pbody.ssid.ssid,buf);
+
+ return;
+}
+
+static void handle_probe_response(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ struct mgmt_body_t pbody;
+ int offset=0;
+ int z=0;
+
+ char buf[128];
+ memset(buf,0,128);
+
+ memset(&pbody,0,sizeof(struct mgmt_body_t));
+
+ memcpy(&pbody.timestamp,p,8); offset += 8;
+ memcpy(&pbody.beacon_interval,p+offset,2); offset += 2;
+ memcpy(&pbody.capability_info,p+offset,2); offset += 2;
+
+ parse_elements(&pbody,p,offset);
+
+ printf("%s (%s) CH: %x %s",subtype_text[ pmh->fc.subtype ],
+pbody.ssid.ssid,pbody.ds.channel,
+ pbody.capability_info.privacy ? ",PRIVACY " : "" );
+
+ return;
+}
+
+static void handle_atim(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ /* the frame body for ATIM is null. */
+ printf("ATIM");
+ return;
+}
+
+static void handle_disassoc(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ struct mgmt_body_t pbody;
+ int offset=0;
+
+ memset(&pbody,0,sizeof(struct mgmt_body_t));
+
+ memcpy(&pbody.reason_code,p,2); offset += 2;
+
+ printf("Disassociation : %s ", pbody.reason_code < 10 ?
+reason_text[pbody.reason_code] : "Reserved" );
+
+ return;
+}
+
+static void handle_auth(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ struct mgmt_body_t pbody;
+ int offset=0;
+
+ memset(&pbody,0,sizeof(struct mgmt_body_t));
+
+
+ memcpy(&pbody.auth_alg,p,2); offset += 2;
+ memcpy(&pbody.auth_trans_seq_num,p+offset,2); offset += 2;
+ memcpy(&pbody.status_code,p+offset,2); offset += 2;
+
+ parse_elements(&pbody,p,offset);
+
+
+ if (( pbody.auth_alg == 1) &&
+ ( ( pbody.auth_trans_seq_num == 2) || (pbody.auth_trans_seq_num == 3)
+))
+ {
+ printf("Authentication (%s)-%x [Challenge Text] %s",pbody.auth_alg < 4
+? auth_alg_text[pbody.auth_alg] : "Reserved" ,
+ pbody.auth_trans_seq_num,
+ ((pbody.auth_trans_seq_num % 2) ?
+ (pbody.status_code < 19 ?
+status_text[pbody.status_code] : "n/a") : "" )
+ );
+ }
+ else
+ {
+ printf("Authentication (%s)-%x: %s",pbody.auth_alg < 4 ?
+auth_alg_text[pbody.auth_alg] : "Reserved" ,
+ pbody.auth_trans_seq_num,
+ ( (pbody.auth_trans_seq_num % 2) ?
+ (pbody.status_code < 19 ?
+status_text[pbody.status_code] : "n/a") : "")
+ );
+ }
+
+
+ return;
+}
+
+static void handle_deauth(const struct mgmt_header_t *pmh,const u_char *p)
+{
+ struct mgmt_body_t pbody;
+ int offset=0;
+
+ memset(&pbody,0,sizeof(struct mgmt_body_t));
+
+ memcpy(&pbody.reason_code,p,2); offset += 2;
+
+ if (eflag)
+ {
+ printf("DeAuthentication :%s",pbody.reason_code < 10 ?
+reason_text[pbody.reason_code] : "Reserved" );
+ }
+ else
+ {
+ printf("DeAuthentication (%s):%s",etheraddr_string(pmh->sa),
+ pbody.reason_code < 10 ? reason_text[pbody.reason_code] :
+"Reserved" );
+ }
+
+ return;
+}
+
+
+/*********************************************************************************
+ * Print Body funcs
+ *********************************************************************************/
+
+
+static void mgmt_body_print(const struct mgmt_header_t *pmh ,const u_char *p, u_int
+length)
+{
+ switch ((int) pmh->fc.subtype)
+ {
+ case ST_ASSOC_REQUEST:
+ handle_assoc_request(pmh,p);
+ break;
+ case ST_ASSOC_RESPONSE:
+ handle_assoc_response(pmh,p);
+ break;
+ case ST_REASSOC_REQUEST:
+ handle_reassoc_request(pmh,p);
+ break;
+ case ST_REASSOC_RESPONSE:
+ handle_reassoc_response(pmh,p);
+ break;
+ case ST_PROBE_REQUEST:
+ handle_probe_request(pmh,p);
+ break;
+ case ST_PROBE_RESPONSE:
+ handle_probe_response(pmh,p);
+ break;
+ case ST_BEACON:
+ handle_beacon(pmh,p);
+ break;
+ case ST_ATIM:
+ handle_atim(pmh,p);
+ break;
+ case ST_DISASSOC:
+ handle_disassoc(pmh,p);
+ break;
+ case ST_AUTH:
+ if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0))
+ {
+ printf("Authentication (Shared-Key)-3 ");
+ wep_print(p,length);
+ }
+ else
+ handle_auth(pmh,p);
+ break;
+ case ST_DEAUTH:
+ handle_deauth(pmh,p);
+ break;
+ default:
+ printf("Unhandled Managment subtype(%x)",pmh->fc.subtype);
+ }
+}
+
+
+/*********************************************************************************
+ * Handles printing all the control frame types
+ *********************************************************************************/
+
+static void ctrl_body_print(const u_char *header,const u_char *p, u_int length)
+{
+ const struct frame_control_t *fcp=(const struct frame_control_t *) header;
+
+ switch ((int) (fcp)->subtype)
+ {
+ case CTRL_PS_POLL:
+ printf("Power Save-Poll AID(%x)",((u_int16_t)( ((struct
+ctrl_ps_poll_t *)p)->aid << 2 )) >> 2 );
+ break;
+ case CTRL_RTS:
+ if (eflag)
+ printf("Request-To-Send");
+ else
+ printf("Request-To-Send TA:%s ", etheraddr_string(
+((struct ctrl_rts_t *)p)->ta));
+ break;
+ case CTRL_CTS:
+ if (eflag)
+ printf("Clear-To-Send");
+ else
+ printf("Clear-To-Send RA:%s ", etheraddr_string(
+((struct ctrl_cts_t *)p)->ra));
+ break;
+ case CTRL_ACK:
+ if (eflag)
+ printf("Acknowledgment");
+ else
+ printf("Acknowledgment RA:%s ", etheraddr_string(
+((struct ctrl_ack_t *)p)->ra));
+ break;
+ case CTRL_CF_END:
+ if (eflag)
+ printf("CF-End");
+ else
+ printf("CF-End RA:%s ", etheraddr_string( ((struct
+ctrl_end_t *)p)->ra));
+ break;
+ case CTRL_END_ACK:
+ if (eflag)
+ printf("CF-End+CF-Ack");
+ else
+ printf("CF-End+CF-Ack RA:%s ", etheraddr_string(
+((struct ctrl_end_ack_t *)p)->ra));
+ break;
+ default:
+ printf("(B) Unknown Ctrl Subtype");
+ }
+}
+
+
+
+/*********************************************************************************
+ * Print Header funcs
+ *********************************************************************************/
+
+/*********************************************************************************
+ * Data Frame - Address field contents
+ *
+ * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
+ * 0 | 0 | DA | SA | BSSID | n/a
+ * 0 | 1 | DA | BSSID | SA | n/a
+ * 1 | 0 | BSSID | SA | DA | n/a
+ * 1 | 1 | RA | TA | DA | SA
+ *********************************************************************************/
+
+#define ADDR1 p+4
+#define ADDR2 p+10
+#define ADDR3 p+16
+#define ADDR4 p+24
+
+static void data_header_print(const u_char *p, u_int length)
+{
+ const struct frame_control_t *fcp=(const struct frame_control_t *) p;
+
+// printf("%x-%x ",fcp->to_ds,fcp->from_ds);
+
+ if (fcp->to_ds == 0)
+ {
+ if (fcp->from_ds == 0)
+ printf("DA:%s SA:%s BSSID:%s ", etheraddr_string( ADDR1),
+ etheraddr_string( ADDR2), etheraddr_string( ADDR3));
+ else
+ printf("DA:%s BSSID:%s SA:%s ", etheraddr_string( ADDR1),
+ etheraddr_string( ADDR2), etheraddr_string( ADDR3));
+ }
+ else
+ {
+ if (fcp->from_ds == 0)
+ printf("BSSID:%s SA:%s DA:%s ", etheraddr_string( ADDR1),
+ etheraddr_string( ADDR2), etheraddr_string( ADDR3));
+ else
+ printf("RA:%s TA:%s DA:%s SA:%s ", etheraddr_string( ADDR1),
+ etheraddr_string( ADDR2), etheraddr_string( ADDR3),
+ etheraddr_string( ADDR4));
+ }
+
+}
+
+
+static void mgmt_header_print(const u_char *p, u_int length)
+{
+ const struct mgmt_header_t *hp=(const struct mgmt_header_t *) p;
+
+ printf("BSSID:%s DA:%s SA:%s ", etheraddr_string( (hp)->bssid),
+ etheraddr_string( (hp)->da),
+ etheraddr_string( (hp)->sa));
+}
+
+static void ctrl_header_print(const u_char *p, u_int length)
+{
+ const struct frame_control_t *fcp=(const struct frame_control_t *) p;
+
+ switch ((int) (fcp)->subtype)
+ {
+ case CTRL_PS_POLL:
+ printf("BSSID:%s TA:%s ", etheraddr_string( ((struct
+ctrl_ps_poll_t *)p)->bssid),
+ etheraddr_string( ((struct
+ctrl_ps_poll_t *)p)->ta));
+ break;
+ case CTRL_RTS:
+ printf("RA:%s TA:%s ", etheraddr_string( ((struct ctrl_rts_t
+*)p)->ra),
+ etheraddr_string( ((struct ctrl_rts_t
+*)p)->ta));
+ break;
+ case CTRL_CTS:
+ printf("RA:%s ", etheraddr_string( ((struct ctrl_cts_t
+*)p)->ra));
+ break;
+ case CTRL_ACK:
+ printf("RA:%s ", etheraddr_string( ((struct ctrl_ack_t
+*)p)->ra));
+ break;
+ case CTRL_CF_END:
+ printf("RA:%s BSSID:%s ", etheraddr_string( ((struct
+ctrl_end_t *)p)->ra),
+ etheraddr_string( ((struct ctrl_end_t
+*)p)->bssid));
+ break;
+ case CTRL_END_ACK:
+ printf("RA:%s BSSID:%s ", etheraddr_string( ((struct
+ctrl_end_ack_t *)p)->ra),
+ etheraddr_string( ((struct
+ctrl_end_ack_t *)p)->bssid));
+ break;
+ default:
+ printf("(H) Unknown Ctrl Subtype");
+ }
+}
+
+static int GetHeaderLength(const struct frame_control_t *fc)
+{
+ int iLength=0;
+
+ switch ((int) fc->type )
+ {
+ case T_MGMT:
+ iLength=sizeof(struct mgmt_header_t);
+ break;
+ case T_CTRL:
+ switch ((int) fc->subtype)
+ {
+ case CTRL_PS_POLL:
+ iLength=sizeof(struct ctrl_ps_poll_t);
+ break;
+ case CTRL_RTS:
+ iLength=sizeof(struct ctrl_rts_t);
+ break;
+ case CTRL_CTS:
+ iLength=sizeof(struct ctrl_cts_t);
+ break;
+ case CTRL_ACK:
+ iLength=sizeof(struct ctrl_ack_t);
+ break;
+ case CTRL_CF_END:
+ iLength=sizeof(struct ctrl_end_t);
+ break;
+ case CTRL_END_ACK:
+ iLength=sizeof(struct ctrl_end_ack_t);
+ break;
+ default:
+ iLength=0;
+ break;
+ }
+ break;
+ case T_DATA:
+ if (fc->to_ds && fc->from_ds)
+ iLength=30;
+ else
+ iLength=24;
+ break;
+ default:
+ printf("unkown IEEE802.11 frame type (%d)",(fc)->type);
+ break;
+ }
+
+ return iLength;
+}
+
+//static int linecount=0;
+
+/*
+ * This is the top level routine of the printer. 'p' is the points
+ * to the ether header of the packet, 'h->tv' is the timestamp,
+ * 'h->length' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+void
+ieee802_11_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+// u_short ether_type;
+ u_short extracted_ethertype;
+ u_int16_t foo;
+ u_int HEADER_LENGTH=0;
+
+ struct frame_control_t fc;
+
+ //memcpy(&fc,p,2);
+ foo=EXTRACT_16BITS(p);
+
+// printf("(%4.4x)(%4.4x)",foo,ntohs(foo));
+
+ foo=ntohs(foo);
+
+// printf("(%4.4x)",foo);
+
+ memcpy(&fc,&foo,2);
+
+// printf("(%x|%x|%x %x|%x|%x|%x|%x|%x|%x|%x)",fc.version,fc.type,
+// fc.subtype,fc.to_ds,
+// fc.from_ds, fc.more_flag,
+// fc.retry, fc.power_mgmt,
+// fc.more_data, fc.wep,
+// fc.order);
+
+// linecount++;
+// printf("[%4.0d]",linecount);
+
+ ts_print(&h->ts);
+
+ if (eflag)
+ {
+ switch ((int) fc.type )
+ {
+ case T_MGMT:
+ mgmt_header_print(p,length);
+ break;
+ case T_CTRL:
+ ctrl_header_print(p,length);
+ break;
+ case T_DATA:
+ data_header_print(p,length);
+ break;
+ default:
+ printf("(header) unkown IEEE802.11 frame type
+(%d)",fc.type);
+ break;
+ }
+ }
+
+
+ /*
+ * Some printers want to get back at the ethernet addresses,
+ * and/or check that they're not walking off the end of the packet.
+ * Rather than pass them all the way down, we set these globals.
+ */
+ packetp = p;
+ snapend = p + caplen;
+
+ HEADER_LENGTH=GetHeaderLength( &fc );
+
+ length -= HEADER_LENGTH;
+ caplen -= HEADER_LENGTH;
+ p += HEADER_LENGTH;
+
+
+ switch ( (int) fc.type )
+ {
+ case T_MGMT:
+ mgmt_body_print((const struct mgmt_header_t
+*)packetp,p,length);
+ break;
+ case T_CTRL:
+ ctrl_body_print(packetp,p,length);
+ break;
+ case T_DATA:
+ /* There may be a problem w/ AP not having this bit set */
+ if (fc.wep)
+ wep_print(p,length);
+ else
+ llc_print(p, length, caplen, packetp+10, packetp+4,
+&extracted_ethertype) ;
+ break;
+ default:
+ printf("(body) unhandled IEEE802.11 frame type (%d)",fc.type);
+ break;
+ }
+
+
+
+ if (xflag)
+ default_print(p, caplen);
+ out:
+ putchar('\n');
+}
+
diff -burN tcpdump-3.6.2/tcpdump.c tcpdump-3.6.2.cdl/tcpdump.c
--- tcpdump-3.6.2/tcpdump.c Thu Dec 21 05:43:24 2000
+++ tcpdump-3.6.2.cdl/tcpdump.c Tue Apr 10 16:28:59 2001
@@ -130,6 +130,7 @@
#ifdef DLT_LINUX_SLL
{ sll_if_print, DLT_LINUX_SLL },
#endif
+ { ieee802_11_if_print, DLT_IEEE802_11},
{ NULL, 0 },
};