tcpflow  1.6.1
About: tcpflow is a TCP/IP packet demultiplexer that captures data transmitted as part of TCP connections (flows), and stores the data in a way that is convenient for protocol analysis and debugging.
  Fossies Dox: tcpflow-1.6.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

wifipcap.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * Log:
3  * 2006-03-12: Parts originally authored by Doug Madory as wifi_parser.c
4  * 2013-03-15: Substantially modified by Simson Garfinkel for inclusion into tcpflow
5  * 2013-11-18: reworked static calls to be entirely calls to a class. Changed TimeVal pointer to an instance variable that includes the full packet header.
6  **********************************************************************/
7 
8 //*do 11-18
9 
10 #include "config.h" // pull in HAVE_ defines
11 
12 #define __STDC_FORMAT_MACROS
13 
14 #include <stdint.h>
15 #include <inttypes.h>
16 
17 #include <iostream>
18 #include <cstdlib>
19 #include <cstdio>
20 #include <cstring>
21 #include <stdarg.h>
22 #include <errno.h>
23 
24 #ifdef HAVE_NET_ETHERNET_H
25 #ifdef HAVE_SYS_PARAM_H
26 #include <sys/param.h>
27 #endif
28 #include <net/ethernet.h>
29 #endif
30 
31 #ifdef HAVE_ARPA_INET_H
32 #include <arpa/inet.h>
33 #endif
34 
35 #ifdef HAVE_UNISTD_H
36 #include <unistd.h>
37 #endif
38 
39 #pragma GCC diagnostic ignored "-Wcast-align"
40 
41 #include "wifipcap.h"
42 
43 #include "cpack.h"
44 #include "extract.h"
45 #include "oui.h"
46 #include "ethertype.h"
47 #include "icmp.h"
48 #include "ipproto.h"
49 
50 /* wifipcap uses a MAC class which is somewhat lame, but works */
51 
52 MAC MAC::broadcast(0xffffffffffffULL);
53 MAC MAC::null((uint64_t)0);
54 int WifiPacket::debug=0;
56 
57 std::ostream& operator<<(std::ostream& out, const MAC& mac) {
58  const char *fmt = MAC::print_fmt == MAC::PRINT_FMT_COLON ?
59  "%02x:%02x:%02x:%02x:%02x:%02x" :
60  "%02x%02x%02x%02x%02x%02x";
61  char buf[24];
62  sprintf(buf, fmt,
63  (int)((mac.val>>40)&0xff),
64  (int)((mac.val>>32)&0xff),
65  (int)((mac.val>>24)&0xff),
66  (int)((mac.val>>16)&0xff),
67  (int)((mac.val>>8)&0xff),
68  (int)((mac.val)&0xff)
69  );
70  out << buf;
71  return out;
72 }
73 
74 std::ostream& operator<<(std::ostream& out, const struct in_addr& ip) {
75  out << inet_ntoa(ip);
76  return out;
77 }
78 
79 struct tok {
80  int v; /* value */
81  const char *s; /* string */
82 };
83 
84 #if 0
85 static const struct tok ethertype_values[] = {
86  { ETHERTYPE_IP, "IPv4" },
87  { ETHERTYPE_MPLS, "MPLS unicast" },
88  { ETHERTYPE_MPLS_MULTI, "MPLS multicast" },
89  { ETHERTYPE_IPV6, "IPv6" },
90  { ETHERTYPE_8021Q, "802.1Q" },
91  { ETHERTYPE_VMAN, "VMAN" },
92  { ETHERTYPE_PUP, "PUP" },
93  { ETHERTYPE_ARP, "ARP"},
94  { ETHERTYPE_REVARP, "Reverse ARP"},
95  { ETHERTYPE_NS, "NS" },
96  { ETHERTYPE_SPRITE, "Sprite" },
97  { ETHERTYPE_TRAIL, "Trail" },
98  { ETHERTYPE_MOPDL, "MOP DL" },
99  { ETHERTYPE_MOPRC, "MOP RC" },
100  { ETHERTYPE_DN, "DN" },
101  { ETHERTYPE_LAT, "LAT" },
102  { ETHERTYPE_SCA, "SCA" },
103  { ETHERTYPE_LANBRIDGE, "Lanbridge" },
104  { ETHERTYPE_DECDNS, "DEC DNS" },
105  { ETHERTYPE_DECDTS, "DEC DTS" },
106  { ETHERTYPE_VEXP, "VEXP" },
107  { ETHERTYPE_VPROD, "VPROD" },
108  { ETHERTYPE_ATALK, "Appletalk" },
109  { ETHERTYPE_AARP, "Appletalk ARP" },
110  { ETHERTYPE_IPX, "IPX" },
111  { ETHERTYPE_PPP, "PPP" },
112  { ETHERTYPE_SLOW, "Slow Protocols" },
113  { ETHERTYPE_PPPOED, "PPPoE D" },
114  { ETHERTYPE_PPPOES, "PPPoE S" },
115  { ETHERTYPE_EAPOL, "EAPOL" },
116  { ETHERTYPE_JUMBO, "Jumbo" },
117  { ETHERTYPE_LOOPBACK, "Loopback" },
118  { ETHERTYPE_ISO, "OSI" },
119  { ETHERTYPE_GRE_ISO, "GRE-OSI" },
120  { 0, NULL}
121 };
122 #endif
123 
124 /*max length of an IEEE 802.11 packet*/
125 #ifndef MAX_LEN_80211
126 #define MAX_LEN_80211 3000
127 #endif
128 
129 /* from ethereal packet-prism.c */
130 #define pletohs(p) ((u_int16_t) \
131  ((u_int16_t)*((const u_int8_t *)(p)+1)<<8| \
132  (u_int16_t)*((const u_int8_t *)(p)+0)<<0))
133 #define pntohl(p) ((u_int32_t)*((const u_int8_t *)(p)+0)<<24| \
134  (u_int32_t)*((const u_int8_t *)(p)+1)<<16| \
135  (u_int32_t)*((const u_int8_t *)(p)+2)<<8| \
136  (u_int32_t)*((const u_int8_t *)(p)+3)<<0)
137 #define COOK_FRAGMENT_NUMBER(x) ((x) & 0x000F)
138 #define COOK_SEQUENCE_NUMBER(x) (((x) & 0xFFF0) >> 4)
139 /* end ethereal code */
140 
141 /* Sequence number gap */
142 #define SEQ_GAP(current, last)(0xfff & (current - last))
143 
144 /* In the following three arrays, even though the QoS subtypes are listed, in the rest of the program
145  * the QoS subtypes are treated as "OTHER_TYPES". The file "ieee802_11.h" currently doesn't account for
146  * the existence of QoS subtypes. The QoS subtypes might need to be accomodated there in the future.
147  */
148 #if 0
149 static const char * mgmt_subtype_text[] = {
150  "AssocReq",
151  "AssocResp",
152  "ReAssocReq",
153  "ReAssocResp",
154  "ProbeReq",
155  "ProbeResp",
156  "",
157  "",
158  "Beacon",
159  "ATIM",
160  "Disassoc",
161  "Auth",
162  "DeAuth",
163  "Action", /*QoS mgmt_subtype*/
164  "",
165  ""
166 };
167 
168 static const char * ctrl_subtype_text[] = {
169  "", "", "", "", "", "", "", "",
170  "BlockAckReq", /*QoS ctrl_subtype*/
171  "BlockAck", /*QoS ctrl_subtype*/
172  "PS-Poll",
173  "RTS",
174  "CTS",
175  "ACK",
176  "CF-End",
177  "CF-End+CF-Ack"
178 };
179 
180 static const char * data_subtype_text[] = {
181  "Data",
182  "Data+CF-Ack",
183  "Data+CF-Poll",
184  "Data+CF-Ack+CF-Poll",
185  "Null(no_data)",
186  "CF-Ack(no_data)",
187  "CF-Poll(no_data)",
188  "CF-Ack+CF-Poll(no_data)",
189  "QoS_Data", /*QoS data_subtypes from here on*/
190  "QoS_Data+CF-Ack",
191  "QoS_Data+CF-Poll",
192  "QoS_Data+CF-Ack+CF-Poll",
193  "QoS_Null(no_data)",
194  "",
195  "QoS_CF-Poll(no_data)",
196  "QoS_CF-Ack+CF-Poll(no_data)"
197 };
198 #endif
199 
200 ///////////////////////////////////////////////////////////////////////////////
201 // crc32 implementation needed for wifi checksum
202 
203 /* crc32.c
204  * CRC-32 routine
205  *
206  * $Id: crc32.cpp,v 1.1 2007/02/14 00:05:50 jpang Exp $
207  *
208  * Ethereal - Network traffic analyzer
209  * By Gerald Combs <gerald@ethereal.com>
210  * Copyright 1998 Gerald Combs
211  *
212  * Copied from README.developer
213  *
214  * This program is free software; you can redistribute it and/or
215  * modify it under the terms of the GNU General Public License
216  * as published by the Free Software Foundation; either version 2
217  * of the License, or (at your option) any later version.
218  *
219  * This program is distributed in the hope that it will be useful,
220  * but WITHOUT ANY WARRANTY; without even the implied warranty of
221  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
222  * GNU General Public License for more details.
223  *
224  * You should have received a copy of the GNU General Public License
225  * along with this program; if not, write to the Free Software
226  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
227  *
228  * Credits:
229  *
230  * Table from Solomon Peachy
231  * Routine from Chris Waters
232  */
233 
234 /*
235  * Table for the AUTODIN/HDLC/802.x CRC.
236  *
237  * Polynomial is
238  *
239  * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^8 + x^7 +
240  * x^5 + x^4 + x^2 + x + 1
241  */
242 static const uint32_t crc32_ccitt_table[256] = {
243  0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
244  0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
245  0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
246  0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
247  0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
248  0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
249  0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
250  0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
251  0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
252  0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
253  0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
254  0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
255  0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
256  0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
257  0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
258  0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
259  0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
260  0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
261  0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
262  0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
263  0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
264  0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
265  0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
266  0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
267  0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
268  0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
269  0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
270  0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
271  0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
272  0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
273  0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
274  0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
275  0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
276  0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
277  0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
278  0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
279  0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
280  0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
281  0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
282  0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
283  0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
284  0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
285  0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
286  0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
287  0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
288  0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
289  0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
290  0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
291  0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
292  0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
293  0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
294  0x2d02ef8d
295 };
296 
297 #define CRC32_CCITT_SEED 0xFFFFFFFF
298 
299 static uint32_t crc32_ccitt_seed(const uint8_t *buf, size_t len, uint32_t seed);
300 
301 static uint32_t crc32_ccitt(const uint8_t *buf, size_t len)
302 {
303  return ( crc32_ccitt_seed(buf, len, CRC32_CCITT_SEED) );
304 }
305 
306 static uint32_t crc32_ccitt_seed(const uint8_t *buf, size_t len, uint32_t seed)
307 {
308  uint32_t crc32 = seed;
309 
310  for (unsigned int i = 0; i < len; i++){
311  crc32 = crc32_ccitt_table[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8);
312  }
313 
314  return ( ~crc32 );
315 }
316 
317 /*
318  * IEEE 802.x version (Ethernet and 802.11, at least) - byte-swap
319  * the result of "crc32()".
320  *
321  * XXX - does this mean we should fetch the Ethernet and 802.11
322  * Frame Checksum (FCS) with "tvb_get_letohl()" rather than "tvb_get_ntohl()",
323  * or is fetching it big-endian and byte-swapping the CRC done
324  * to cope with 802.x sending stuff out in reverse bit order?
325  */
326 static uint32_t crc32_802(const unsigned char *buf, size_t len)
327 {
328  uint32_t c_crc;
329 
330  c_crc = crc32_ccitt(buf, len);
331 
332  /* Byte reverse. */
333  c_crc = ((unsigned char)(c_crc>>0)<<24) |
334  ((unsigned char)(c_crc>>8)<<16) |
335  ((unsigned char)(c_crc>>16)<<8) |
336  ((unsigned char)(c_crc>>24)<<0);
337 
338  return ( c_crc );
339 }
340 ///////////////////////////////////////////////////////////////////////////////
341 
342 ///////////////////////////////////////////////////////////////////////////////
343 
344 /* Translate Ethernet address, as seen in struct ether_header, to type MAC. */
345 /* Extract header length. */
346 static size_t extract_header_length(u_int16_t fc)
347 {
348  switch (FC_TYPE(fc)) {
349  case T_MGMT:
350  return MGMT_HDRLEN;
351  case T_CTRL:
352  switch (FC_SUBTYPE(fc)) {
353  case CTRL_PS_POLL:
354  return CTRL_PS_POLL_HDRLEN;
355  case CTRL_RTS:
356  return CTRL_RTS_HDRLEN;
357  case CTRL_CTS:
358  return CTRL_CTS_HDRLEN;
359  case CTRL_ACK:
360  return CTRL_ACK_HDRLEN;
361  case CTRL_CF_END:
362  return CTRL_END_HDRLEN;
363  case CTRL_END_ACK:
364  return CTRL_END_ACK_HDRLEN;
365  default:
366  return 0;
367  }
368  case T_DATA:
369  return (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
370  default:
371  return 0;
372  }
373 }
374 
375 ///////////////////////////////////////////////////////////////////////////////
376 
377 ///////////////////////////////////////////////////////////////////////////////
378 
379 #pragma GCC diagnostic ignored "-Wcast-align"
380 void WifiPacket::handle_llc(const mac_hdr_t &mac,const u_char *ptr, size_t len,u_int16_t fc)
381 {
382  if (len < 7) {
383  // truncated header!
384  cbs->HandleLLC(*this,NULL, ptr, len);
385  return;
386  }
387 
388  // http://www.wildpackets.com/resources/compendium/wireless_lan/wlan_packets
389 
390  llc_hdr_t hdr;
391  hdr.dsap = EXTRACT_LE_8BITS(ptr); // Destination Service Access point
392  hdr.ssap = EXTRACT_LE_8BITS(ptr + 1); // Source Service Access Point
393  hdr.control= EXTRACT_LE_8BITS(ptr + 2); // ignored by most protocols
394  hdr.oui = EXTRACT_24BITS(ptr + 3);
395  hdr.type = EXTRACT_16BITS(ptr + 6);
396 
397 
398  /* "When both the DSAP and SSAP are set to 0xAA, the type is
399  * interpreted as a protocol not defined by IEEE and the LSAP is
400  * referred to as SubNetwork Access Protocol (SNAP). In SNAP, the
401  * 5 bytes that follow the DSAP, SSAP, and control byte are called
402  * the Protocol Discriminator."
403  */
404 
405  if(hdr.dsap==0xAA && hdr.ssap==0xAA){
406  cbs->HandleLLC(*this,&hdr,ptr+8,len-8);
407  return;
408  }
409 
410  if (hdr.oui == OUI_ENCAP_ETHER || hdr.oui == OUI_CISCO_90) {
411  cbs->HandleLLC(*this,&hdr, ptr+8, len-8);
412  return;
413  }
414 
415  cbs->HandleLLCUnknown(*this,ptr, len);
416 }
417 
418 void WifiPacket::handle_wep(const u_char *ptr, size_t len)
419 {
420  // Jeff: XXX handle TKIP/CCMP ? how can we demultiplex different
421  // protection protocols?
422 
423  struct wep_hdr_t hdr;
424  u_int32_t iv;
425 
427  // truncated!
428  cbs->HandleWEP(*this,NULL, ptr, len);
429  return;
430  }
431  iv = EXTRACT_LE_32BITS(ptr);
432  hdr.iv = IV_IV(iv);
433  hdr.pad = IV_PAD(iv);
434  hdr.keyid = IV_KEYID(iv);
435  cbs->HandleWEP(*this,&hdr, ptr, len);
436 }
437 
438 ///////////////////////////////////////////////////////////////////////////////
439 
440 static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
441 #define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0])
442 
443 static const char *status_text[] = {
444  "Succesful", /* 0 */
445  "Unspecified failure", /* 1 */
446  "Reserved", /* 2 */
447  "Reserved", /* 3 */
448  "Reserved", /* 4 */
449  "Reserved", /* 5 */
450  "Reserved", /* 6 */
451  "Reserved", /* 7 */
452  "Reserved", /* 8 */
453  "Reserved", /* 9 */
454  "Cannot Support all requested capabilities in the Capability Information field", /* 10 */
455  "Reassociation denied due to inability to confirm that association exists", /* 11 */
456  "Association denied due to reason outside the scope of the standard", /* 12 */
457  "Responding station does not support the specified authentication algorithm ", /* 13 */
458  "Received an Authentication frame with authentication transaction " \
459  "sequence number out of expected sequence", /* 14 */
460  "Authentication rejected because of challenge failure", /* 15 */
461  "Authentication rejected due to timeout waiting for next frame in sequence", /* 16 */
462  "Association denied because AP is unable to handle additional associated stations", /* 17 */
463  "Association denied due to requesting station not supporting all of the " \
464  "data rates in BSSBasicRateSet parameter", /* 18 */
465 };
466 #define NUM_STATUSES (sizeof status_text / sizeof status_text[0])
467 
468 static const char *reason_text[] = {
469  "Reserved", /* 0 */
470  "Unspecified reason", /* 1 */
471  "Previous authentication no longer valid", /* 2 */
472  "Deauthenticated because sending station is leaving (or has left) IBSS or ESS", /* 3 */
473  "Disassociated due to inactivity", /* 4 */
474  "Disassociated because AP is unable to handle all currently associated stations", /* 5 */
475  "Class 2 frame received from nonauthenticated station", /* 6 */
476  "Class 3 frame received from nonassociated station", /* 7 */
477  "Disassociated because sending station is leaving (or has left) BSS", /* 8 */
478  "Station requesting (re)association is not authenticated with responding station", /* 9 */
479 };
480 #define NUM_REASONS (sizeof reason_text / sizeof reason_text[0])
481 
483  return v < NUM_AUTH_ALGS ? auth_alg_text[v] : "Unknown";
484 }
486  return v < NUM_STATUSES ? status_text[v] : "Reserved";
487 }
489  return v < NUM_REASONS ? reason_text[v] : "Reserved";
490 }
491 
492 ///////////////////////////////////////////////////////////////////////////////
493 
494 // Jeff: HACK -- tcpdump uses a global variable to check truncation
495 #define TTEST2(_p, _l) ((const u_char *)&(_p) - p + (_l) <= (ssize_t)len)
496 
497 void WifiPacket::parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset, size_t len)
498 {
499  /*
500  * We haven't seen any elements yet.
501  */
502  pbody->challenge_status = NOT_PRESENT;
503  pbody->ssid_status = NOT_PRESENT;
504  pbody->rates_status = NOT_PRESENT;
505  pbody->ds_status = NOT_PRESENT;
506  pbody->cf_status = NOT_PRESENT;
507  pbody->tim_status = NOT_PRESENT;
508 
509  for (;;) {
510  if (!TTEST2(*(p + offset), 1))
511  return;
512  switch (*(p + offset)) {
513  case E_SSID:
514  /* Present, possibly truncated */
515  pbody->ssid_status = TRUNCATED;
516  if (!TTEST2(*(p + offset), 2))
517  return;
518  memcpy(&pbody->ssid, p + offset, 2);
519  offset += 2;
520  if (pbody->ssid.length != 0) {
521  if (pbody->ssid.length >
522  sizeof(pbody->ssid.ssid) - 1)
523  return;
524  if (!TTEST2(*(p + offset), pbody->ssid.length))
525  return;
526  memcpy(&pbody->ssid.ssid, p + offset,
527  pbody->ssid.length);
528  offset += pbody->ssid.length;
529  }
530  pbody->ssid.ssid[pbody->ssid.length] = '\0';
531  /* Present and not truncated */
532  pbody->ssid_status = PRESENT;
533  break;
534  case E_CHALLENGE:
535  /* Present, possibly truncated */
536  pbody->challenge_status = TRUNCATED;
537  if (!TTEST2(*(p + offset), 2))
538  return;
539  memcpy(&pbody->challenge, p + offset, 2);
540  offset += 2;
541  if (pbody->challenge.length != 0) {
542  if (pbody->challenge.length >
543  sizeof(pbody->challenge.text) - 1)
544  return;
545  if (!TTEST2(*(p + offset), pbody->challenge.length))
546  return;
547  memcpy(&pbody->challenge.text, p + offset,
548  pbody->challenge.length);
549  offset += pbody->challenge.length;
550  }
551  pbody->challenge.text[pbody->challenge.length] = '\0';
552  /* Present and not truncated */
553  pbody->challenge_status = PRESENT;
554  break;
555  case E_RATES:
556  /* Present, possibly truncated */
557  pbody->rates_status = TRUNCATED;
558  if (!TTEST2(*(p + offset), 2))
559  return;
560  memcpy(&(pbody->rates), p + offset, 2);
561  offset += 2;
562  if (pbody->rates.length != 0) {
563  if (pbody->rates.length > sizeof pbody->rates.rate)
564  return;
565  if (!TTEST2(*(p + offset), pbody->rates.length))
566  return;
567  memcpy(&pbody->rates.rate, p + offset,
568  pbody->rates.length);
569  offset += pbody->rates.length;
570  }
571  /* Present and not truncated */
572  pbody->rates_status = PRESENT;
573  break;
574  case E_DS:
575  /* Present, possibly truncated */
576  pbody->ds_status = TRUNCATED;
577  if (!TTEST2(*(p + offset), 3))
578  return;
579  memcpy(&pbody->ds, p + offset, 3);
580  offset += 3;
581  /* Present and not truncated */
582  pbody->ds_status = PRESENT;
583  break;
584  case E_CF:
585  /* Present, possibly truncated */
586  pbody->cf_status = TRUNCATED;
587  if (!TTEST2(*(p + offset), 8))
588  return;
589  memcpy(&pbody->cf, p + offset, 8);
590  offset += 8;
591  /* Present and not truncated */
592  pbody->cf_status = PRESENT;
593  break;
594  case E_TIM:
595  /* Present, possibly truncated */
596  pbody->tim_status = TRUNCATED;
597  if (!TTEST2(*(p + offset), 2))
598  return;
599  memcpy(&pbody->tim, p + offset, 2);
600  offset += 2;
601  if (!TTEST2(*(p + offset), 3))
602  return;
603  memcpy(&pbody->tim.count, p + offset, 3);
604  offset += 3;
605 
606  if (pbody->tim.length <= 3)
607  break;
608  if (pbody->rates.length > sizeof pbody->tim.bitmap)
609  return;
610  if (!TTEST2(*(p + offset), pbody->tim.length - 3))
611  return;
612  memcpy(pbody->tim.bitmap, p + (pbody->tim.length - 3),
613  (pbody->tim.length - 3));
614  offset += pbody->tim.length - 3;
615  /* Present and not truncated */
616  pbody->tim_status = PRESENT;
617  break;
618  default:
619 #ifdef DEBUG_WIFI
620  printf("(1) unhandled element_id (%d) ", *(p + offset) );
621 #endif
622  if (!TTEST2(*(p + offset), 2))
623  return;
624  if (!TTEST2(*(p + offset + 2), *(p + offset + 1)))
625  return;
626  offset += *(p + offset + 1) + 2;
627  break;
628  }
629  }
630 }
631 
632 /*********************************************************************************
633  * Print Handle functions for the management frame types
634  *********************************************************************************/
635 
636 int
637 WifiPacket::handle_beacon( const struct mgmt_header_t *pmh, const u_char *p, size_t len)
638 {
639  struct mgmt_body_t pbody;
640  int offset = 0;
641 
642  memset(&pbody, 0, sizeof(pbody));
643 
646  return 0;
647  memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
648  offset += IEEE802_11_TSTAMP_LEN;
649  pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
650  offset += IEEE802_11_BCNINT_LEN;
651  pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
652  offset += IEEE802_11_CAPINFO_LEN;
653 
654  parse_elements(&pbody, p, offset, len);
655 
656  /*
657  PRINT_SSID(pbody);
658  PRINT_RATES(pbody);
659  printf(" %s",
660  CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
661  PRINT_DS_CHANNEL(pbody);
662  */
663  cbs->Handle80211MgmtBeacon(*this, pmh, &pbody);
664  return 1;
665 }
666 
667 int WifiPacket::handle_assoc_request( const struct mgmt_header_t *pmh, const u_char *p, size_t len)
668 {
669  struct mgmt_body_t pbody;
670  int offset = 0;
671 
672  memset(&pbody, 0, sizeof(pbody));
673 
675  return 0;
677  offset += IEEE802_11_CAPINFO_LEN;
678  pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
679  offset += IEEE802_11_LISTENINT_LEN;
680 
681  parse_elements(&pbody, p, offset, len);
682 
683  /*
684  PRINT_SSID(pbody);
685  PRINT_RATES(pbody);
686  */
687  cbs->Handle80211MgmtAssocRequest(*this, pmh, &pbody);
688 
689  return 1;
690 }
691 
692 int WifiPacket::handle_assoc_response( const struct mgmt_header_t *pmh, const u_char *p, size_t len, bool reassoc)
693 {
694  struct mgmt_body_t pbody;
695  int offset = 0;
696 
697  memset(&pbody, 0, sizeof(pbody));
698 
701  return 0;
703  offset += IEEE802_11_CAPINFO_LEN;
704  pbody.status_code = EXTRACT_LE_16BITS(p+offset);
705  offset += IEEE802_11_STATUS_LEN;
706  pbody.aid = EXTRACT_LE_16BITS(p+offset);
707  offset += IEEE802_11_AID_LEN;
708 
709  parse_elements(&pbody, p, offset, len);
710 
711  /*
712  printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
713  CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
714  (pbody.status_code < NUM_STATUSES
715  ? status_text[pbody.status_code]
716  : "n/a"));
717  */
718  if (!reassoc)
719  cbs->Handle80211MgmtAssocResponse(*this, pmh, &pbody);
720  else
721  cbs->Handle80211MgmtReassocResponse(*this, pmh, &pbody);
722 
723  return 1;
724 }
725 
726 int
727 WifiPacket::handle_reassoc_request( const struct mgmt_header_t *pmh, const u_char *p, size_t len)
728 {
729  struct mgmt_body_t pbody;
730  int offset = 0;
731 
732  memset(&pbody, 0, sizeof(pbody));
733 
736  return 0;
738  offset += IEEE802_11_CAPINFO_LEN;
739  pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
740  offset += IEEE802_11_LISTENINT_LEN;
741  memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
742  offset += IEEE802_11_AP_LEN;
743 
744  parse_elements(&pbody, p, offset, len);
745 
746  /*
747  PRINT_SSID(pbody);
748  printf(" AP : %s", etheraddr_string( pbody.ap ));
749  */
750  cbs->Handle80211MgmtReassocRequest(*this, pmh, &pbody);
751 
752  return 1;
753 }
754 
755 int
756 WifiPacket::handle_reassoc_response( const struct mgmt_header_t *pmh, const u_char *p, size_t len)
757 {
758  /* Same as a Association Reponse */
759  return handle_assoc_response(pmh, p, len, true);
760 }
761 
762 int
763 WifiPacket::handle_probe_request( const struct mgmt_header_t *pmh, const u_char *p, size_t len)
764 {
765  struct mgmt_body_t pbody;
766  int offset = 0;
767 
768  memset(&pbody, 0, sizeof(pbody));
769 
770  parse_elements(&pbody, p, offset, len);
771 
772  /*
773  PRINT_SSID(pbody);
774  PRINT_RATES(pbody);
775  */
776  cbs->Handle80211MgmtProbeRequest(*this, pmh, &pbody);
777 
778  return 1;
779 }
780 
781 int
782 WifiPacket::handle_probe_response( const struct mgmt_header_t *pmh, const u_char *p, size_t len)
783 {
784  struct mgmt_body_t pbody;
785  int offset = 0;
786 
787  memset(&pbody, 0, sizeof(pbody));
788 
791  return 0;
792 
793  memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
794  offset += IEEE802_11_TSTAMP_LEN;
795  pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
796  offset += IEEE802_11_BCNINT_LEN;
797  pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
798  offset += IEEE802_11_CAPINFO_LEN;
799 
800  parse_elements(&pbody, p, offset, len);
801 
802  /*
803  PRINT_SSID(pbody);
804  PRINT_RATES(pbody);
805  PRINT_DS_CHANNEL(pbody);
806  */
807  cbs->Handle80211MgmtProbeResponse(*this, pmh, &pbody);
808 
809  return 1;
810 }
811 
812 int
813 WifiPacket::handle_atim( const struct mgmt_header_t *pmh, const u_char *p, size_t len)
814 {
815  /* the frame body for ATIM is null. */
816 
817  cbs->Handle80211MgmtATIM(*this, pmh);
818 
819  return 1;
820 }
821 
822 int
823 WifiPacket::handle_disassoc( const struct mgmt_header_t *pmh, const u_char *p, size_t len)
824 {
825  struct mgmt_body_t pbody;
826 
827  memset(&pbody, 0, sizeof(pbody));
828 
829  if (!TTEST2(*p, IEEE802_11_REASON_LEN))
830  return 0;
831  pbody.reason_code = EXTRACT_LE_16BITS(p);
832 
833  /*
834  printf(": %s",
835  (pbody.reason_code < NUM_REASONS)
836  ? reason_text[pbody.reason_code]
837  : "Reserved" );
838  */
839  cbs->Handle80211MgmtDisassoc(*this, pmh, &pbody);
840 
841  return 1;
842 }
843 
844 int
845 WifiPacket::handle_auth( const struct mgmt_header_t *pmh, const u_char *p, size_t len)
846 {
847  struct mgmt_body_t pbody;
848  int offset = 0;
849 
850  memset(&pbody, 0, sizeof(pbody));
851 
852  if (!TTEST2(*p, 6))
853  return 0;
854  pbody.auth_alg = EXTRACT_LE_16BITS(p);
855  offset += 2;
856  pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
857  offset += 2;
858  pbody.status_code = EXTRACT_LE_16BITS(p + offset);
859  offset += 2;
860 
861  parse_elements(&pbody, p, offset, len);
862 
863  /*
864  if ((pbody.auth_alg == 1) &&
865  ((pbody.auth_trans_seq_num == 2) ||
866  (pbody.auth_trans_seq_num == 3))) {
867  printf(" (%s)-%x [Challenge Text] %s",
868  (pbody.auth_alg < NUM_AUTH_ALGS)
869  ? auth_alg_text[pbody.auth_alg]
870  : "Reserved",
871  pbody.auth_trans_seq_num,
872  ((pbody.auth_trans_seq_num % 2)
873  ? ((pbody.status_code < NUM_STATUSES)
874  ? status_text[pbody.status_code]
875  : "n/a") : ""));
876  return 1;
877  }
878  printf(" (%s)-%x: %s",
879  (pbody.auth_alg < NUM_AUTH_ALGS)
880  ? auth_alg_text[pbody.auth_alg]
881  : "Reserved",
882  pbody.auth_trans_seq_num,
883  (pbody.auth_trans_seq_num % 2)
884  ? ((pbody.status_code < NUM_STATUSES)
885  ? status_text[pbody.status_code]
886  : "n/a")
887  : "");
888  */
889  cbs->Handle80211MgmtAuth(*this, pmh, &pbody);
890 
891  return 1;
892 }
893 
894 int
895 WifiPacket::handle_deauth( const struct mgmt_header_t *pmh, const u_char *p, size_t len)
896 {
897  struct mgmt_body_t pbody;
898  int offset = 0;
899  //const char *reason = NULL;
900 
901  memset(&pbody, 0, sizeof(pbody));
902 
903  if (!TTEST2(*p, IEEE802_11_REASON_LEN))
904  return 0;
905  pbody.reason_code = EXTRACT_LE_16BITS(p);
906  offset += IEEE802_11_REASON_LEN;
907 
908  /*
909  reason = (pbody.reason_code < NUM_REASONS)
910  ? reason_text[pbody.reason_code]
911  : "Reserved";
912 
913  if (eflag) {
914  printf(": %s", reason);
915  } else {
916  printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
917  }
918  */
919  cbs->Handle80211MgmtDeauth(*this, pmh, &pbody);
920 
921  return 1;
922 }
923 
924 
925 /*********************************************************************************
926  * Print Body funcs
927  *********************************************************************************/
928 
929 
930 /** Decode a management request.
931  * @return 0 - failure, non-zero success
932  *
933  * NOTE — this function and all that it calls should be handled as methods in WifipcapCallbacks
934  */
935 
936 int
937 WifiPacket::decode_mgmt_body(u_int16_t fc, struct mgmt_header_t *pmh, const u_char *p, size_t len)
938 {
939  if(debug) std::cerr << "decode_mgmt_body FC_SUBTYPE(fc)="<<(int)FC_SUBTYPE(fc)<<" ";
940  switch (FC_SUBTYPE(fc)) {
941  case ST_ASSOC_REQUEST:
942  return handle_assoc_request(pmh, p, len);
943  case ST_ASSOC_RESPONSE:
944  return handle_assoc_response(pmh, p, len);
945  case ST_REASSOC_REQUEST:
946  return handle_reassoc_request(pmh, p, len);
947  case ST_REASSOC_RESPONSE:
948  return handle_reassoc_response(pmh, p, len);
949  case ST_PROBE_REQUEST:
950  return handle_probe_request(pmh, p, len);
951  case ST_PROBE_RESPONSE:
952  return handle_probe_response(pmh, p, len);
953  case ST_BEACON:
954  return handle_beacon(pmh, p, len);
955  case ST_ATIM:
956  return handle_atim(pmh, p, len);
957  case ST_DISASSOC:
958  return handle_disassoc(pmh, p, len);
959  case ST_AUTH:
960  if (len < 3) {
961  return 0;
962  }
963  if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
964  //printf("Authentication (Shared-Key)-3 ");
965  cbs->Handle80211MgmtAuthSharedKey(*this, pmh, p, len);
966  return 0;
967  }
968  return handle_auth(pmh, p, len);
969  case ST_DEAUTH:
970  return handle_deauth(pmh, p, len);
971  break;
972  default:
973  return 0;
974  }
975 }
976 
977 int WifiPacket::decode_mgmt_frame(const u_char * ptr, size_t len, u_int16_t fc, u_int8_t hdrlen)
978 {
979  mgmt_header_t hdr;
980  u_int16_t seq_ctl;
981 
982  hdr.da = MAC::ether2MAC(ptr + 4);
983  hdr.sa = MAC::ether2MAC(ptr + 10);
984  hdr.bssid = MAC::ether2MAC(ptr + 16);
985 
986  hdr.duration = EXTRACT_LE_16BITS(ptr+2);
987 
988  seq_ctl = pletohs(ptr + 22);
989 
990  hdr.seq = COOK_SEQUENCE_NUMBER(seq_ctl);
991  hdr.frag = COOK_FRAGMENT_NUMBER(seq_ctl);
992 
993  cbs->Handle80211(*this, fc, hdr.sa, hdr.da, MAC::null, MAC::null, ptr, len);
994 
995  int ret = decode_mgmt_body(fc, &hdr, ptr+MGMT_HDRLEN, len-MGMT_HDRLEN);
996 
997  if (ret==0) {
998  cbs->Handle80211Unknown(*this, fc, ptr, len);
999  return 0;
1000  }
1001 
1002  return 0;
1003 }
1004 
1005 int WifiPacket::decode_data_frame(const u_char * ptr, size_t len, u_int16_t fc)
1006 {
1007  mac_hdr_t hdr;
1008  hdr.fc = fc;
1009  hdr.duration = EXTRACT_LE_16BITS(ptr+2);
1010  hdr.seq_ctl = pletohs(ptr + 22);
1011  hdr.seq = COOK_SEQUENCE_NUMBER(hdr.seq_ctl);
1012  hdr.frag = COOK_FRAGMENT_NUMBER(hdr.seq_ctl);
1013 
1014  if(FC_TYPE(fc)==2 && FC_SUBTYPE(fc)==8){ // quality of service?
1015  hdr.qos = 1;
1016  }
1017 
1018  size_t hdrlen=0;
1019 
1020  const MAC address1 = MAC::ether2MAC(ptr+4);
1021  const MAC address2 = MAC::ether2MAC(ptr+10);
1022  const MAC address3 = MAC::ether2MAC(ptr+16);
1023 
1024  /* call the 80211 callback data callback */
1025 
1026  if (FC_TO_DS(fc)==0 && FC_FROM_DS(fc)==0) { /* ad hoc IBSS */
1027  hdr.da = address1;
1028  hdr.sa = address2;
1029  hdr.bssid = address3;
1030  hdrlen = DATA_HDRLEN;
1031  if(hdr.qos) hdrlen+=2;
1032  cbs->Handle80211( *this, fc, hdr.sa, hdr.da, hdr.ra, hdr.ta, ptr, len);
1033  cbs->Handle80211DataIBSS( *this, hdr, ptr+hdrlen, len-hdrlen);
1034  } else if (FC_TO_DS(fc)==0 && FC_FROM_DS(fc)) { /* from AP to STA */
1035  hdr.da = address1;
1036  hdr.bssid = address2;
1037  hdr.sa = address3;
1038  hdrlen = DATA_HDRLEN;
1039  if(hdr.qos) hdrlen+=2;
1040  cbs->Handle80211( *this, fc, hdr.sa, hdr.da, hdr.ra, hdr.ta, ptr, len);
1041  cbs->Handle80211DataFromAP( *this, hdr, ptr+hdrlen, len-hdrlen);
1042  } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)==0) { /* frame from STA to AP */
1043  hdr.bssid = address1;
1044  hdr.sa = address2;
1045  hdr.da = address3;
1046  hdrlen = DATA_HDRLEN;
1047  if(hdr.qos) hdrlen+=2;
1048  cbs->Handle80211( *this, fc, hdr.sa, hdr.da, hdr.ra, hdr.ta, ptr, len);
1049  cbs->Handle80211DataToAP( *this, hdr, ptr+hdrlen, len-hdrlen);
1050  } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) { /* WDS */
1051  const MAC address4 = MAC::ether2MAC(ptr+18);
1052  hdr.ra = address1;
1053  hdr.ta = address2;
1054  hdr.da = address3;
1055  hdr.sa = address4;
1056  hdrlen = DATA_WDS_HDRLEN;
1057  if(hdr.qos) hdrlen+=2;
1058  cbs->Handle80211( *this, fc, hdr.sa, hdr.da, hdr.ra, hdr.ta, ptr, len);
1059  cbs->Handle80211DataWDS( *this, hdr, ptr+hdrlen, len-hdrlen);
1060  }
1061 
1062  /* Handle either the WEP or the link layer. This handles the data itself */
1063  if (FC_WEP(fc)) {
1064  handle_wep(ptr+hdrlen, len-hdrlen-4 );
1065  } else {
1066  handle_llc(hdr, ptr+hdrlen, len-hdrlen-4, fc);
1067  }
1068  return 0;
1069 }
1070 
1071 int WifiPacket::decode_ctrl_frame(const u_char * ptr, size_t len, u_int16_t fc)
1072 {
1073  u_int16_t du = EXTRACT_LE_16BITS(ptr+2); //duration
1074 
1075  switch (FC_SUBTYPE(fc)) {
1076  case CTRL_PS_POLL: {
1077  ctrl_ps_poll_t hdr;
1078  hdr.fc = fc;
1079  hdr.aid = du;
1080  hdr.bssid = MAC::ether2MAC(ptr+4);
1081  hdr.ta = MAC::ether2MAC(ptr+10);
1082  cbs->Handle80211( *this, fc, MAC::null, MAC::null, MAC::null, hdr.ta, ptr, len);
1083  cbs->Handle80211CtrlPSPoll( *this, &hdr);
1084  break;
1085  }
1086  case CTRL_RTS: {
1087  ctrl_rts_t hdr;
1088  hdr.fc = fc;
1089  hdr.duration = du;
1090  hdr.ra = MAC::ether2MAC(ptr+4);
1091  hdr.ta = MAC::ether2MAC(ptr+10);
1092  cbs->Handle80211( *this, fc, MAC::null, MAC::null, hdr.ra, hdr.ta, ptr, len);
1093  cbs->Handle80211CtrlRTS( *this, &hdr);
1094  break;
1095  }
1096  case CTRL_CTS: {
1097  ctrl_cts_t hdr;
1098  hdr.fc = fc;
1099  hdr.duration = du;
1100  hdr.ra = MAC::ether2MAC(ptr+4);
1101  cbs->Handle80211( *this, fc, MAC::null, MAC::null, hdr.ra, MAC::null, ptr, len);
1102  cbs->Handle80211CtrlCTS( *this, &hdr);
1103  break;
1104  }
1105  case CTRL_ACK: {
1106  ctrl_ack_t hdr;
1107  hdr.fc = fc;
1108  hdr.duration = du;
1109  hdr.ra = MAC::ether2MAC(ptr+4);
1110  cbs->Handle80211( *this, fc, MAC::null, MAC::null, hdr.ra, MAC::null, ptr, len);
1111  cbs->Handle80211CtrlAck( *this, &hdr);
1112  break;
1113  }
1114  case CTRL_CF_END: {
1115  ctrl_end_t hdr;
1116  hdr.fc = fc;
1117  hdr.duration = du;
1118  hdr.ra = MAC::ether2MAC(ptr+4);
1119  hdr.bssid = MAC::ether2MAC(ptr+10);
1120  cbs->Handle80211( *this, fc, MAC::null, MAC::null, hdr.ra, MAC::null, ptr, len);
1121  cbs->Handle80211CtrlCFEnd( *this, &hdr);
1122  break;
1123  }
1124  case CTRL_END_ACK: {
1125  ctrl_end_ack_t hdr;
1126  hdr.fc = fc;
1127  hdr.duration = du;
1128  hdr.ra = MAC::ether2MAC(ptr+4);
1129  hdr.bssid = MAC::ether2MAC(ptr+10);
1130  cbs->Handle80211( *this, fc, MAC::null, MAC::null, hdr.ra, MAC::null, ptr, len);
1131  cbs->Handle80211CtrlEndAck( *this, &hdr);
1132  break;
1133  }
1134  default: {
1135  cbs->Handle80211( *this, fc, MAC::null, MAC::null, MAC::null, MAC::null, ptr, len);
1136  cbs->Handle80211Unknown( *this, fc, ptr, len);
1137  return -1;
1138  //add the case statements for QoS control frames once ieee802_11.h is updated
1139  }
1140  }
1141  return 0;
1142 }
1143 
1144 #ifndef roundup2
1145 #define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
1146 #endif
1147 
1148 void WifiPacket::handle_80211(const u_char * pkt, size_t len /* , int pad */)
1149 {
1150  if (debug) std::cerr << "handle_80211(len= " << len << " ";
1151  if (len < 2) {
1152  cbs->Handle80211( *this, 0, MAC::null, MAC::null, MAC::null, MAC::null, pkt, len);
1153  cbs->Handle80211Unknown( *this, -1, pkt, len);
1154  return;
1155  }
1156 
1157  u_int16_t fc = EXTRACT_LE_16BITS(pkt); //frame control
1158  size_t hdrlen = extract_header_length(fc);
1159  /*
1160  if (pad) {
1161  hdrlen = roundup2(hdrlen, 4);
1162  }
1163  */
1164 
1165  if (debug) std::cerr << "FC_TYPE(fc)= " << FC_TYPE(fc) << " ";
1166 
1167  if (len < IEEE802_11_FC_LEN || len < hdrlen) {
1168  cbs->Handle80211Unknown( *this, fc, pkt, len);
1169  return;
1170  }
1171 
1172  /* Always calculate the frame checksum, but only process the packets if the FCS or if we are ignoring it */
1173  if (len >= hdrlen + 4) {
1174  // assume fcs is last 4 bytes (?)
1175  u_int32_t fcs_sent = EXTRACT_32BITS(pkt+len-4);
1176  u_int32_t fcs = crc32_802(pkt, len-4);
1177 
1178  /*
1179  if (fcs != fcs_sent) {
1180  cerr << "bad fcs: ";
1181  fprintf (stderr, "%08x != %08x\n", fcs_sent, fcs);
1182  }
1183  */
1184 
1185  fcs_ok = (fcs == fcs_sent);
1186  }
1187  if (cbs->Check80211FCS(*this) && fcs_ok==false){
1188  cbs->Handle80211Unknown(*this,fc,pkt,len);
1189  return;
1190  }
1191 
1192 
1193  // fill in current_frame: type, sn
1194  switch (FC_TYPE(fc)) {
1195  case T_MGMT:
1196  if(decode_mgmt_frame(pkt, len, fc, hdrlen)<0)
1197  return;
1198  break;
1199  case T_DATA:
1200  if(decode_data_frame(pkt, len, fc)<0)
1201  return;
1202  break;
1203  case T_CTRL:
1204  if(decode_ctrl_frame(pkt, len, fc)<0)
1205  return;
1206  break;
1207  default:
1208  cbs->Handle80211( *this, fc, MAC::null, MAC::null, MAC::null, MAC::null, pkt, len);
1209  cbs->Handle80211Unknown( *this, fc, pkt, len);
1210  return;
1211  }
1212 }
1213 
1214 int WifiPacket::print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad, radiotap_hdr *hdr)
1215 {
1216  union {
1217  int8_t i8;
1218  u_int8_t u8;
1219  int16_t i16;
1220  u_int16_t u16;
1221  u_int32_t u32;
1222  u_int64_t u64;
1223  } u, u2, u3;
1224  int rc;
1225 
1226  switch (bit) {
1228  rc = cpack_uint8(s, &u.u8);
1229  if (u.u8 & IEEE80211_RADIOTAP_F_DATAPAD)
1230  *pad = 1;
1231  break;
1236  rc = cpack_uint8(s, &u.u8);
1237  break;
1240  rc = cpack_int8(s, &u.i8);
1241  break;
1243  rc = cpack_uint16(s, &u.u16);
1244  if (rc != 0)
1245  break;
1246  rc = cpack_uint16(s, &u2.u16);
1247  break;
1251  rc = cpack_uint16(s, &u.u16);
1252  break;
1254  rc = cpack_uint8(s, &u.u8);
1255  break;
1257  rc = cpack_int8(s, &u.i8);
1258  break;
1260  rc = cpack_uint64(s, &u.u64);
1261  break;
1263  rc = cpack_uint16(s, &u.u16);
1264  break;
1266  rc = cpack_uint16(s, &u.u16);
1267  break;
1269  rc = cpack_uint8(s, &u.u8);
1270  break;
1272  rc = cpack_uint8(s, &u.u8);
1273  break;
1274  // simson add follows:
1276  rc = cpack_uint8(s, &u.u8); // simson guess
1277  break;
1279  rc = cpack_uint8(s, &u.u8) || cpack_uint8(s, &u2.u8) || cpack_uint8(s, &u3.u8); // simson guess
1280  break;
1281  // simson end
1282  default:
1283  /* this bit indicates a field whose
1284  * size we do not know, so we cannot
1285  * proceed.
1286  */
1287  //printf("[0x%08x] ", bit);
1288  fprintf(stderr, "wifipcap: unknown radiotap bit: %d (%d)\n", bit,IEEE80211_RADIOTAP_XCHANNEL);
1289  return -1 ;
1290  }
1291 
1292  if (rc != 0) {
1293  //printf("[|802.11]");
1294  fprintf(stderr, "wifipcap: truncated radiotap header for bit: %d\n", bit);
1295  return rc ;
1296  }
1297 
1298  switch (bit) {
1300  //printf("%u MHz ", u.u16);
1301  if (u2.u16 != 0)
1302  //printf("(0x%04x) ", u2.u16);
1303  hdr->has_channel = true;
1304  hdr->channel = u2.u16;
1305  break;
1307  //printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
1308  hdr->has_fhss = true;
1309  hdr->fhss_fhset = u.u16 & 0xff;
1310  hdr->fhss_fhpat = (u.u16 >> 8) & 0xff;
1311  break;
1313  //PRINT_RATE("", u.u8, " Mb/s ");
1314  hdr->has_rate = true;
1315  hdr->rate = u.u8;
1316  break;
1318  //printf("%ddB signal ", u.i8);
1319  hdr->has_signal_dbm = true;
1320  hdr->signal_dbm = u.i8;
1321  break;
1323  //printf("%ddB noise ", u.i8);
1324  hdr->has_noise_dbm = true;
1325  hdr->noise_dbm = u.i8;
1326  break;
1328  //printf("%ddB signal ", u.u8);
1329  hdr->has_signal_db = true;
1330  hdr->signal_db = u.u8;
1331  break;
1333  //printf("%ddB noise ", u.u8);
1334  hdr->has_noise_db = true;
1335  hdr->noise_db = u.u8;
1336  break;
1338  //printf("%u sq ", u.u16);
1339  hdr->has_quality = true;
1340  hdr->quality = u.u16;
1341  break;
1343  //printf("%d tx power ", -(int)u.u16);
1344  hdr->has_txattenuation = true;
1345  hdr->txattenuation = -(int)u.u16;
1346  break;
1348  //printf("%ddB tx power ", -(int)u.u8);
1349  hdr->has_txattenuation_db = true;
1350  hdr->txattenuation_db = -(int)u.u8;
1351  break;
1353  //printf("%ddBm tx power ", u.i8);
1354  hdr->has_txpower_dbm = true;
1355  hdr->txpower_dbm = u.i8;
1356  break;
1358  hdr->has_flags = true;
1359  if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
1360  //printf("cfp ");
1361  hdr->flags_cfp = true;
1362  if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
1363  //printf("short preamble ");
1364  hdr->flags_short_preamble = true;
1365  if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
1366  //printf("wep ");
1367  hdr->flags_wep = true;
1368  if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
1369  //printf("fragmented ");
1370  hdr->flags_fragmented = true;
1371  if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
1372  //printf("bad-fcs ");
1373  hdr->flags_badfcs = true;
1374  break;
1376  //printf("antenna %d ", u.u8);
1377  hdr->has_antenna = true;
1378  hdr->antenna = u.u8;
1379  break;
1381  //printf("%" PRIu64 "us tsft ", u.u64);
1382  hdr->has_tsft = true;
1383  hdr->tsft = u.u64;
1384  break;
1386  hdr->has_rxflags = true;
1387  hdr->rxflags = u.u16;
1388  break;
1390  hdr->has_txflags = true;
1391  hdr->txflags = u.u16;
1392  break;
1394  hdr->has_rts_retries = true;
1395  hdr->rts_retries = u.u8;
1396  break;
1398  hdr->has_data_retries = true;
1399  hdr->data_retries = u.u8;
1400  break;
1401  }
1402  return 0 ;
1403 }
1404 
1405 
1406 
1407 void WifiPacket::handle_radiotap(const u_char *p,size_t caplen)
1408 {
1409 #define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
1410 #define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
1411 #define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
1412 #define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
1413 #define BITNO_2(x) (((x) & 2) ? 1 : 0)
1414 #define BIT(n) (1 << n)
1415 #define IS_EXTENDED(__p) (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
1416 
1417  // If caplen is too small, just give it a try and carry on.
1418  if (caplen < sizeof(struct ieee80211_radiotap_header)) {
1419  cbs->HandleRadiotap( *this, NULL, p, caplen);
1420  return;
1421  }
1422 
1423  struct ieee80211_radiotap_header *hdr = (struct ieee80211_radiotap_header *)p;
1424 
1425  size_t len = EXTRACT_LE_16BITS(&hdr->it_len); // length of radiotap header
1426 
1427  if (caplen < len) {
1428  //printf("[|802.11]");
1429  cbs->HandleRadiotap( *this, NULL, p, caplen);
1430  return;// caplen;
1431  }
1432  uint32_t *last_presentp=0;
1433  for (last_presentp = &hdr->it_present;
1434  IS_EXTENDED(last_presentp) && (u_char*)(last_presentp + 1) <= p + len;
1435  last_presentp++){
1436  }
1437 
1438  /* are there more bitmap extensions than bytes in header? */
1439  if (IS_EXTENDED(last_presentp)) {
1440  //printf("[|802.11]");
1441  cbs->HandleRadiotap( *this, NULL, p, caplen);
1442  return;// caplen;
1443  }
1444 
1445  const u_char *iter = (u_char*)(last_presentp + 1);
1446  struct cpack_state cpacker;
1447 
1448 
1449  /* Handle malformed data */
1450  if ((ssize_t)(len - (iter - p)) <= 0) {
1451  cbs->HandleRadiotap( *this, NULL, p, caplen);
1452  return;// caplen;
1453  }
1454 
1455  if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
1456  /* XXX */
1457  //printf("[|802.11]");
1458  cbs->HandleRadiotap( *this, NULL, p, caplen);
1459  return;// caplen;
1460  }
1461 
1462  radiotap_hdr ohdr;
1463  memset(&ohdr, 0, sizeof(ohdr));
1464 
1465  /* Assume no Atheros padding between 802.11 header and body */
1466  int pad = 0;
1467  uint32_t *presentp;
1468  int bit0=0;
1469  for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
1470  presentp++, bit0 += 32) {
1471 
1472  u_int32_t present, next_present;
1473  for (present = EXTRACT_LE_32BITS(presentp); present;
1474  present = next_present) {
1475  /* clear the least significant bit that is set */
1476  next_present = present & (present - 1);
1477 
1478  /* extract the least significant bit that is set */
1480  (bit0 + BITNO_32(present ^ next_present));
1481 
1482  /* print the next radiotap field */
1483  int r = print_radiotap_field(&cpacker, bit, &pad, &ohdr);
1484 
1485  /* If we got an error, break both loops */
1486  if(r!=0) goto done;
1487  }
1488  }
1489 done:;
1490  cbs->HandleRadiotap( *this, &ohdr, p, caplen);
1491  //return len + ieee802_11_print(p + len, length - len, caplen - len, pad);
1492 #undef BITNO_32
1493 #undef BITNO_16
1494 #undef BITNO_8
1495 #undef BITNO_4
1496 #undef BITNO_2
1497 #undef BIT
1498  handle_80211(p+len, caplen-len);
1499 }
1500 
1501 void WifiPacket::handle_prism(const u_char *pc, size_t len)
1502 {
1503  prism2_pkthdr hdr;
1504 
1505  /* get the fields */
1506  if (len>=144){
1507  hdr.host_time = EXTRACT_LE_32BITS(pc+32);
1508  hdr.mac_time = EXTRACT_LE_32BITS(pc+44);
1509  hdr.channel = EXTRACT_LE_32BITS(pc+56);
1510  hdr.rssi = EXTRACT_LE_32BITS(pc+68);
1511  hdr.sq = EXTRACT_LE_32BITS(pc+80);
1512  hdr.signal = EXTRACT_LE_32BITS(pc+92);
1513  hdr.noise = EXTRACT_LE_32BITS(pc+104);
1514  hdr.rate = EXTRACT_LE_32BITS(pc+116)/2;
1515  hdr.istx = EXTRACT_LE_32BITS(pc+128);
1516  cbs->HandlePrism( *this, &hdr, pc + 144, len - 144);
1517  handle_80211(pc+144,len-144);
1518  }
1519 }
1520 
1521 ///////////////////////////////////////////////////////////////////////////////
1522 ///
1523 /// handle_*:
1524 /// handle each of the packet types
1525 ///
1526 
1527 /// 2018-08-02: slg - I'm not sure why this is commented out.
1528 void WifiPacket::handle_ether(const u_char *ptr, size_t len)
1529 {
1530 #if 0
1531  ether_hdr_t hdr;
1532 
1533  hdr.da = MAC::ether2MAC(ptr);
1534  hdr.sa = MAC::ether2MAC(ptr+6);
1535  hdr.type = EXTRACT_16BITS(ptr + 12);
1536 
1537  ptr += 14;
1538  len -= 14;
1539 
1540  cbs->HandleEthernet(*this, &hdr, ptr, len);
1541 
1542  switch (hdr.type) {
1543  case ETHERTYPE_IP:
1544  handle_ip(ptr, len);
1545  return;
1546  case ETHERTYPE_IPV6:
1547  handle_ip6(ptr, len);
1548  return;
1549  case ETHERTYPE_ARP:
1550  handle_arp( ptr, len);
1551  return;
1552  default:
1553  cbs->HandleL2Unknown(*this, hdr.type, ptr, len);
1554  return;
1555  }
1556 #endif
1557 }
1558 
1559 ///////////////////////////////////////////////////////////////////////////////
1560 /* These are all static functions */
1561 #if 0
1562 void Wifipcap::dl_prism(const PcapUserData &data, const struct pcap_pkthdr *header, const u_char * packet)
1563 {
1564  WifipcapCallbacks *cbs = data.cbs;
1565 
1566  if(header->caplen < 144) return; // prism header
1567 
1568  cbs->PacketBegin( packet, header->caplen, header->len);
1569  handle_prism(cbs,packet+144,header->caplen-144);
1570  cbs->PacketEnd();
1571 }
1572 
1573 void Wifipcap::dl_prism(u_char *user, const struct pcap_pkthdr *header, const u_char * packet)
1574 {
1575  PcapUserData *data = reinterpret_cast<PcapUserData *>(user);
1576  Wifipcap::dl_prism(*data,header,packet);
1577 }
1578 #endif
1579 
1580 #if 0
1581 void Wifipcap::dl_ieee802_11_radio(const PcapUserData &data, const struct pcap_pkthdr *header,
1582  const u_char * packet)
1583 {
1584 
1585  data.cbs->PacketBegin( packet, header->caplen, header->len);
1586  handle_radiotap(packet, header->caplen);
1587  data.cbs->PacketEnd();
1588 }
1589 #endif
1590 
1591 void Wifipcap::dl_ieee802_11_radio(const u_char *user, const struct pcap_pkthdr *header, const u_char * packet)
1592 {
1593  const PcapUserData *data = reinterpret_cast<const PcapUserData *>(user);
1594  WifiPacket pkt(data->cbs,data->header_type,header,packet);
1595 
1596  data->cbs->PacketBegin(pkt,packet,header->caplen,header->len);
1597  pkt.handle_radiotap(packet,header->caplen);
1598  data->cbs->PacketEnd(pkt);
1599 
1600  //Wifipcap::dl_ieee802_11_radio(*data,header,packet);
1601 }
1602 
1603 ///////////////////////////////////////////////////////////////////////////////
1604 
1605 /* None of these are used in tcpflow */
1606 
1608 {
1609  if (morefiles.size() < 1){
1610  return false;
1611  }
1612  if (descr) {
1613  pcap_close(descr);
1614  }
1615  Init(morefiles.front(), false);
1616  morefiles.pop_front();
1617  return true;
1618 }
1619 
1620 void Wifipcap::Init(const char *name, bool live) {
1621  if (verbose){
1622  std::cerr << "wifipcap: initializing '" << name << "'" << std::endl;
1623  }
1624 
1625  if (!live) {
1626 #ifdef _WIN32
1627  std::cerr << "Trace replay is unsupported in windows." << std::endl;
1628  exit(1);
1629 #else
1630  // mini hack: handle gziped files since all our traces are in
1631  // this format
1632  int slen = strlen(name);
1633 
1634  bool gzip = !strcmp(name+slen-3, ".gz");
1635  bool bzip = !strcmp(name+slen-4, ".bz2");
1636 
1637  char cmd[256];
1638  char errbuf[256];
1639  if (gzip)
1640  sprintf(cmd, "zcat %s", name);
1641  else if (bzip)
1642  sprintf(cmd, "bzcat %s", name);
1643  else
1644  // using cat here instead of pcap_open or fopen is intentional
1645  // neither of these may be able to handle large files (>2GB files)
1646  // but cat uses the linux routines to allow it to
1647  sprintf(cmd, "cat %s", name);
1648 
1649  FILE *pipe = popen(cmd, "r");
1650  if (pipe == NULL) {
1651  printf("popen(): %s\n", strerror(errno));
1652  exit(1);
1653  }
1654  descr = pcap_fopen_offline(pipe, errbuf);
1655 
1656  if(descr == NULL) {
1657  printf("pcap_open_offline(): %s\n", errbuf);
1658  exit(1);
1659  }
1660 #endif
1661  } else {
1662  char errbuf[256];
1663  descr = pcap_open_live(name,BUFSIZ,1,-1,errbuf);
1664  if(descr == NULL) {
1665  printf("pcap_open_live(): %s\n", errbuf);
1666  exit(1);
1667  }
1668  }
1669 
1671  if (datalink != DLT_PRISM_HEADER && datalink != DLT_IEEE802_11_RADIO && datalink != DLT_IEEE802_11) {
1672  if (datalink == DLT_EN10MB) {
1673  printf("warning: ethernet datalink type: %s\n",
1674  pcap_datalink_val_to_name(datalink));
1675  } else {
1676  printf("warning: unrecognized datalink type: %s\n",
1677  pcap_datalink_val_to_name(datalink));
1678  }
1679  }
1680 }
1681 
1682 
1683 
1684 
1685 /* object-oriented version of pcap callback. Called with the callbacks object,
1686  * the DLT type, the header and the packet.
1687  * This is the main packet processor.
1688  * It records some stats and then dispatches to the appropriate callback.
1689  */
1690 void Wifipcap::handle_packet(WifipcapCallbacks *cbs,int header_type,
1691  const struct pcap_pkthdr *header, const u_char * packet)
1692 {
1693  /* Record start time if we don't have it */
1694  if (startTime == TIME_NONE) {
1695  startTime = header->ts;
1696  lastPrintTime = header->ts;
1697  }
1698  /* Print stats if necessary */
1699  if (header->ts.tv_sec > lastPrintTime.tv_sec + Wifipcap::PRINT_TIME_INTERVAL) {
1700  if (verbose) {
1701  int hours = (header->ts.tv_sec - startTime.tv_sec)/3600;
1702  int days = hours/24;
1703  int left = hours%24;
1704  fprintf(stderr, "wifipcap: %2d days %2d hours, %10" PRId64 " pkts\n",
1705  days, left, packetsProcessed);
1706  }
1707  lastPrintTime = header->ts;
1708  }
1709  packetsProcessed++;
1710 
1711  /* Create the packet object and call the appropriate callbacks */
1712  WifiPacket pkt(cbs,header_type,header,packet);
1713 
1714  /* Notify callback */
1715  cbs->PacketBegin(pkt, packet, header->caplen, header->len);
1716  //int frameLen = header->caplen;
1717  switch(header_type) {
1718  case DLT_PRISM_HEADER:
1719  pkt.handle_prism(packet,header->caplen);
1720  break;
1721  case DLT_IEEE802_11_RADIO:
1722  pkt.handle_radiotap(packet,header->caplen);
1723  break;
1724  case DLT_IEEE802_11:
1725  pkt.handle_80211(packet,header->caplen);
1726  break;
1727  case DLT_EN10MB:
1728  pkt.handle_ether(packet,header->caplen);
1729  break;
1730  default:
1731 #if 0
1732  /// 2018-08-02: slg - I'm also not sure why this is commented out.
1733  // try handling it as default IP assuming framing is ethernet
1734  // (this is for testing)
1735  pkt.handle_ip(packet,header->caplen);
1736 #endif
1737  break;
1738  }
1739  cbs->PacketEnd(pkt);
1740 }
1741 
1742 
1743 /* The raw callback from pcap; jump back into the object-oriented domain */
1744 /* note: u_char *user may not be const according to spec */
1745 void Wifipcap::handle_packet_callback(u_char *user, const struct pcap_pkthdr *header, const u_char * packet)
1746 {
1747  Wifipcap::PcapUserData *data = reinterpret_cast<Wifipcap::PcapUserData *>(user);
1748  data->wcap->handle_packet(data->cbs,data->header_type,header,packet);
1749 }
1750 
1751 
1752 const char *Wifipcap::SetFilter(const char *filter)
1753 {
1754  struct bpf_program fp;
1755 #ifdef PCAP_NETMASK_UNKNOWN
1756  bpf_u_int32 netp=PCAP_NETMASK_UNKNOWN;
1757 #else
1758  bpf_u_int32 netp=0;
1759 #endif
1760 
1761 
1762  if(pcap_compile(descr,&fp,(char *)filter,0,netp) == -1) {
1763  return "Error calling pcap_compile";
1764  }
1765 
1766  if(pcap_setfilter(descr,&fp) == -1) {
1767  return "Error setting filter";
1768  }
1769 
1770  return NULL;
1771 }
1772 
1773 
1774 void Wifipcap::Run(WifipcapCallbacks *cbs, int maxpkts)
1775 {
1776  /* NOTE: This needs to be fixed so that the correct handle_packet is called */
1777 
1778  packetsProcessed = 0;
1779 
1780  do {
1781  PcapUserData data(this,cbs,DLT_IEEE802_11_RADIO);
1782  pcap_loop(descr, maxpkts > 0 ? maxpkts - packetsProcessed : 0,
1783  Wifipcap::handle_packet_callback, reinterpret_cast<u_char *>(&data));
1784  } while ( InitNext() );
1785 }
1786 
1787 
1788 ///////////////////////////////////////////////////////////////////////////////
1789 
TimeVal TIME_NONE
Definition: TimeVal.cpp:41
static const char * MgmtAuthAlg2Txt(uint v)
Definition: wifipcap.cpp:482
static const char * MgmtReasonCode2Txt(uint v)
Definition: wifipcap.cpp:488
static const char * MgmtStatusCode2Txt(uint v)
Definition: wifipcap.cpp:485
static void handle_packet_callback(u_char *user, const struct pcap_pkthdr *header, const u_char *packet)
Definition: wifipcap.cpp:1745
const char * SetFilter(const char *filter)
Definition: wifipcap.cpp:1752
int datalink
Definition: wifipcap.h:821
bool verbose
Definition: wifipcap.h:825
uint64_t packetsProcessed
Definition: wifipcap.h:828
static const int PRINT_TIME_INTERVAL
Definition: wifipcap.h:829
std::list< const char * > morefiles
Definition: wifipcap.h:822
void Run(WifipcapCallbacks *cbs, int maxpkts=0)
Definition: wifipcap.cpp:1774
bool InitNext()
Definition: wifipcap.cpp:1607
void dl_prism(const PcapUserData &data, const struct pcap_pkthdr *header, const u_char *packet)
struct timeval startTime
Definition: wifipcap.h:826
void dl_ieee802_11_radio(const PcapUserData &data, const struct pcap_pkthdr *header, const u_char *packet)
void Init(const char *name, bool live)
Definition: wifipcap.cpp:1620
void handle_packet(WifipcapCallbacks *cbs, int header_type, const struct pcap_pkthdr *header, const u_char *packet)
Definition: wifipcap.cpp:1690
struct timeval lastPrintTime
Definition: wifipcap.h:827
pcap_t * descr
Definition: wifipcap.h:820
int cpack_init(struct cpack_state *cs, u_int8_t *buf, size_t buflen)
Definition: cpack.cpp:68
int cpack_uint64(struct cpack_state *cs, u_int64_t *u)
Definition: cpack.cpp:81
int cpack_uint16(struct cpack_state *cs, u_int16_t *u)
Definition: cpack.cpp:113
int cpack_uint8(struct cpack_state *cs, u_int8_t *u)
Definition: cpack.cpp:129
int cpack_int8(struct cpack_state *s, int8_t *p)
Definition: cpack.h:50
#define ETHERTYPE_8021Q
Definition: ethertype.h:104
#define ETHERTYPE_ATALK
Definition: ethertype.h:98
#define ETHERTYPE_LANBRIDGE
Definition: ethertype.h:83
#define ETHERTYPE_ISO
Definition: ethertype.h:143
#define ETHERTYPE_PPPOED
Definition: ethertype.h:125
#define ETHERTYPE_MPLS
Definition: ethertype.h:119
#define ETHERTYPE_GRE_ISO
Definition: ethertype.h:44
#define ETHERTYPE_DECDNS
Definition: ethertype.h:86
#define ETHERTYPE_DN
Definition: ethertype.h:74
#define ETHERTYPE_SLOW
Definition: ethertype.h:116
#define ETHERTYPE_MOPRC
Definition: ethertype.h:71
#define ETHERTYPE_PPP
Definition: ethertype.h:113
#define ETHERTYPE_VEXP
Definition: ethertype.h:92
#define ETHERTYPE_VPROD
Definition: ethertype.h:95
#define ETHERTYPE_MPLS_MULTI
Definition: ethertype.h:122
#define ETHERTYPE_VMAN
Definition: ethertype.h:140
#define ETHERTYPE_MOPDL
Definition: ethertype.h:68
#define ETHERTYPE_DECDTS
Definition: ethertype.h:89
#define ETHERTYPE_PPPOES
Definition: ethertype.h:128
#define ETHERTYPE_LAT
Definition: ethertype.h:77
#define ETHERTYPE_EAPOL
Definition: ethertype.h:134
#define ETHERTYPE_JUMBO
Definition: ethertype.h:131
#define ETHERTYPE_NS
Definition: ethertype.h:59
#define ETHERTYPE_SCA
Definition: ethertype.h:80
#define EXTRACT_LE_32BITS(p)
Definition: extract.h:117
#define EXTRACT_LE_16BITS(p)
Definition: extract.h:114
#define EXTRACT_24BITS(p)
Definition: extract.h:104
#define EXTRACT_32BITS(p)
Definition: extract.h:97
#define EXTRACT_16BITS(p)
Definition: extract.h:95
#define EXTRACT_LE_8BITS(p)
Definition: extract.h:113
static int debug
#define ETHERTYPE_PUP
#define ETHERTYPE_REVARP
#define ETHERTYPE_ARP
#define ETHERTYPE_LOOPBACK
#define ETHERTYPE_AARP
#define ETHERTYPE_SPRITE
#define ETHERTYPE_IPV6
#define ETHERTYPE_IPX
#define ETHERTYPE_IP
const char * name
Definition: http_parser.c:465
#define IEEE80211_RADIOTAP_F_CFP
#define IEEE80211_RADIOTAP_F_DATAPAD
#define IEEE80211_RADIOTAP_F_SHORTPRE
#define IEEE80211_RADIOTAP_F_BADFCS
#define IEEE80211_RADIOTAP_F_WEP
ieee80211_radiotap_type
@ IEEE80211_RADIOTAP_DB_TX_ATTENUATION
@ IEEE80211_RADIOTAP_DATA_RETRIES
@ IEEE80211_RADIOTAP_DBM_TX_POWER
@ IEEE80211_RADIOTAP_TX_FLAGS
@ IEEE80211_RADIOTAP_RTS_RETRIES
@ IEEE80211_RADIOTAP_MCS
@ IEEE80211_RADIOTAP_LOCK_QUALITY
@ IEEE80211_RADIOTAP_CHANNEL
@ IEEE80211_RADIOTAP_FLAGS
@ IEEE80211_RADIOTAP_TX_ATTENUATION
@ IEEE80211_RADIOTAP_DB_ANTNOISE
@ IEEE80211_RADIOTAP_DB_ANTSIGNAL
@ IEEE80211_RADIOTAP_TSFT
@ IEEE80211_RADIOTAP_XCHANNEL
@ IEEE80211_RADIOTAP_RATE
@ IEEE80211_RADIOTAP_FHSS
@ IEEE80211_RADIOTAP_DBM_ANTNOISE
@ IEEE80211_RADIOTAP_ANTENNA
@ IEEE80211_RADIOTAP_DBM_ANTSIGNAL
@ IEEE80211_RADIOTAP_RX_FLAGS
#define IEEE80211_RADIOTAP_F_FRAG
unsigned int uint32_t
Definition: core.h:40
#define ETHERTYPE_TRAIL
Definition: net_ethernet.h:76
#define OUI_CISCO_90
Definition: oui.h:26
#define OUI_ENCAP_ETHER
Definition: oui.h:23
pcap_t * pcap_open_live(const char *, int, int, int, char *)
Definition: pcap_fake.cpp:65
int pcap_datalink(pcap_t *p)
Definition: pcap_fake.cpp:159
int pcap_compile(pcap_t *p, struct bpf_program *program, const char *expression, int optimize, uint32_t mask)
Definition: pcap_fake.cpp:150
int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, uint8_t *user)
Definition: pcap_fake.cpp:169
pcap_t * pcap_fopen_offline(FILE *fp, char *errbuf)
Definition: pcap_fake.cpp:87
void pcap_close(pcap_t *p)
Definition: pcap_fake.cpp:218
int pcap_setfilter(pcap_t *p, struct bpf_program *prog)
Definition: pcap_fake.cpp:163
#define DLT_EN10MB
Definition: pcap_fake.h:69
Definition: wifipcap.h:118
@ PRINT_FMT_COLON
Definition: wifipcap.h:119
static MAC ether2MAC(const uint8_t *ether)
Definition: wifipcap.h:157
uint64_t val
Definition: wifipcap.h:120
static MAC null
Definition: wifipcap.h:162
static MAC broadcast
Definition: wifipcap.h:161
static int print_fmt
Definition: wifipcap.h:163
void handle_llc(const mac_hdr_t &hdr, const u_char *ptr, size_t len, u_int16_t fc)
Definition: wifipcap.cpp:380
int handle_reassoc_request(const struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:727
int handle_auth(const struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:845
int handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:895
int handle_assoc_request(const struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:667
void handle_80211(const u_char *ptr, size_t len)
Definition: wifipcap.cpp:1148
int decode_data_frame(const u_char *ptr, size_t len, u_int16_t fc)
Definition: wifipcap.cpp:1005
int handle_beacon(const struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:637
void handle_prism(const u_char *ptr, size_t len)
Definition: wifipcap.cpp:1501
void handle_ip(const u_char *ptr, size_t len)
int print_radiotap_field(struct cpack_state *s, u_int32_t bit, int *pad, radiotap_hdr *hdr)
Definition: wifipcap.cpp:1214
WifipcapCallbacks * cbs
Definition: wifipcap.h:597
void handle_wep(const u_char *ptr, size_t len)
Definition: wifipcap.cpp:418
void handle_ether(const u_char *ptr, size_t len)
2018-08-02: slg - I'm not sure why this is commented out.
Definition: wifipcap.cpp:1528
int decode_mgmt_body(u_int16_t fc, struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:937
int handle_reassoc_response(const struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:756
static int debug
Definition: wifipcap.h:564
int handle_probe_request(const struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:763
int handle_atim(const struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:813
void handle_radiotap(const u_char *ptr, size_t caplen)
Definition: wifipcap.cpp:1407
int handle_probe_response(const struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:782
int handle_disassoc(const struct mgmt_header_t *pmh, const u_char *p, size_t len)
Definition: wifipcap.cpp:823
int decode_ctrl_frame(const u_char *ptr, size_t len, u_int16_t fc)
Definition: wifipcap.cpp:1071
void parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset, size_t len)
Definition: wifipcap.cpp:497
int decode_mgmt_frame(const u_char *ptr, size_t len, u_int16_t fc, u_int8_t hdrlen)
Definition: wifipcap.cpp:977
int handle_assoc_response(const struct mgmt_header_t *pmh, const u_char *p, size_t len, bool reassoc=false)
Definition: wifipcap.cpp:692
virtual void HandleWEP(const WifiPacket &p, const struct wep_hdr_t *hdr, const u_char *rest, size_t len)
Definition: wifipcap.h:690
virtual void HandleLLCUnknown(const WifiPacket &p, const u_char *rest, size_t len)
Definition: wifipcap.h:689
virtual void PacketBegin(const WifiPacket &p, const u_char *pkt, size_t len, int origlen)
Definition: wifipcap.h:624
virtual void HandleLLC(const WifiPacket &p, const struct llc_hdr_t *hdr, const u_char *rest, size_t len)
Definition: wifipcap.h:688
virtual void PacketEnd(const WifiPacket &p)
Definition: wifipcap.h:625
const int header_type
Definition: wifipcap.h:802
class Wifipcap * wcap
Definition: wifipcap.h:800
struct WifipcapCallbacks * cbs
Definition: wifipcap.h:801
u_int8_t text[254]
Definition: wifipcap.h:190
u_int8_t length
Definition: wifipcap.h:189
u_int16_t duration
Definition: wifipcap.h:270
u_int16_t fc
Definition: wifipcap.h:268
u_int16_t fc
Definition: wifipcap.h:258
u_int16_t duration
Definition: wifipcap.h:260
u_int16_t duration
Definition: wifipcap.h:304
u_int16_t fc
Definition: wifipcap.h:302
u_int16_t fc
Definition: wifipcap.h:291
MAC bssid
Definition: wifipcap.h:294
u_int16_t duration
Definition: wifipcap.h:292
u_int16_t aid
Definition: wifipcap.h:280
u_int16_t fc
Definition: wifipcap.h:278
u_int16_t duration
Definition: wifipcap.h:502
u_int16_t fc
Definition: wifipcap.h:501
MAC sa
Definition: ether.h:3
MAC da
Definition: ether.h:3
uint16_t type
Definition: ether.h:4
Definition: ip.h:50
Definition: llc.h:125
uint8_t ssap
Definition: llc.h:127
uint8_t dsap
Definition: llc.h:126
uint8_t control
Definition: llc.h:128
uint16_t oui
Definition: llc.h:129
uint16_t type
Definition: llc.h:130
MAC da
Definition: wifipcap.h:323
uint8_t frag
Definition: wifipcap.h:322
bool qos
Definition: wifipcap.h:328
uint16_t duration
Definition: wifipcap.h:319
uint16_t fc
Definition: wifipcap.h:318
uint16_t seq
Definition: wifipcap.h:321
MAC ra
Definition: wifipcap.h:326
MAC bssid
Definition: wifipcap.h:327
MAC ta
Definition: wifipcap.h:325
MAC sa
Definition: wifipcap.h:324
uint16_t seq_ctl
Definition: wifipcap.h:320
struct ds_t ds
Definition: wifipcap.h:490
u_int8_t timestamp[8]
Definition: wifipcap.h:471
u_int16_t auth_trans_seq_num
Definition: wifipcap.h:481
struct tim_t tim
Definition: wifipcap.h:496
struct cf_t cf
Definition: wifipcap.h:492
struct challenge_t challenge
Definition: wifipcap.h:483
u_int16_t capability_info
Definition: wifipcap.h:484
u_int16_t listen_interval
Definition: wifipcap.h:475
u_int16_t status_code
Definition: wifipcap.h:476
elem_status_t rates_status
Definition: wifipcap.h:487
elem_status_t cf_status
Definition: wifipcap.h:491
elem_status_t tim_status
Definition: wifipcap.h:495
u_int16_t beacon_interval
Definition: wifipcap.h:474
elem_status_t ds_status
Definition: wifipcap.h:489
u_int16_t aid
Definition: wifipcap.h:477
u_int16_t auth_alg
Definition: wifipcap.h:480
elem_status_t challenge_status
Definition: wifipcap.h:482
u_char ap[6]
Definition: wifipcap.h:478
u_int16_t reason_code
Definition: wifipcap.h:479
elem_status_t ssid_status
Definition: wifipcap.h:485
struct ssid_t ssid
Definition: wifipcap.h:486
struct rates_t rates
Definition: wifipcap.h:488
u_int8_t frag
Definition: wifipcap.h:463
u_int16_t seq
Definition: wifipcap.h:462
u_int16_t duration
Definition: wifipcap.h:458
uint32_t caplen
Definition: pcap_fake.h:37
struct timeval ts
Definition: pcap_fake.h:36
uint32_t len
Definition: pcap_fake.h:38
u_int32_t istx
Definition: prism.h:44
u_int32_t rssi
Definition: prism.h:39
u_int32_t mac_time
Definition: prism.h:37
int noise
Definition: prism.h:42
u_int32_t sq
Definition: prism.h:40
u_int32_t rate
Definition: prism.h:43
u_int32_t channel
Definition: prism.h:38
int signal
Definition: prism.h:41
u_int32_t host_time
Definition: prism.h:36
int signal_dbm
Definition: radiotap.h:19
bool has_signal_dbm
Definition: radiotap.h:18
int txpower_dbm
Definition: radiotap.h:40
bool has_rate
Definition: radiotap.h:15
int txflags
Definition: radiotap.h:59
bool has_tsft
Definition: radiotap.h:52
int antenna
Definition: radiotap.h:50
bool has_flags
Definition: radiotap.h:42
bool has_fhss
Definition: radiotap.h:11
int fhss_fhpat
Definition: radiotap.h:13
u_int64_t tsft
Definition: radiotap.h:53
int txattenuation_db
Definition: radiotap.h:37
bool has_noise_dbm
Definition: radiotap.h:21
bool has_antenna
Definition: radiotap.h:49
bool flags_wep
Definition: radiotap.h:45
bool has_txflags
Definition: radiotap.h:58
int noise_dbm
Definition: radiotap.h:22
int rxflags
Definition: radiotap.h:56
int signal_db
Definition: radiotap.h:25
int data_retries
Definition: radiotap.h:65
bool has_rxflags
Definition: radiotap.h:55
int noise_db
Definition: radiotap.h:28
bool has_signal_db
Definition: radiotap.h:24
bool has_txattenuation_db
Definition: radiotap.h:36
int quality
Definition: radiotap.h:31
bool flags_badfcs
Definition: radiotap.h:47
bool has_data_retries
Definition: radiotap.h:64
bool flags_fragmented
Definition: radiotap.h:46
bool flags_short_preamble
Definition: radiotap.h:44
int txattenuation
Definition: radiotap.h:34
int fhss_fhset
Definition: radiotap.h:12
bool has_quality
Definition: radiotap.h:30
bool has_txattenuation
Definition: radiotap.h:33
bool has_channel
Definition: radiotap.h:8
bool has_noise_db
Definition: radiotap.h:27
bool has_txpower_dbm
Definition: radiotap.h:39
int channel
Definition: radiotap.h:9
bool has_rts_retries
Definition: radiotap.h:61
bool flags_cfp
Definition: radiotap.h:43
int rts_retries
Definition: radiotap.h:62
u_int8_t rate[16]
Definition: wifipcap.h:183
u_int8_t length
Definition: wifipcap.h:182
u_int8_t length
Definition: wifipcap.h:175
char ssid[33]
Definition: wifipcap.h:176
u_int8_t count
Definition: wifipcap.h:221
u_int8_t bitmap[251]
Definition: wifipcap.h:224
u_int8_t length
Definition: wifipcap.h:220
Definition: util.h:44
const char * s
Definition: util.h:46
int v
Definition: util.h:45
u_int32_t iv
Definition: wifipcap.h:377
u_int32_t keyid
Definition: wifipcap.h:380
u_int32_t pad
Definition: wifipcap.h:379
unsigned char uint8_t
Definition: util.h:6
#define CRC32_CCITT_SEED
Definition: wifipcap.cpp:297
#define NUM_REASONS
Definition: wifipcap.cpp:480
std::ostream & operator<<(std::ostream &out, const MAC &mac)
Definition: wifipcap.cpp:57
#define IS_EXTENDED(__p)
#define COOK_FRAGMENT_NUMBER(x)
Definition: wifipcap.cpp:137
static uint32_t crc32_ccitt(const uint8_t *buf, size_t len)
Definition: wifipcap.cpp:301
static size_t extract_header_length(u_int16_t fc)
Definition: wifipcap.cpp:346
static const uint32_t crc32_ccitt_table[256]
Definition: wifipcap.cpp:242
#define NUM_STATUSES
Definition: wifipcap.cpp:466
#define COOK_SEQUENCE_NUMBER(x)
Definition: wifipcap.cpp:138
#define TTEST2(_p, _l)
Definition: wifipcap.cpp:495
static uint32_t crc32_802(const unsigned char *buf, size_t len)
Definition: wifipcap.cpp:326
static const char * reason_text[]
Definition: wifipcap.cpp:468
#define BITNO_32(x)
#define pletohs(p)
Definition: wifipcap.cpp:130
static const char * status_text[]
Definition: wifipcap.cpp:443
#define NUM_AUTH_ALGS
Definition: wifipcap.cpp:441
static uint32_t crc32_ccitt_seed(const uint8_t *buf, size_t len, uint32_t seed)
Definition: wifipcap.cpp:306
static const char * auth_alg_text[]
Definition: wifipcap.cpp:440
#define ST_PROBE_REQUEST
Definition: wifipcap.h:62
#define IEEE802_11_AID_LEN
Definition: wifipcap.h:46
#define CTRL_PS_POLL
Definition: wifipcap.h:75
#define FC_WEP(fc)
Definition: wifipcap.h:103
#define ST_ASSOC_RESPONSE
Definition: wifipcap.h:59
#define IEEE802_11_FC_LEN
Definition: wifipcap.h:26
#define E_DS
Definition: wifipcap.h:230
#define E_CF
Definition: wifipcap.h:231
#define E_CHALLENGE
Definition: wifipcap.h:245
#define E_TIM
Definition: wifipcap.h:232
#define FC_FROM_DS(fc)
Definition: wifipcap.h:98
#define ST_DISASSOC
Definition: wifipcap.h:68
#define CTRL_CF_END
Definition: wifipcap.h:79
#define IEEE802_11_CAPINFO_LEN
Definition: wifipcap.h:43
#define T_CTRL
Definition: wifipcap.h:54
#define IV_IV(iv)
Definition: wifipcap.h:312
#define IV_PAD(iv)
Definition: wifipcap.h:313
#define CTRL_CTS_HDRLEN
Definition: wifipcap.h:265
#define T_DATA
Definition: wifipcap.h:55
#define MGMT_HDRLEN
Definition: wifipcap.h:106
#define ST_REASSOC_RESPONSE
Definition: wifipcap.h:61
#define IEEE802_11_LISTENINT_LEN
Definition: wifipcap.h:44
#define CTRL_CTS
Definition: wifipcap.h:77
#define DATA_HDRLEN
Definition: wifipcap.h:367
#define ST_AUTH
Definition: wifipcap.h:69
#define ST_PROBE_RESPONSE
Definition: wifipcap.h:63
#define ST_DEAUTH
Definition: wifipcap.h:70
#define ST_ASSOC_REQUEST
Definition: wifipcap.h:58
#define DATA_WDS_HDRLEN
Definition: wifipcap.h:371
#define IEEE802_11_IV_LEN
Definition: wifipcap.h:34
#define IEEE802_11_AP_LEN
Definition: wifipcap.h:51
#define E_SSID
Definition: wifipcap.h:227
#define CTRL_PS_POLL_HDRLEN
Definition: wifipcap.h:286
#define ST_BEACON
Definition: wifipcap.h:66
#define CTRL_ACK
Definition: wifipcap.h:78
#define IEEE802_11_BCNINT_LEN
Definition: wifipcap.h:42
#define IEEE802_11_REASON_LEN
Definition: wifipcap.h:48
#define IEEE802_11_TSTAMP_LEN
Definition: wifipcap.h:41
#define FC_SUBTYPE(fc)
Definition: wifipcap.h:96
#define CTRL_RTS
Definition: wifipcap.h:76
#define E_RATES
Definition: wifipcap.h:228
#define CTRL_ACK_HDRLEN
Definition: wifipcap.h:275
#define CTRL_END_ACK
Definition: wifipcap.h:80
#define T_MGMT
Definition: wifipcap.h:53
#define IEEE802_11_STATUS_LEN
Definition: wifipcap.h:47
#define CTRL_RTS_HDRLEN
Definition: wifipcap.h:254
#define FC_TYPE(fc)
Definition: wifipcap.h:95
#define IEEE802_11_KID_LEN
Definition: wifipcap.h:35
#define CTRL_END_ACK_HDRLEN
Definition: wifipcap.h:310
#define ST_ATIM
Definition: wifipcap.h:67
#define ST_REASSOC_REQUEST
Definition: wifipcap.h:60
#define IV_KEYID(iv)
Definition: wifipcap.h:314
@ TRUNCATED
Definition: wifipcap.h:169
@ PRESENT
Definition: wifipcap.h:168
@ NOT_PRESENT
Definition: wifipcap.h:167
#define FC_TO_DS(fc)
Definition: wifipcap.h:97
#define CTRL_END_HDRLEN
Definition: wifipcap.h:298