"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 ðer[0], ðer[1], ðer[2], ðer[3], ðer[4], ðer[5]);
135 if (ret != 6) {
136 ret = sscanf(str, "%02X:%02X:%02X:%02X:%02X:%02X",
137 ðer[0], ðer[1], ðer[2], ðer[3], ðer[4], ðer[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