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;
MACMAC121     MAC():val() {}
MACMAC122     MAC(uint64_t val_):val(val_){}
MACMAC123     MAC(const MAC& o):val(o.val){}
MACMAC124     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)){}
MACMAC131     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 
ether2MACMAC157     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 {
ssid_tssid_t173     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 {
rates_trates_t180     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 {
challenge_tchallenge_t187     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 {
fh_tfh_t194     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 {
ctrl_cts_tctrl_cts_t258     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 {
ctrl_ack_tctrl_ack_t268     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 {
ctrl_ps_poll_tctrl_ps_poll_t278     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 {
ctrl_end_tctrl_end_t290     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 {
ctrl_end_ack_tctrl_end_ack_t302     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
mac_hdr_tmac_hdr_t317     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 {
wep_hdr_twep_hdr_t377     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 {
ether_hdr_tether_hdr_t450     ether_hdr_t():sa(),da(),type(){};
451     MAC sa, da;
452     uint16_t type;
453 };
454 
455 struct mgmt_header_t {
mgmt_header_tmgmt_header_t456     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 
mgmt_body_tmgmt_body_t468     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 {
ctrl_rts_tctrl_rts_t500     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 
WifiPacketWifiPacket566     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 
WifipcapCallbacksWifipcapCallbacks610     WifipcapCallbacks(){};
~WifipcapCallbacksWifipcapCallbacks611     virtual ~WifipcapCallbacks(){};
612 
nameWifipcapCallbacks613     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      */
PacketBeginWifipcapCallbacks624     virtual void PacketBegin(const WifiPacket &p, const u_char *pkt, size_t len, int origlen){}
PacketEndWifipcapCallbacks625     virtual void PacketEnd(const WifiPacket &p ){}
626 
627     // If a Prism or RadioTap packet is found, call these, and then call Handle80211()
628 
HandlePrismWifipcapCallbacks629     virtual void HandlePrism(const WifiPacket &p, struct prism2_pkthdr *hdr, const u_char *rest, size_t len){}
HandleRadiotapWifipcapCallbacks630     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.
Handle80211WifipcapCallbacks645     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
Check80211FCSWifipcapCallbacks650     virtual bool Check80211FCS(const WifiPacket &p ) { return false; }
651 
652     // Management
Handle80211MgmtBeaconWifipcapCallbacks653     virtual void Handle80211MgmtBeacon(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body)   {puts("Handle80211MgmtBeacon");}
Handle80211MgmtAssocRequestWifipcapCallbacks654     virtual void Handle80211MgmtAssocRequest(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
Handle80211MgmtAssocResponseWifipcapCallbacks655     virtual void Handle80211MgmtAssocResponse(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
Handle80211MgmtReassocRequestWifipcapCallbacks656     virtual void Handle80211MgmtReassocRequest(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
Handle80211MgmtReassocResponseWifipcapCallbacks657     virtual void Handle80211MgmtReassocResponse(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
Handle80211MgmtProbeRequestWifipcapCallbacks658     virtual void Handle80211MgmtProbeRequest(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
Handle80211MgmtProbeResponseWifipcapCallbacks659     virtual void Handle80211MgmtProbeResponse(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
Handle80211MgmtATIMWifipcapCallbacks660     virtual void Handle80211MgmtATIM(const WifiPacket &p, const struct mgmt_header_t *hdr){}
Handle80211MgmtDisassocWifipcapCallbacks661     virtual void Handle80211MgmtDisassoc(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
Handle80211MgmtAuthWifipcapCallbacks662     virtual void Handle80211MgmtAuth(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
Handle80211MgmtAuthSharedKeyWifipcapCallbacks663     virtual void Handle80211MgmtAuthSharedKey(const WifiPacket &p, const struct mgmt_header_t *hdr, const u_char *rest, size_t len){}
Handle80211MgmtDeauthWifipcapCallbacks664     virtual void Handle80211MgmtDeauth(const WifiPacket &p, const struct mgmt_header_t *hdr, const struct mgmt_body_t *body){}
665 
666     // Control
Handle80211CtrlPSPollWifipcapCallbacks667     virtual void Handle80211CtrlPSPoll(const WifiPacket &p, const struct ctrl_ps_poll_t *hdr){}
Handle80211CtrlRTSWifipcapCallbacks668     virtual void Handle80211CtrlRTS(const WifiPacket &p, const struct ctrl_rts_t *hdr){}
Handle80211CtrlCTSWifipcapCallbacks669     virtual void Handle80211CtrlCTS(const WifiPacket &p, const struct ctrl_cts_t *hdr){}
Handle80211CtrlAckWifipcapCallbacks670     virtual void Handle80211CtrlAck(const WifiPacket &p, const struct ctrl_ack_t *hdr){}
Handle80211CtrlCFEndWifipcapCallbacks671     virtual void Handle80211CtrlCFEnd(const WifiPacket &p, const struct ctrl_end_t *hdr){}
Handle80211CtrlEndAckWifipcapCallbacks672     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
Handle80211DataWifipcapCallbacks675     virtual void Handle80211Data(const WifiPacket &p, u_int16_t fc, const struct mac_hdr_t &hdr,
676                                  const u_char *rest, size_t len){}
Handle80211DataIBSSWifipcapCallbacks677     virtual void Handle80211DataIBSS(const WifiPacket &p, const struct mac_hdr_t &hdr, const u_char *rest, size_t len){}
Handle80211DataFromAPWifipcapCallbacks678     virtual void Handle80211DataFromAP(const WifiPacket &p, const struct mac_hdr_t &hdr, const u_char *rest, size_t len){}
Handle80211DataToAPWifipcapCallbacks679     virtual void Handle80211DataToAP(const WifiPacket &p, const struct mac_hdr_t &hdr, const u_char *rest, size_t len){}
Handle80211DataWDSWifipcapCallbacks680     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
Handle80211UnknownWifipcapCallbacks684     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 
HandleLLCWifipcapCallbacks688     virtual void HandleLLC(const WifiPacket &p, const struct llc_hdr_t *hdr, const u_char *rest, size_t len){}
HandleLLCUnknownWifipcapCallbacks689     virtual void HandleLLCUnknown(const WifiPacket &p, const u_char *rest, size_t len){}
HandleWEPWifipcapCallbacks690     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
HandleEthernetWifipcapCallbacks693     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 
HandleARPWifipcapCallbacks697     virtual void HandleARP(const WifiPacket &p, const arp_pkthdr *hdr, const u_char *rest, size_t len){}
HandleIPWifipcapCallbacks698     virtual void HandleIP(const WifiPacket &p, const ip4_hdr_t *hdr, const u_char *options, int optlen, const u_char *rest, size_t len){}
HandleIP6WifipcapCallbacks699     virtual void HandleIP6(const WifiPacket &p, const ip6_hdr_t *hdr, const u_char *rest, size_t len){}
HandleL2UnknownWifipcapCallbacks700     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
HandleICMPWifipcapCallbacks711     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){}
HandleTCPWifipcapCallbacks712     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){}
HandleUDPWifipcapCallbacks713     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){}
HandleL3UnknownWifipcapCallbacks714     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      */
Wifipcap()752     Wifipcap():descr(),datalink(),morefiles(),verbose(),startTime(),lastPrintTime(),packetsProcessed(){
753     };
754     Wifipcap(const char *name, bool live_ = false, bool verbose_ = false):
descr(NULL)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):
descr(NULL)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 
~Wifipcap()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  {
PcapUserDataPcapUserData798         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 
GetPcap()813     pcap_t *GetPcap() const { return descr; }
GetDataLink()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
838