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 },
 };
 

Reply via email to