"Fossies" - the Fresh Open Source Software Archive

Member "tcpflow-1.6.1/src/wifipcap/wifipcap.h" (19 Feb 2021, 29554 Bytes) of package /linux/misc/tcpflow-1.6.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "wifipcap.h" see the Fossies "Dox" file reference documentation.

    1 /**
    2  * Include this header in applications using wifipcap.
    3  * Released under GPLv3.
    4  * Some code (c) Jeffrey Pang <jeffpang@cs.cmu.edu>, 2003
    5  *           (C) Simson Garfinkel <simsong@acm.org> 2012-
    6  */
    7 
    8 #ifndef _WIFIPCAP_H_
    9 #define _WIFIPCAP_H_
   10 
   11 #include <list>
   12 #include <stdint.h>
   13 #include <inttypes.h>
   14 
   15 #include <pcap/pcap.h>
   16 #include <netinet/in.h>
   17 
   18 #include "arp.h"
   19 #include "ip.h"
   20 #include "ip6.h"
   21 #include "tcp.h"
   22 #include "udp.h"
   23 #include "TimeVal.h"
   24 
   25 /* Lengths of 802.11 header components. */
   26 #define IEEE802_11_FC_LEN       2
   27 #define IEEE802_11_DUR_LEN      2
   28 #define IEEE802_11_DA_LEN       6
   29 #define IEEE802_11_SA_LEN       6
   30 #define IEEE802_11_BSSID_LEN        6
   31 #define IEEE802_11_RA_LEN       6
   32 #define IEEE802_11_TA_LEN       6
   33 #define IEEE802_11_SEQ_LEN      2
   34 #define IEEE802_11_IV_LEN       3
   35 #define IEEE802_11_KID_LEN      1
   36 
   37 /* Frame check sequence length. */
   38 #define IEEE802_11_FCS_LEN      4
   39 
   40 /* Lengths of beacon components. */
   41 #define IEEE802_11_TSTAMP_LEN       8
   42 #define IEEE802_11_BCNINT_LEN       2
   43 #define IEEE802_11_CAPINFO_LEN      2
   44 #define IEEE802_11_LISTENINT_LEN    2
   45 
   46 #define IEEE802_11_AID_LEN      2
   47 #define IEEE802_11_STATUS_LEN       2
   48 #define IEEE802_11_REASON_LEN       2
   49 
   50 /* Length of previous AP in reassocation frame */
   51 #define IEEE802_11_AP_LEN       6
   52 
   53 #define T_MGMT 0x0      /* management */
   54 #define T_CTRL 0x1      /* control */
   55 #define T_DATA 0x2      /* data */
   56 #define T_RESV 0x3      /* reserved */
   57 
   58 #define ST_ASSOC_REQUEST    0x0
   59 #define ST_ASSOC_RESPONSE   0x1
   60 #define ST_REASSOC_REQUEST      0x2
   61 #define ST_REASSOC_RESPONSE     0x3
   62 #define ST_PROBE_REQUEST    0x4
   63 #define ST_PROBE_RESPONSE       0x5
   64 /* RESERVED             0x6  */
   65 /* RESERVED             0x7  */
   66 #define ST_BEACON           0x8
   67 #define ST_ATIM         0x9
   68 #define ST_DISASSOC     0xA
   69 #define ST_AUTH         0xB
   70 #define ST_DEAUTH       0xC
   71 /* RESERVED             0xD  */
   72 /* RESERVED             0xE  */
   73 /* RESERVED             0xF  */
   74 
   75 #define CTRL_PS_POLL            0xA
   76 #define CTRL_RTS                0xB
   77 #define CTRL_CTS                0xC
   78 #define CTRL_ACK                0xD
   79 #define CTRL_CF_END             0xE
   80 #define CTRL_END_ACK            0xF
   81 
   82 #define DATA_DATA       0x0
   83 #define DATA_DATA_CF_ACK    0x1
   84 #define DATA_DATA_CF_POLL   0x2
   85 #define DATA_DATA_CF_ACK_POLL   0x3
   86 #define DATA_NODATA     0x4
   87 #define DATA_NODATA_CF_ACK  0x5
   88 #define DATA_NODATA_CF_POLL 0x6
   89 #define DATA_NODATA_CF_ACK_POLL 0x7
   90 
   91 /*
   92  * Bits in the frame control field.
   93  */
   94 #define FC_VERSION(fc)      ((fc) & 0x3)
   95 #define FC_TYPE(fc)     (((fc) >> 2) & 0x3)
   96 #define FC_SUBTYPE(fc)      (((fc) >> 4) & 0xF)
   97 #define FC_TO_DS(fc)        ((fc) & 0x0100)
   98 #define FC_FROM_DS(fc)      ((fc) & 0x0200)
   99 #define FC_MORE_FLAG(fc)    ((fc) & 0x0400)
  100 #define FC_RETRY(fc)        ((fc) & 0x0800)
  101 #define FC_POWER_MGMT(fc)   ((fc) & 0x1000)
  102 #define FC_MORE_DATA(fc)    ((fc) & 0x2000)
  103 #define FC_WEP(fc)      ((fc) & 0x4000)
  104 #define FC_ORDER(fc)        ((fc) & 0x8000)
  105 
  106 #define MGMT_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+          \
  107              IEEE802_11_DA_LEN+IEEE802_11_SA_LEN+           \
  108              IEEE802_11_BSSID_LEN+IEEE802_11_SEQ_LEN)
  109 
  110 #define CAPABILITY_ESS(cap) ((cap) & 0x0001)
  111 #define CAPABILITY_IBSS(cap)    ((cap) & 0x0002)
  112 #define CAPABILITY_CFP(cap) ((cap) & 0x0004)
  113 #define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008)
  114 #define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010)
  115 
  116 
  117 
  118 struct MAC {          
  119     enum { PRINT_FMT_COLON, PRINT_FMT_PLAIN };
  120     uint64_t val;
  121     MAC():val() {}
  122     MAC(uint64_t val_):val(val_){}
  123     MAC(const MAC& o):val(o.val){}
  124     MAC(const uint8_t *ether):val(
  125         ((uint64_t)(ether[0]) << 40) |
  126         ((uint64_t)(ether[1]) << 32) |
  127         ((uint64_t)(ether[2]) << 24) |
  128         ((uint64_t)(ether[3]) << 16) |
  129         ((uint64_t)(ether[4]) <<  8) |
  130         ((uint64_t)(ether[5]) <<  0)){}
  131     MAC(const char *str):val(){
  132         int ether[6];
  133         int ret = sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",
  134                          &ether[0], &ether[1], &ether[2], &ether[3], &ether[4], &ether[5]);
  135         if (ret != 6) {
  136             ret = sscanf(str, "%02X:%02X:%02X:%02X:%02X:%02X",
  137                          &ether[0], &ether[1], &ether[2], &ether[3], &ether[4], &ether[5]);
  138         }
  139         if (ret != 6) {
  140             std::cerr << "bad mac address: " << str << std::endl;
  141             val = 0;
  142             return;
  143         }
  144         val = 
  145             ((uint64_t)(ether[0]) << 40) |
  146             ((uint64_t)(ether[1]) << 32) |
  147             ((uint64_t)(ether[2]) << 24) |
  148             ((uint64_t)(ether[3]) << 16) |
  149             ((uint64_t)(ether[4]) <<  8) |
  150             ((uint64_t)(ether[5]) <<  0);
  151     }
  152     
  153     bool operator==(const MAC& o) const { return val == o.val; }
  154     bool operator!=(const MAC& o) const { return val != o.val; }
  155     bool operator<(const MAC& o)  const { return val <  o.val; }
  156     
  157     static MAC ether2MAC(const uint8_t * ether) {
  158         return MAC(ether);
  159     }
  160 
  161     static MAC broadcast;
  162     static MAC null;
  163     static int print_fmt;
  164 };
  165 
  166 typedef enum {
  167     NOT_PRESENT,
  168     PRESENT,
  169     TRUNCATED
  170 } elem_status_t;
  171 
  172 struct ssid_t {
  173     ssid_t():element_id(),length(),ssid(){};
  174     u_int8_t    element_id;
  175     u_int8_t    length;
  176     char    ssid[33];  /* 32 + 1 for null */
  177 };
  178 
  179 struct rates_t {
  180     rates_t():element_id(),length(),rate(){};
  181     u_int8_t    element_id;
  182     u_int8_t    length;
  183     u_int8_t    rate[16];
  184 };
  185 
  186 struct challenge_t {
  187     challenge_t():element_id(),length(),text(){};
  188     u_int8_t    element_id;
  189     u_int8_t    length;
  190     u_int8_t    text[254]; /* 1-253 + 1 for null */
  191 };
  192 
  193 struct fh_t {
  194     fh_t():element_id(),length(),dwell_time(),hop_set(),hop_pattern(),hop_index(){};
  195     u_int8_t    element_id;
  196     u_int8_t    length;
  197     u_int16_t   dwell_time;
  198     u_int8_t    hop_set;
  199     u_int8_t    hop_pattern;
  200     u_int8_t    hop_index;
  201 };
  202 
  203 struct ds_t {
  204     u_int8_t    element_id;
  205     u_int8_t    length;
  206     u_int8_t    channel;
  207 };
  208 
  209 struct cf_t {
  210     u_int8_t    element_id;
  211     u_int8_t    length;
  212     u_int8_t    count;
  213     u_int8_t    period;
  214     u_int16_t   max_duration;
  215     u_int16_t   dur_remaing;
  216 };
  217 
  218 struct tim_t {
  219     u_int8_t    element_id;
  220     u_int8_t    length;
  221     u_int8_t    count;
  222     u_int8_t    period;
  223     u_int8_t    bitmap_control;
  224     u_int8_t    bitmap[251];
  225 };
  226 
  227 #define E_SSID      0
  228 #define E_RATES     1
  229 #define E_FH        2
  230 #define E_DS        3
  231 #define E_CF        4
  232 #define E_TIM       5
  233 #define E_IBSS      6
  234 /* reserved         7 */
  235 /* reserved         8 */
  236 /* reserved         9 */
  237 /* reserved         10 */
  238 /* reserved         11 */
  239 /* reserved         12 */
  240 /* reserved         13 */
  241 /* reserved         14 */
  242 /* reserved         15 */
  243 /* reserved         16 */
  244 
  245 #define E_CHALLENGE     16
  246 /* reserved         17 */
  247 /* reserved         18 */
  248 /* reserved         19 */
  249 /* reserved         16 */
  250 /* reserved         16 */
  251 
  252 // XXX Jeff: no FCS fields are filled in right now
  253 
  254 #define CTRL_RTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+  \
  255              IEEE802_11_RA_LEN+IEEE802_11_TA_LEN)
  256 
  257 struct ctrl_cts_t {
  258     ctrl_cts_t():fc(),duration(),ra(),fcs(){};
  259     u_int16_t fc;
  260     u_int16_t duration;
  261     MAC ra;
  262     u_int8_t fcs[4];
  263 };
  264 
  265 #define CTRL_CTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
  266 
  267 struct ctrl_ack_t {
  268     ctrl_ack_t():fc(),duration(),ra(),fcs(){};
  269     u_int16_t fc;
  270     u_int16_t duration;
  271     MAC ra;
  272     u_int8_t fcs[4];
  273 };
  274 
  275 #define CTRL_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
  276 
  277 struct ctrl_ps_poll_t {
  278     ctrl_ps_poll_t():fc(),aid(),bssid(),ta(),fcs(){};
  279     u_int16_t fc;
  280     u_int16_t aid;
  281     MAC bssid;
  282     MAC ta;
  283     u_int8_t fcs[4];
  284 };
  285 
  286 #define CTRL_PS_POLL_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+  \
  287                  IEEE802_11_BSSID_LEN+IEEE802_11_TA_LEN)
  288 
  289 struct ctrl_end_t {
  290     ctrl_end_t():fc(),duration(),ra(),bssid(),fcs(){}
  291     u_int16_t fc;
  292     u_int16_t duration;
  293     MAC ra;
  294     MAC bssid;
  295     u_int8_t fcs[4];
  296 };
  297 
  298 #define CTRL_END_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+          \
  299              IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
  300 
  301 struct ctrl_end_ack_t {
  302     ctrl_end_ack_t():fc(),duration(),ra(),bssid(),fcs(){};
  303     u_int16_t fc;
  304     u_int16_t duration;
  305     MAC ra;
  306     MAC bssid;
  307     u_int8_t fcs[4];
  308 };
  309 
  310 #define CTRL_END_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+  \
  311                  IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
  312 #define IV_IV(iv)   ((iv) & 0xFFFFFF)
  313 #define IV_PAD(iv)  (((iv) >> 24) & 0x3F)
  314 #define IV_KEYID(iv)    (((iv) >> 30) & 0x03)
  315 
  316 struct mac_hdr_t {                 // unified 80211 header
  317     mac_hdr_t():fc(),duration(),seq_ctl(),seq(),frag(),da(),sa(),ta(),ra(),bssid(),qos(){}
  318     uint16_t fc;                    // frame control
  319     uint16_t duration;
  320     uint16_t seq_ctl;
  321     uint16_t seq;                   // sequence number
  322     uint8_t frag;                   // fragment number?
  323     MAC da;                         // destination address // address1
  324     MAC sa;                         // source address      // address2
  325     MAC ta;                         // transmitter         // address3 
  326     MAC ra;                         // receiver            // address4
  327     MAC bssid;                      // BSSID
  328     bool qos;                       // has quality of service
  329 };
  330         
  331 #if 0
  332 struct data_hdr_ibss_t {          // 80211 Independent Basic Service Set - e.g. ad hoc mode
  333     data_hdr_ibss_t():fc(),duration(),seq(),frag(),fcs(){};
  334     u_int16_t fc;
  335     u_int16_t duration;
  336     u_int16_t seq;
  337     u_int8_t  frag;
  338     u_int8_t  fcs[4];
  339 };
  340 
  341 struct data_hdr_t {
  342     data_hdr_t():fc(),duration(),seq(),frag(),sa(),da(),bssid(),fcs(){}
  343     u_int16_t fc;                   // 
  344     u_int16_t duration;             // ?
  345     u_int16_t seq;                  // sequence #?
  346     u_int8_t  frag;                 // fragment #?
  347     MAC       sa;                   // sender address
  348     MAC       da;                   // destination address
  349     MAC       bssid;                // base station ID
  350     u_int8_t  fcs[4];               // frame check sequence
  351 };
  352 
  353 struct data_hdr_wds_t {             // 80211 Wireless Distribution System
  354     data_hdr_wds_t():fc(),duration(),seq(),frag(),ra(),ta(),sa(),da(),fcs(){}
  355     u_int16_t fc;
  356     u_int16_t duration;
  357     u_int16_t seq;
  358     u_int8_t frag;
  359     MAC ra;
  360     MAC ta;
  361     MAC sa;
  362     MAC da;
  363     u_int8_t fcs[4];
  364 };
  365 #endif
  366 
  367 #define DATA_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+          \
  368              IEEE802_11_SA_LEN+IEEE802_11_DA_LEN+           \
  369              IEEE802_11_BSSID_LEN+IEEE802_11_SEQ_LEN)
  370 
  371 #define DATA_WDS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+          \
  372              IEEE802_11_RA_LEN+IEEE802_11_TA_LEN+           \
  373              IEEE802_11_SA_LEN+IEEE802_11_DA_LEN+IEEE802_11_SEQ_LEN)
  374 
  375 /* Jeff: added for fully-decoded wep info */
  376 struct wep_hdr_t {
  377     wep_hdr_t():iv(),pad(),keyid(){};
  378     u_int32_t iv;
  379     u_int32_t pad;
  380     u_int32_t keyid;
  381 };
  382 
  383 /* prism header */
  384 #ifdef _WIN32
  385 #pragma pack(push, 1)
  386 #endif
  387 struct prism2_pkthdr {
  388     uint32_t host_time;
  389     uint32_t mac_time;
  390     uint32_t channel;
  391     uint32_t rssi;
  392     uint32_t sq;
  393     int32_t  signal;
  394     int32_t  noise;
  395     uint32_t rate;
  396     uint32_t istx;
  397     uint32_t frmlen;
  398 } __attribute__((__packed__));
  399 
  400 struct radiotap_hdr {
  401     bool has_channel;
  402     int channel;
  403     bool has_fhss;
  404     int fhss_fhset;
  405     int fhss_fhpat;
  406     bool has_rate;
  407     int rate;
  408     bool has_signal_dbm;
  409     int signal_dbm;
  410     bool has_noise_dbm;
  411     int noise_dbm;
  412     bool has_signal_db;
  413     int signal_db;
  414     bool has_noise_db;
  415     int noise_db;
  416     bool has_quality;
  417     int quality;
  418     bool has_txattenuation;
  419     int txattenuation;
  420     bool has_txattenuation_db;
  421     int txattenuation_db;
  422     bool has_txpower_dbm;
  423     int txpower_dbm;
  424     bool has_flags;
  425     bool flags_cfp;
  426     bool flags_short_preamble;
  427     bool flags_wep;
  428     bool flags_fragmented;
  429     bool flags_badfcs;
  430     bool has_antenna;
  431     int antenna;
  432     
  433     bool has_tsft;
  434     u_int64_t tsft;
  435 
  436     bool has_rxflags;
  437     int rxflags;
  438 
  439     bool has_txflags;
  440     int txflags;
  441 
  442     bool has_rts_retries;
  443     int rts_retries;
  444 
  445     bool has_data_retries;
  446     int data_retries;
  447 } __attribute__((__packed__));
  448 
  449 struct ether_hdr_t {
  450     ether_hdr_t():sa(),da(),type(){};
  451     MAC sa, da;
  452     uint16_t type;
  453 };
  454 
  455 struct mgmt_header_t {
  456     mgmt_header_t():fc(),duration(),da(),sa(),bssid(),seq(),frag(){};
  457     u_int16_t fc;
  458     u_int16_t duration;
  459     MAC da;
  460     MAC sa;
  461     MAC bssid;
  462     u_int16_t seq;
  463     u_int8_t  frag;
  464 };
  465 
  466 struct mgmt_body_t {
  467 
  468     mgmt_body_t():timestamp(),beacon_interval(),listen_interval(),status_code(),aid(),ap(),reason_code(),
  469                   auth_alg(),auth_trans_seq_num(),challenge_status(),challenge(),capability_info(),
  470                   ssid_status(),ssid(),rates_status(),rates(),ds_status(),ds(),cf_status(),cf(),
  471                   fh_status(),fh(),tim_status(),tim(){};
  472 
  473     u_int8_t    timestamp[IEEE802_11_TSTAMP_LEN];
  474     u_int16_t   beacon_interval;
  475     u_int16_t   listen_interval;
  476     u_int16_t   status_code;
  477     u_int16_t   aid;
  478     u_char      ap[IEEE802_11_AP_LEN];
  479     u_int16_t   reason_code;
  480     u_int16_t   auth_alg;
  481     u_int16_t   auth_trans_seq_num;
  482     elem_status_t   challenge_status;
  483     struct challenge_t  challenge;
  484     u_int16_t   capability_info;
  485     elem_status_t   ssid_status;
  486     struct ssid_t   ssid;
  487     elem_status_t   rates_status;
  488     struct rates_t  rates;
  489     elem_status_t   ds_status;
  490     struct ds_t ds;
  491     elem_status_t   cf_status;
  492     struct cf_t cf;
  493     elem_status_t   fh_status;
  494     struct fh_t fh;
  495     elem_status_t   tim_status;
  496     struct tim_t    tim;
  497 };
  498 
  499 struct ctrl_rts_t {
  500     ctrl_rts_t():fc(),duration(),ra(),ta(),fcs(){}
  501     u_int16_t fc;
  502     u_int16_t duration;
  503     MAC ra;
  504     MAC ta;
  505     u_int8_t fcs[4];
  506 };
  507 
  508 #ifdef _WIN32
  509 #pragma pack(pop)
  510 #endif
  511 
  512 
  513 
  514 /**
  515  * Applications should implement a subclass of this interface and pass
  516  * it to Wifipcap::Run(). Each time pcap reads a packet, Wifipcap will
  517  * call:
  518  *
  519  * (1) PacketBegin()
  520  *
  521  * (2) Each Handle*() callback in order from layer 1 to layer 3 (or as
  522  *     far as it is able to demultiplex the packet). The time values 
  523  *     are the same in all these calls. The 'len' argument passed to
  524  *     functions refers to the amount of captured data available
  525  *     (e.g., in the 'rest' variable), not necessarily the original
  526  *     length of the packet (to get that, look inside appropriate
  527  *     packet headers, or during PacketBegin()).
  528  *
  529  * (3) PacketEnd()
  530  *
  531  * If the header for a layer was truncated, the appropriate function
  532  * will be called with the header == NULL and the rest == the start of
  533  * the packet.  For truncated 802.11 headers, 80211Unknown will be
  534  * called with fc == -1; for truncated ICMP headers, type == code ==
  535  * -1.
  536  *
  537  * All structures passed to the application will have fields in host
  538  * byte-order. For details about each header structure, see the
  539  * obvious header (e.g., ieee802_11.h for 802.11 stuff, ip.h for IPv4,
  540  * tcp.h for TCP, etc.). Note that there may be structures with
  541  * similar names that are only used internally; don't confuse them.
  542  *
  543  * For help parsing other protocols, the tcpdump source code will be
  544  * helpful. See the print-X.c file for help parsing protocol X.
  545  * The entry function is usually called X_print(...).
  546  */
  547 
  548 struct WifiPacket;
  549 struct WifipcapCallbacks;
  550 class Wifipcap;
  551 extern std::ostream& operator<<(std::ostream& out, const MAC& mac);
  552 extern std::ostream& operator<<(std::ostream& out, const struct in_addr& ip);
  553 
  554 ///////////////////////////////////////////////////////////////////////////////
  555 
  556 
  557 /* 
  558  * This class decodes a specific packet
  559  */
  560 struct WifiPacket {
  561     /* Some instance variables */
  562 
  563     /** 48-bit MACs in 64-bit ints */
  564     static int debug;                   // prints callback before they are called
  565 
  566     WifiPacket(WifipcapCallbacks *cbs_,const int header_type_,const struct pcap_pkthdr *header_,const u_char *packet_):
  567         cbs(cbs_),header_type(header_type_),header(header_),packet(packet_),fcs_ok(false){}
  568     void parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset, size_t len);
  569     int handle_beacon(const struct mgmt_header_t *pmh, const u_char *p, size_t len);
  570     int handle_assoc_request(const struct mgmt_header_t *pmh, const u_char *p, size_t len);
  571     int handle_assoc_response(const struct mgmt_header_t *pmh, const u_char *p, size_t len, bool reassoc = false);
  572     int handle_reassoc_request(const struct mgmt_header_t *pmh, const u_char *p, size_t len);
  573     int handle_reassoc_response(const struct mgmt_header_t *pmh, const u_char *p, size_t len);
  574     int handle_probe_request(const struct mgmt_header_t *pmh, const u_char *p, size_t len);
  575     int handle_probe_response(const struct mgmt_header_t *pmh, const u_char *p, size_t len);
  576     int handle_atim(const struct mgmt_header_t *pmh, const u_char *p, size_t len);
  577     int handle_disassoc(const struct mgmt_header_t *pmh, const u_char *p, size_t len);
  578     int handle_auth(const struct mgmt_header_t *pmh, const u_char *p, size_t len);
  579     int handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, size_t len);
  580 
  581     int decode_mgmt_body(u_int16_t fc, struct mgmt_header_t *pmh, const u_char *p, size_t len);
  582     int decode_mgmt_frame(const u_char * ptr, size_t len, u_int16_t fc, u_int8_t hdrlen);
  583     int decode_data_frame(const u_char * ptr, size_t len, u_int16_t fc);
  584     int decode_ctrl_frame(const u_char * ptr, size_t len, u_int16_t fc);
  585 
  586     /* Handle the individual packet types based on DTL callback switch */
  587     void handle_llc(const mac_hdr_t &hdr,const u_char *ptr, size_t len,u_int16_t fc);
  588     void handle_wep(const u_char *ptr, size_t len);
  589     void handle_prism(const u_char *ptr, size_t len);
  590     void handle_ether(const u_char *ptr, size_t len);
  591     void handle_ip(const u_char *ptr, size_t len);
  592     void handle_80211(const u_char *ptr, size_t len); 
  593     int print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad, radiotap_hdr *hdr);
  594     void handle_radiotap(const u_char *ptr, size_t caplen);
  595 
  596     /* And finally the data for each packet */
  597     WifipcapCallbacks *cbs;             // the callbacks to use with this packet
  598     const int header_type;                    // DLT
  599     const struct pcap_pkthdr *header;   // the actual pcap headers
  600     const u_char *packet;               // the actual packet data
  601     bool fcs_ok;                        // was it okay?
  602 };
  603 
  604 
  605 struct WifipcapCallbacks {
  606     /****************************************************************
  607      *** Data Structures for each Packet Follow
  608      ****************************************************************/
  609 
  610     WifipcapCallbacks(){};
  611     virtual ~WifipcapCallbacks(){};
  612 
  613     virtual const char *name() const {return "WifipcapCallbacks";} // override with your own name!
  614 
  615     /* Instance variables --- for a specific packet.
  616      * (Previously all of the functions had these parameters as the arguments, which made no sense)
  617      */
  618     /**
  619      * @param t the time the packet was captured
  620      * @param pkt the entire packet captured
  621      * @param len the length of the data captured
  622      * @param origlen the original length of the data (before truncated by pcap)
  623      */
  624     virtual void PacketBegin(const WifiPacket &p, const u_char *pkt, size_t len, int origlen){}
  625     virtual void PacketEnd(const WifiPacket &p ){}
  626 
  627     // If a Prism or RadioTap packet is found, call these, and then call Handle80211()
  628 
  629     virtual void HandlePrism(const WifiPacket &p, struct prism2_pkthdr *hdr, const u_char *rest, size_t len){}
  630     virtual void HandleRadiotap(const WifiPacket &p, struct radiotap_hdr *hdr, const u_char *rest, size_t len){}
  631 
  632     // 802.11 MAC (see ieee802_11.h)
  633     //
  634     // This method is called for every 802.11 frame just before the
  635     // specific functions below are called. This allows you to have
  636     // one entry point to easily do something with all 802.11 packets.
  637     //
  638     // The MAC addresses will be MAC::null unless applicable to the
  639     // particular type of packet. For unknown 802.11 packets, all
  640     // MAC addresses will be MAC::null and if the packet is truncated,
  641     // so that fc was not decoded, it will be 0.
  642     //
  643     // fcs_ok will be true if the frame had a valid fcs (frame
  644     // checksum) trailer and Check80211FCS() returns true.
  645     virtual void Handle80211(const WifiPacket &p, u_int16_t fc, const MAC& sa, const MAC& da, const MAC& ra, const MAC& ta, const u_char *ptr, size_t len){}
  646 
  647     // if this returns true, we'll check the fcs on every frame.
  648     // Note: if frames are truncated, the fcs check will fail, so you need
  649     // a complete packet capture for this to be meaningful
  650     virtual bool Check80211FCS(const WifiPacket &p ) { return false; }
  651 
  652     // Management
  653     virtual void Handle80211MgmtBeacon(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body)   {puts("Handle80211MgmtBeacon");}
  654     virtual void Handle80211MgmtAssocRequest(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
  655     virtual void Handle80211MgmtAssocResponse(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
  656     virtual void Handle80211MgmtReassocRequest(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
  657     virtual void Handle80211MgmtReassocResponse(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
  658     virtual void Handle80211MgmtProbeRequest(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
  659     virtual void Handle80211MgmtProbeResponse(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
  660     virtual void Handle80211MgmtATIM(const WifiPacket &p, const struct mgmt_header_t *hdr){}
  661     virtual void Handle80211MgmtDisassoc(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
  662     virtual void Handle80211MgmtAuth(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
  663     virtual void Handle80211MgmtAuthSharedKey(const WifiPacket &p, const struct mgmt_header_t *hdr, const u_char *rest, size_t len){}
  664     virtual void Handle80211MgmtDeauth(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
  665 
  666     // Control
  667     virtual void Handle80211CtrlPSPoll(const WifiPacket &p, const struct ctrl_ps_poll_t *hdr){}
  668     virtual void Handle80211CtrlRTS(const WifiPacket &p, const struct ctrl_rts_t *hdr){}
  669     virtual void Handle80211CtrlCTS(const WifiPacket &p, const struct ctrl_cts_t *hdr){}
  670     virtual void Handle80211CtrlAck(const WifiPacket &p, const struct ctrl_ack_t *hdr){}
  671     virtual void Handle80211CtrlCFEnd(const WifiPacket &p, const struct ctrl_end_t *hdr){}
  672     virtual void Handle80211CtrlEndAck(const WifiPacket &p, const struct ctrl_end_ack_t *hdr){}
  673     
  674     // Data - Each data packet results in a call to Handle80211Data and one of the others
  675     virtual void Handle80211Data(const WifiPacket &p, u_int16_t fc, const struct mac_hdr_t &hdr,
  676                                  const u_char *rest, size_t len){}
  677     virtual void Handle80211DataIBSS(const WifiPacket &p, const struct mac_hdr_t &hdr, const u_char *rest, size_t len){}
  678     virtual void Handle80211DataFromAP(const WifiPacket &p, const struct mac_hdr_t &hdr, const u_char *rest, size_t len){}
  679     virtual void Handle80211DataToAP(const WifiPacket &p, const struct mac_hdr_t &hdr, const u_char *rest, size_t len){}
  680     virtual void Handle80211DataWDS(const WifiPacket &p, const struct mac_hdr_t &hdr, const u_char *rest, size_t len){}
  681     
  682     // Erroneous Frames/Truncated Frames
  683     // Also called if Check80211FCS() returns true and the checksum is bad
  684     virtual void Handle80211Unknown(const WifiPacket &p, int fc, const u_char *rest, size_t len){}
  685 
  686     // LLC/SNAP (const WifiPacket &p, see llc.h)
  687 
  688     virtual void HandleLLC(const WifiPacket &p, const struct llc_hdr_t *hdr, const u_char *rest, size_t len){}
  689     virtual void HandleLLCUnknown(const WifiPacket &p, const u_char *rest, size_t len){}
  690     virtual void HandleWEP(const WifiPacket &p, const struct wep_hdr_t *hdr, const u_char *rest, size_t len){}
  691 
  692     // for non-802.11 ethernet traces
  693     virtual void HandleEthernet(const WifiPacket &p, const struct ether_hdr_t *hdr, const u_char *rest, size_t len){}
  694 
  695     ///// Layer 2 (see arp.h, ip.h, ip6.h)
  696 
  697     virtual void HandleARP(const WifiPacket &p, const arp_pkthdr *hdr, const u_char *rest, size_t len){}
  698     virtual void HandleIP(const WifiPacket &p, const ip4_hdr_t *hdr, const u_char *options, int optlen, const u_char *rest, size_t len){}
  699     virtual void HandleIP6(const WifiPacket &p, const ip6_hdr_t *hdr, const u_char *rest, size_t len){}
  700     virtual void HandleL2Unknown(const WifiPacket &p, uint16_t ether_type, const u_char *rest, size_t len){}
  701 
  702     ///// Layer 3 (see icmp.h, tcp.h, udp.h)
  703 
  704     // IP headers are included for convenience. one of ip4h, ip6h will
  705     // be non-NULL. Only the first fragment in a fragmented packet
  706     // will be decoded. The other fragments will not be passed to any
  707     // of these functions.
  708 
  709     // Jeff: XXX icmp callback will probably eventually change to
  710     // parse the entire icmp packet
  711     virtual void HandleICMP(const WifiPacket &p, const ip4_hdr_t *ip4h, const ip6_hdr_t *ip6h, int type, int code, const u_char *rest, size_t len){}
  712     virtual void HandleTCP(const WifiPacket &p, const ip4_hdr_t *ip4h, const ip6_hdr_t *ip6h, const tcp_hdr_t *hdr, const u_char *options, int optlen, const u_char *rest, size_t len){}
  713     virtual void HandleUDP(const WifiPacket &p, const ip4_hdr_t *ip4h, const ip6_hdr_t *ip6h, const udp_hdr_t *hdr, const u_char *rest, size_t len){}
  714     virtual void HandleL3Unknown(const WifiPacket &p, const ip4_hdr_t *ip4h, const ip6_hdr_t *ip6h, const u_char *rest, size_t len){}
  715 };
  716 
  717 
  718 
  719 
  720 /**
  721  * Applications create an instance of this to start processing a pcap
  722  * trace. Example:
  723  *
  724  *    Wifipcap *wp = new Wifipcap("/path/to/mytrace.cap");
  725  *    wp->Run(new MyCallbacks());
  726  */
  727 class Wifipcap {
  728     // these are not implemented
  729     Wifipcap(const Wifipcap &t);
  730     Wifipcap &operator=(const Wifipcap &that);
  731 public:
  732     /**
  733      * Utility functions for 802.11 fields.
  734      */
  735     class WifiUtil {
  736     public:
  737         // some functions to convert codes to ascii names
  738         static const char *MgmtAuthAlg2Txt(uint v);
  739         static const char *MgmtStatusCode2Txt(uint v);
  740         static const char *MgmtReasonCode2Txt(uint v);
  741         static const char *EtherType2Txt(uint t);
  742     };
  743 
  744     /**
  745      * Initialize the lib. Exits with error message upon failure.
  746      *
  747      * @param name the device if live = true, else the file name of
  748      * the trace. If the file name ends in '.gz', we assume its a
  749      * gzipped trace and will pipe it through zcat before parsing it.
  750      * @param live true if reading from a device, otherwise a trace
  751      */
  752     Wifipcap():descr(),datalink(),morefiles(),verbose(),startTime(),lastPrintTime(),packetsProcessed(){
  753     }; 
  754     Wifipcap(const char *name, bool live_ = false, bool verbose_ = false):
  755         descr(NULL), datalink(),morefiles(),verbose(verbose_), startTime(TIME_NONE), 
  756         lastPrintTime(TIME_NONE), packetsProcessed(0) {
  757         Init(name, live_);
  758     }
  759     
  760     /**
  761      * Initialize with nfiles. Will run on all of them in order.
  762      */
  763     Wifipcap(const char* const *names, int nfiles_, bool verbose_ = false):
  764         descr(NULL), datalink(),morefiles(),verbose(verbose_), startTime(TIME_NONE), 
  765         lastPrintTime(TIME_NONE), packetsProcessed(0) {
  766         for (int i=0; i<nfiles_; i++) {
  767             morefiles.push_back(names[i]);
  768         }
  769         InitNext();
  770     }
  771 
  772     virtual ~Wifipcap(){ };
  773 
  774     /**
  775      * Set a pcap filter. Returns non-null error string if fail.
  776      */
  777     const char *SetFilter(const char *filter);
  778 
  779     /**
  780      * Print some diagnostic messages if verbose
  781      */
  782     void SetVerbose(bool v = true) { verbose = v; }
  783 
  784     /**
  785      * Start executing the packet processing loop, calling back cbs as
  786      * required.
  787      *
  788      * @param cbs the callbacks to use during this run.
  789      * @param maxpkts the maximum number of packets to process before
  790      * returning. 0 = inifinite.
  791      */
  792     /** Packet handling callback
  793      *  @param user - pointer to a PcapUserData struct
  794      */
  795 
  796     /** Solely for call from ::handle_packet to WifiPcap::handle_packet */
  797     struct PcapUserData  {
  798         PcapUserData(class Wifipcap *wcap_,
  799                      struct WifipcapCallbacks *cbs_,const int header_type_):wcap(wcap_),cbs(cbs_),header_type(header_type_){};
  800         class Wifipcap *wcap;
  801         struct WifipcapCallbacks *cbs;
  802         const int header_type;
  803     };
  804     void dl_prism(const PcapUserData &data, const struct pcap_pkthdr *header, const u_char * packet);
  805     void dl_ieee802_11_radio(const PcapUserData &data, const struct pcap_pkthdr *header, const u_char * packet);
  806     void handle_packet(WifipcapCallbacks *cbs,int header_type,
  807                        const struct pcap_pkthdr *header, const u_char * packet);
  808 
  809     static void dl_prism(const u_char *user, const struct pcap_pkthdr *header, const u_char * packet);
  810     static void dl_ieee802_11_radio(const u_char *user, const struct pcap_pkthdr *header, const u_char * packet);
  811     static void handle_packet_callback(u_char *user, const struct pcap_pkthdr *header, const u_char * packet);
  812 
  813     pcap_t *GetPcap() const { return descr; }
  814     int    GetDataLink() const { return datalink; }
  815     void   Run(WifipcapCallbacks *cbs, int maxpkts = 0);
  816 
  817 private:
  818     void  Init(const char *name, bool live);
  819     bool  InitNext();
  820     pcap_t *descr;                      // can't be const
  821     int   datalink;
  822     std::list<const char *> morefiles;
  823 
  824 public:
  825     bool           verbose;
  826     struct timeval startTime;
  827     struct timeval lastPrintTime;
  828     uint64_t       packetsProcessed;
  829     static const int PRINT_TIME_INTERVAL = 6*60*60; // sec
  830 };
  831 
  832 ///////////////////////////////////////////////////////////////////////////////
  833 
  834 #include "ieee802_11_radio.h"
  835 #include "llc.h"
  836 
  837 #endif