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 ð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 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