source: libpacketdump/link_4.c @ d0f25d4

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivendag_formatrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since d0f25d4 was ee6e802, checked in by Shane Alcock <salcock@…>, 5 years ago

Updated copyright blurb on all source files

In some cases, this meant adding copyright blurbs to files that
had never had them before.

  • Property mode set to 100644
File size: 26.0 KB
Line 
1/*
2 *
3 * Copyright (c) 2007-2016 The University of Waikato, Hamilton, New Zealand.
4 * All rights reserved.
5 *
6 * This file is part of libtrace.
7 *
8 * This code has been developed by the University of Waikato WAND
9 * research group. For further information please see http://www.wand.net.nz/
10 *
11 * libtrace is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * libtrace is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23 *
24 *
25 */
26/*
27 * 802.11 libpacketdump decoder
28 *
29 * Originally based on "wagdump" (c) 2005 Dean Armstrong
30 *
31 * This decoder will attempt to do it's best at decoding the frame formats
32 * defined in the following standards. Not all fields are decoded, but they
33 * are at least acknowledged as being present.
34 *
35 *  802.11
36 *  802.11b
37 *  802.11d - operation in multiple regulatory domains
38 *  802.11e - wireless multimedia extensions
39 *  802.11g
40 *  802.11h - power management
41 *  802.11i - MAC security enhancements
42 *
43 *  It will also attempt to decode vendor specific Information Elements
44 *  if possible.
45 *
46 *  (c) 2006 Scott Raynel <scottraynel@gmail.com>
47 */
48
49#include <sys/types.h>
50#include <netinet/in.h>
51#include <stdio.h>
52#include <inttypes.h>
53#include "libpacketdump.h"
54#include "libtrace.h"
55
56typedef struct ieee80211_frame_control {
57# if __BYTE_ORDER == __LITTLE_ENDIAN   
58        uint8_t         version:2;
59        uint8_t         type:2;
60        uint8_t         subtype:4;
61        uint8_t         to_ds:1;
62        uint8_t         from_ds:1;
63        uint8_t         more_frag:1;
64        uint8_t         retry:1;
65        uint8_t         power:1;
66        uint8_t         more_data:1;
67        uint8_t         wep:1;
68        uint8_t         order:1;
69# elif __BYTE_ORDER == __BIG_ENDIAN
70        uint8_t         subtype:4;
71        uint8_t         type:2;
72        uint8_t         version:2;
73        uint8_t         order:1;
74        uint8_t         wep:1;
75        uint8_t         more_data:1;
76        uint8_t         power:1;
77        uint8_t         retry:1;
78        uint8_t         more_frag:1;
79        uint8_t         from_ds:1;
80        uint8_t         to_ds:1;
81#else
82#       error "Adjust your <bits/endian.h> defines"
83# endif
84} __attribute__ ((__packed__)) ieee80211_frame_control;
85
86typedef struct ieee80211_ctrl_frame_1addr {
87        ieee80211_frame_control ctl;
88        uint16_t     duration;
89        uint8_t      addr1[6];
90} __attribute__ ((__packed__)) ieee80211_ctrl_frame_1addr;
91
92typedef struct ieee80211_ctrl_frame_2addr {
93        ieee80211_frame_control ctl;
94        uint16_t     duration;
95        uint8_t      addr1[6];
96        uint8_t      addr2[6];
97} __attribute__ ((__packed__)) ieee80211_ctrl_frame_2addr;
98
99typedef struct ieee80211_data_frame_3 {
100        ieee80211_frame_control ctl;
101        uint16_t        duration;
102        uint8_t         addr1[6];
103        uint8_t         addr2[6];
104        uint8_t         addr3[6];
105        uint16_t        seq_ctrl;
106} __attribute__ ((__packed__)) ieee80211_data_frame_3;
107
108typedef struct ieee80211_data_frame {
109        ieee80211_frame_control ctl;
110        uint16_t        duration;
111        uint8_t         addr1[6];
112        uint8_t         addr2[6];
113        uint8_t         addr3[6];
114        uint16_t        seq_ctrl;
115        uint8_t         addr4[6];
116} __attribute__ ((__packed__)) ieee80211_data_frame;
117
118typedef struct ieee80211_qos_data_frame {
119        ieee80211_frame_control ctl;
120        uint16_t        duration;
121        uint8_t         addr1[6];
122        uint8_t         addr2[6];
123        uint8_t         addr3[6];
124        uint16_t        seq_ctrl;
125        uint8_t         addr4[6];
126        uint16_t        qos;
127} __attribute__ ((__packed__)) ieee80211_qos_data_frame;
128
129typedef struct ieee80211_mgmt_frame {
130        ieee80211_frame_control ctl;
131        uint16_t        duration;
132        uint8_t         addr1[6];
133        uint8_t         addr2[6];
134        uint8_t         addr3[6];
135        uint16_t        seq_ctrl;
136} __attribute__ ((__packed__)) ieee80211_mgmt_frame;
137
138typedef struct ieee80211_payload {
139        uint16_t        ethertype;
140        uint8_t         payload[1];
141} __attribute__ ((__packed__)) ieee80211_payload;
142
143static char *macaddr(uint8_t mac[]) {
144        static char ether_buf[18] = {0, };
145        trace_ether_ntoa(mac, ether_buf);
146        return ether_buf;
147}
148
149typedef struct ieee80211_capinfo {
150#if __BYTE_ORDER == __LITTLE_ENDIAN
151        uint8_t ess:1;
152        uint8_t ibss:1;
153        uint8_t cf_pollable:1;
154        uint8_t cf_poll_req:1;
155        uint8_t privacy:1;
156        uint8_t short_preamble:1;
157        uint8_t pbcc:1;
158        uint8_t channel_agility:1;
159        uint8_t spectrum_mgmt:1;
160        uint8_t qos:1;
161        uint8_t short_slot_time:1;
162        uint8_t apsd:1;
163        uint8_t res1:1;
164        uint8_t dsss_ofdm:1;
165        uint8_t delayed_block_ack:1;
166        uint8_t immediate_block_ack:1;
167#elif __BYTE_ORDER == __BIG_ENDIAN
168        uint8_t channel_agility:1;
169        uint8_t pbcc:1;
170        uint8_t short_preamble:1;
171        uint8_t privacy:1;
172        uint8_t cf_poll_req:1;
173        uint8_t cf_pollable:1;
174        uint8_t ibss:1;
175        uint8_t ess:1;
176        uint8_t immediate_block_ack:1;
177        uint8_t delayed_block_ack:1;
178        uint8_t dsss_ofdm:1;
179        uint8_t res1:1;
180        uint8_t apsd:1;
181        uint8_t short_slot_time:1;
182        uint8_t qos:1;
183        uint8_t spectrum_mgmt:1;
184#else
185# error "Unknown byte order -- please check <bits/endian.h>"
186#endif
187} __attribute__ ((__packed__)) ieee80211_capinfo;
188
189typedef struct ieee80211_beacon {
190        ieee80211_mgmt_frame mgmt;
191        uint64_t        ts;
192        uint16_t        interval;
193        ieee80211_capinfo capinfo;
194} __attribute__ ((__packed__)) ieee80211_beacon;
195
196typedef struct ieee80211_assoc_req { 
197        ieee80211_mgmt_frame mgmt;
198        ieee80211_capinfo capinfo;
199        uint16_t        listen_interval;
200} __attribute__ ((__packed__)) ieee80211_assoc_req;
201
202typedef struct ieee80211_assoc_resp {
203        ieee80211_mgmt_frame mgmt;
204        ieee80211_capinfo capinfo;
205        uint16_t        status_code;
206        uint16_t        assoc_id;
207} __attribute__ ((__packed__)) ieee80211_assoc_resp;
208
209typedef struct ieee80211_reassoc_req {
210        ieee80211_mgmt_frame mgmt;
211        ieee80211_capinfo capinfo;
212        uint16_t        listen_interval;
213        uint8_t         current_address[6];
214} __attribute__ ((__packed__)) ieee80211_reassoc_req;
215
216typedef struct ieee80211_auth {
217        ieee80211_mgmt_frame mgmt;
218        uint16_t        auth_algo_num;
219        uint16_t        auth_trans_seq_num;
220        uint16_t        status_code;
221} __attribute__ ((__packed__)) ieee80211_auth;
222
223
224typedef struct ieee80211_ie {
225        uint8_t         id;
226        uint8_t         length;
227} __attribute__ ((__packed__)) ieee80211_ie;
228
229/*
230 * Takes a vendor IE and decodes it
231 */
232static void decode_80211_vendor_ie(ieee80211_ie *ie) {
233        uint8_t *data = (uint8_t *) ((char *)ie + sizeof(ieee80211_ie));
234        uint32_t ie_oui;       
235        printf("  Vendor Private Information Element\n");
236        if (ie->length <= 3) return;
237        ie_oui = (data[0] << 16) | (data[1] << 8) | data[2];
238        switch(ie_oui) {
239                case 0x0050f2:
240                        printf("   Atheros 802.11i/WPA IE\n");
241                        break;
242                case 0x00037f:
243                        printf("   Atheros Advanced Capability IE\n");
244                        break;
245                default:
246                        printf("   Unknown Vendor OUI (0x%06x)\n", ie_oui);
247                        break;
248        }
249
250}
251
252/*
253 * Takes a pointer to the start of the IEs in a beacon and the
254 * length remaining and decodes the IEs.
255 */
256static void decode_80211_information_elements(const char *pkt, unsigned len) {
257        ieee80211_ie *ie;
258        int i = 0;
259        const uint8_t * data;
260        uint8_t bmap_offset;
261        while (len >= sizeof(ieee80211_ie)) {
262                ie = (ieee80211_ie *) pkt;
263               
264                if ( len < ( sizeof(ieee80211_ie) + ie->length)) {
265                        printf("  [Truncated]\n");
266                        return;
267                }
268               
269                data = (( const unsigned char *)pkt + sizeof (ieee80211_ie));
270               
271                switch (ie->id) {
272                        case 0:
273                                printf("  SSID = ");
274                                for (i = 0; i < ie->length; i++) 
275                                        printf("%c", data[i]);
276                                printf("\n");
277                                break;
278                        case 1:
279                                printf("  Supported Rates (Kbit/s):\n   ");
280                                /* NB: the MSB of each field will be set
281                                 * if the rate it describes is part of the
282                                 * basic rate set, hence the AND */
283                                for (i = 0; i < ie->length; i++) {
284                                        printf("%u, ", 
285                                                ( (data[i]&0x7F) * 500));
286
287                                }
288                                printf("%c%c\n", 0x8, 0x8);
289                                break;
290                        case 3:
291                                printf("  DSSS Channel = ");
292                                printf("%u\n", *data);
293                                break;
294                        case 5:
295                                printf("  Traffic Indication Message:\n");
296                                printf("   DTIM Count = %u, ", *data);
297                                data++;
298                                printf("DTIM Period = %u\n", *data);
299                                data++;
300                                printf("   Broadcast/Multicast waiting = %s\n", 
301                                        (*data) & 0x01 ? "Yes\0" : "No\0");
302                                bmap_offset = ((*data) & 0xFE) >> 1;
303                                data++;
304                                if ((ie->length == 4) && ( *data == 0)) {
305                                        printf("   No traffic waiting for stations\n");
306                                        break;
307                                }
308                               
309                                printf("   Traffic waiting for AssocIDs: ");
310                                for (i = 0; i < (ie->length - 3); i++) {
311                                        int j;
312                                        for (j = 0; j < 8; j++) {
313                                                if (data[i] & (1 << j)) {
314                                                        printf("%u ", (bmap_offset + i + 1) * 8 + j);
315                                                }
316                                        }
317                                }               
318                                printf("\n");
319                                               
320                                break;
321                        case 7:
322                                printf("  802.11d Country Information:\n");
323                                printf("   ISO 3166 Country Code: %c%c\n", data[0], data[1]);
324                                printf("   Regulatory Operating Environment: ");
325                                if (data[2] == ' ') printf("Indoor/Outdoor\n");
326                                else if (data[2] == 'O') printf("Outdoor only\n");
327                                else if (data[2] == 'I') printf("Indoor only\n");
328                                else printf("Unknown, code = %c\n", data[2]);
329                                data += sizeof(uint8_t) * 3;
330                                for (i = 0; i < ((ie->length - 3) / 3); i++) {
331                                        printf("   First Channel: %u, Num Channels: %u, Max Tx Power %idBm\n",
332                                                        data[0], data[1], (int8_t) data[2]);
333                                        data += sizeof(uint8_t) * 3;
334                                }
335                               
336                                break;
337                        case 11:
338                                printf("  802.11e QBSS Load\n");
339                                break;
340                        case 12:
341                                printf("  802.11e EDCA Parameter\n");
342                                break;
343                        case 13:
344                                printf("  802.11e TSPEC\n");
345                                break;
346                        case 14:
347                                printf("  802.11e TCLAS\n");
348                                break;
349                        case 15:
350                                printf("  802.11e Schedule\n");
351                                break;
352                        case 16:
353                                printf("  Authentication Challenge Text\n");
354                                break;
355                        case 32:
356                                printf("  802.11h Power Contraint\n");
357                                printf("   Local Power Contraint = %udB\n", data[0]);
358                                break;
359                        case 33:
360                                printf("  802.11h Power Capability\n");
361                                printf("   Minimum Transmit Power Capability = %idBm\n", (int8_t)data[0]);
362                                printf("   Maximum Transmit Power Capability = %idBm\n", (int8_t)data[1]);
363                                break;
364                        case 34:
365                                printf("  802.11h Transmit Power Control Request\n");
366                                break;
367                        case 35:
368                                printf("  802.11h Transmit Power Control Report\n");
369                                printf("   Transmit Power = %idBm\n", (int8_t)data[0]);
370                                printf("   Link Margin = %idB\n", (int8_t)data[1]);
371                                break;
372                        case 36:
373                                printf("  802.11h Supported Channels\n");
374                                for(i = 0; i < (ie->length / 2); i++) {
375                                        printf("   First Channel = %u, Num Channels = %u\n", data[0], data[1]);
376                                        data += 2;
377                                }
378                                break;
379                        case 37:
380                                printf("  802.11h Channel Switch Announcement\n");
381                                printf("   New Channel Number = %u\n", data[1]);
382                                printf("   Target Beacon Transmission Times untill switch = %u\n", data[2]);
383                                if (data[0]) printf("   Don't transmit more frames until switch occurs\n");
384                                break;
385                        case 38:
386                                printf("  802.11h Measurement Request\n");
387                                break;
388                        case 39:
389                                printf("  802.11h Measurement Report\n");
390                                break;
391                        case 40:
392                                printf("  802.11h Quiet\n");
393                                break;
394                        case 41:
395                                printf("  802.11h IBSS DFS\n");
396                                break;
397                        case 42:
398                                printf("  802.11g ERP Information\n");
399                                if(data[0] & 0x80) printf("   NonERP STAs are present in this BSS\n");
400                                if(data[0] & 0x40) printf("   Use Protection Mechanism\n");
401                                if(data[0] & 0x20) printf("   Do not use short preamble\n");
402                                break;
403                        case 43:
404                                printf("  802.11e TS Delay\n");
405                                break;
406                        case 44:
407                                printf("  802.11e TCLAS Processing\n");
408                                break;
409                        case 46:
410                                printf("  802.11e QoS Capability\n");
411                                break;
412                        case 48:
413                                printf("  802.11i RSN:\n");
414                                break;
415                        case 50:
416                                printf("  802.11g Extended Supported Rates (Kbit/s)\n   ");
417                                for(i = 0; i < ie->length; i++) 
418                                        printf("%u, ", data[i] * 500);
419                                printf("%c%c\n", (char) 8, (char) 8);           
420                                break;
421                               
422                        case 221:
423                                decode_80211_vendor_ie(ie);
424                                break;
425                        default:
426                                printf("  Unknown IE Element ID, 0x%02x\n", ie->id);
427                }
428                len -= sizeof(ieee80211_ie) + ie->length;
429                pkt = ((char *)pkt + sizeof(ieee80211_ie) + ie->length);
430        }
431}
432
433static
434void ieee80211_print_reason_code(uint16_t code) {
435        switch (code) {
436                case 0: printf("Reserved"); break;
437                case 1: printf("Unspecified Reason"); break;
438                case 2: printf("Previous authentication no longer valid"); break;
439                case 3: printf("Deauthenticated because sending station is leaving or has left IBSS or BSS"); break;
440                case 4: printf("Disassociated due to inactivity"); break;
441                case 5: printf("Disassociated because AP is unable to handle all currently associated stations"); break;
442                case 6: printf("Class 2 frame received from nonauthenticated station"); break;
443                case 7: printf("Class 3 frame received from nonassociated station"); break;
444                case 8: printf("Disassociated because AP is leaving (or has left) BSS"); break;
445                case 9: printf("Station requesting (re)association is not authenticated with responding station"); break;
446                default: printf("Unknown reason code: %u\n", code);
447        }
448}
449
450static 
451void ieee80211_print_status_code(uint16_t code) {
452        switch (code) {
453                case 0: printf("Successful"); break;
454                case 1: printf("Unspecified failure"); break;
455                case 10: printf("Cannot support all requested capabilities in the Capability Information field"); break;
456                case 11: printf("Reassociation denied due to inablity to confirm that association exists"); break;
457                case 12: printf("Association denied due to reason outside the scope of this standard"); break;
458                case 13: printf("Responding station does not support the specified authentication algorithm"); break;
459                case 14: printf("Received an Authentication frame with authentication transaction sequence number outside of expected sequence"); break;
460                case 15: printf("Authentication rejected because of channege failure"); break;
461                case 16: printf("Authentication rejected due to timeout waiting for next frame in sequence"); break;
462                case 17: printf("Association denied because AP is unable to handle additional associated stations"); break;
463                case 18: printf("Association denied due to requesting station not supporting all of the data rates in the BSSBasicRates parameter"); break;
464                default: printf("Unknown status code: %u", code);
465        }
466}
467
468/* Decodes a capability info field */
469static void decode_80211_capinfo(ieee80211_capinfo *c) {
470        printf(" 802.11MAC: Capability Info:");
471        if (c->ess) printf(" ESS");
472        if (c->ibss) printf(" IBSS");
473        if (c->cf_pollable) printf(" CF-POLLABLE");
474        if (c->cf_poll_req) printf(" CF-POLL-REQ");
475        if (c->privacy) printf(" PRIVACY");
476        if (c->short_preamble) printf(" SHORT-PREAMBLE");
477        if (c->pbcc) printf (" PBCC");
478        if (c->channel_agility) printf (" CHANNEL-AGILITY");
479        if (c->spectrum_mgmt) printf( " SPECTRUM-MGMT");
480        if (c->qos) printf(" QoS");
481        if (c->short_slot_time) printf (" SHORT-SLOT-TIME");
482        if (c->apsd) printf(" APSD");
483        if (c->dsss_ofdm) printf (" DSSS-OFDM");
484        if (c->delayed_block_ack) printf(" DELAYED-BLK-ACK");
485        if (c->immediate_block_ack) printf(" IMMEDIATE-BLK-ACK");
486        printf("\n");
487}
488       
489/* Decodes a beacon (or a probe response) */
490static void decode_80211_beacon(const char *pkt, unsigned len) {
491        ieee80211_beacon *b = (ieee80211_beacon *)pkt;
492        if (len < sizeof(ieee80211_beacon)) {
493                printf(" 802.11MAC: [Truncated]\n");
494                return;
495        }
496       
497        printf(" 802.11MAC: Timestamp = %" PRIu64 "\n", b->ts);
498        printf(" 802.11MAC: Beacon Interval = %u\n", b->interval);
499        decode_80211_capinfo(&b->capinfo);
500        printf(" 802.11MAC: Information Elements:\n");
501        decode_80211_information_elements((char *) pkt + sizeof(ieee80211_beacon), len - sizeof(ieee80211_beacon));             
502}
503
504static void decode_80211_assoc_request(const char *pkt, unsigned len) {
505        ieee80211_assoc_req *a = (ieee80211_assoc_req *) pkt;
506       
507        if (len < sizeof(ieee80211_assoc_req)) {
508                printf(" [Truncated association request]\n");
509                return;
510        }
511
512        decode_80211_capinfo(&a->capinfo);
513        printf(" 802.11MAC: Listen Interval = %u beacon intervals\n", a->listen_interval);
514        printf(" 802.11MAC: Information Elements:\n");
515        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_assoc_req), len - sizeof(ieee80211_assoc_req));
516}
517
518static void decode_80211_assoc_response(const char *pkt, unsigned len) {
519        ieee80211_assoc_resp *r = (ieee80211_assoc_resp *) pkt;
520
521        if (len < sizeof(ieee80211_assoc_resp)) {
522                printf(" [Truncated association response]\n");
523                return;
524        }
525        decode_80211_capinfo(&r->capinfo);
526        printf(" 802.11MAC: Status Code = ");
527        ieee80211_print_status_code(r->status_code);
528        /* AID has two most significant bits set to 1 */
529        printf("\n 802.11MAC: Association ID = %u\n", r->assoc_id & 0x3FFF);
530        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_assoc_resp), len-sizeof(ieee80211_assoc_resp));
531}
532       
533static void decode_80211_reassoc_request(const char *pkt, unsigned len) {
534        ieee80211_reassoc_req *r = (ieee80211_reassoc_req *) pkt;
535
536        if (len < sizeof(ieee80211_reassoc_req)) {
537                printf(" [Truncated reassociation request]\n");
538                return;
539        }
540        decode_80211_capinfo(&r->capinfo);
541        printf(" 802.11MAC: Listen Interval = %u beacon intervals\n", r->listen_interval);
542        printf(" 802.11MAC: Current AP address = %s\n", macaddr(r->current_address));
543        printf(" 802.11MAC: Information Elements:\n");
544        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_reassoc_req), len - sizeof(ieee80211_reassoc_req));
545}
546
547static void decode_80211_authentication_frame(const char *pkt, unsigned len) {
548        ieee80211_auth *auth = (ieee80211_auth *)pkt;
549        if(len < sizeof(ieee80211_auth)) {
550                printf(" [Truncated authentication frame]\n");
551                return;
552        }
553        printf(" 802.11MAC: Authentication algorithm number = %u\n", auth->auth_algo_num);
554        printf(" 802.11MAC: Authentication transaction sequence number = %u\n", auth->auth_trans_seq_num);
555        printf(" 802.11MAC: Status Code = ");
556        ieee80211_print_status_code(auth->status_code);
557        printf("\n 802.11MAC: Information Elements:\n");
558        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_auth), len - sizeof(ieee80211_auth));
559
560}
561
562static void decode_80211_mgmt(const char *pkt, unsigned len) {
563        ieee80211_mgmt_frame *mgmt = (ieee80211_mgmt_frame *)pkt;
564        const char *data;
565       
566        printf(" 802.11MAC: Management frame: ");
567       
568        if (len < sizeof(ieee80211_mgmt_frame)) {
569                printf("[Truncated]\n");
570                return;
571        }
572
573        switch (mgmt->ctl.subtype) {
574                case 0: printf("association request"); break;
575                case 1: printf("association response"); break;
576                case 2: printf("reassociation request"); break;
577                case 3: printf("reassociation response"); break;
578                case 4: printf("probe request"); break;
579                case 5: printf("probe response"); break;
580                case 8: printf("beacon"); break;
581                case 9: printf("ATIM"); break;
582                case 10: printf("disassociation"); break;
583                case 11: printf("authentication"); break;
584                case 12: printf("deauthentication"); break;
585                case 13: printf("action"); break;
586                default: printf("RESERVED"); break;
587        }
588       
589        printf("\n 802.11MAC: Duration = %u us\n", mgmt->duration);
590        printf(" 802.11MAC: DA       = %s\n", macaddr(mgmt->addr1));
591        printf(" 802.11MAC: SA       = %s\n", macaddr(mgmt->addr2));
592        printf(" 802.11MAC: BSSID    = %s\n", macaddr(mgmt->addr3));
593        printf(" 802.11MAC: fragment no. = %u, sequence no. = %u\n",
594                        (mgmt->seq_ctrl & 0x000F) ,
595                        (mgmt->seq_ctrl & 0xFFF0) >> 4);
596
597        switch (mgmt->ctl.subtype) {
598                case 0:
599                        decode_80211_assoc_request(pkt, len);
600                        break; 
601                case 1:
602                        decode_80211_assoc_response(pkt, len);
603                        break;
604                case 2:
605                        decode_80211_reassoc_request(pkt, len);
606                        break;
607                case 3:
608                        /* Reassoc response == assoc response */
609                        decode_80211_assoc_response(pkt, len);
610                        break;
611                case 4:
612                        decode_80211_information_elements((char *)pkt + sizeof(ieee80211_mgmt_frame), len - sizeof(ieee80211_mgmt_frame));
613                        break;
614                case 5:
615                        /* Probe response == beacon frame */
616                        decode_80211_beacon(pkt, len);
617                        break;
618                case 8:
619                        decode_80211_beacon(pkt, len);
620                        break;
621                case 10:
622                        data = (pkt + sizeof(ieee80211_mgmt_frame));
623                        printf(" 802.11MAC: Reason Code = ");
624                        ieee80211_print_reason_code((uint16_t) ((data[0] << 8) | (data[1])));
625                        printf("\n");
626                        break;
627                                                   
628                case 11:
629                        decode_80211_authentication_frame(pkt, len);
630                        break;
631                case 12:
632                        data = (pkt + sizeof(ieee80211_mgmt_frame));
633                        printf(" 802.11MAC: Reason Code = ");
634                        ieee80211_print_reason_code((uint16_t) ((data[0] << 8) | (data[1])));
635                        printf("\n");
636                        break;
637                default:
638                        printf(" 802.11MAC: Subtype %u decoder not implemented\n", mgmt->ctl.subtype);
639        }
640
641        printf("\n");
642
643}
644
645static void decode_80211_ctrl(const char *pkt, unsigned len) {
646        ieee80211_ctrl_frame_1addr *ctrl1 = (ieee80211_ctrl_frame_1addr *) pkt;
647        ieee80211_ctrl_frame_2addr *ctrl2 = (ieee80211_ctrl_frame_2addr *) pkt;
648        printf(" 802.11MAC: Control frame: ");
649       
650        if (len < sizeof(ieee80211_ctrl_frame_1addr)) {
651                printf("[Truncated]\n");
652                return;
653        }
654       
655        switch (ctrl1->ctl.subtype) {
656                case 8:
657                        printf("BlockAckReq\n"); 
658                        break;
659                case 9:
660                        printf("BlockAck\n"); 
661                        break;
662                case 10:
663                        printf("PS-Poll\n"); 
664                        printf(" 802.11MAC: AID = 0x%04x\n", ntohs(ctrl1->duration));
665                        printf(" 802.11MAC: BSSID = %s\n", macaddr(ctrl1->addr1));
666                        break;
667                case 11:
668                        printf("RTS\n");
669 
670                        if (len < sizeof(ieee80211_ctrl_frame_2addr)) {
671                                printf("[Truncated]\n");
672                                return;
673                        }
674
675                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl2->addr1));
676                        printf(" 802.11MAC: TA = %s\n", macaddr(ctrl2->addr2));
677                        break;
678                case 12:
679                        printf("CTS\n"); 
680                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl1->addr1));
681                        break;
682                case 13:
683                        printf("ACK\n"); 
684                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl1->addr1));
685                        break;
686                case 14:
687                        printf("CF-End\n"); 
688
689                        if (len < sizeof(ieee80211_ctrl_frame_2addr)) {
690                                printf("[Truncated]\n");
691                                return;
692                        }
693
694                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl2->addr1));
695                        printf(" 802.11MAC: BSSID = %s\n", macaddr(ctrl2->addr2));
696                        break;
697                case 15:
698                        printf("CF-End + CF-Ack\n"); 
699
700                        if (len < sizeof(ieee80211_ctrl_frame_2addr)) {
701                                printf("[Truncated]\n");
702                                return;
703                        }
704
705                        printf(" 802.11MAC: RA = %s\n", macaddr(ctrl2->addr1));
706                        printf(" 802.11MAC: BSSID = %s\n", macaddr(ctrl2->addr2));
707                        break;
708                default:
709                        printf("RESERVED"); 
710                        break;
711        }
712
713}
714
715static void decode_80211_data(const char *pkt, unsigned len) {
716        ieee80211_data_frame *data = (ieee80211_data_frame *) pkt;
717        ieee80211_qos_data_frame *qos = (ieee80211_qos_data_frame *)pkt;
718        ieee80211_payload *pld; 
719        uint32_t hdrlen = 0;
720       
721        printf(" 802.11MAC: Data frame: ");
722       
723        if (len < sizeof(ieee80211_data_frame_3)) {
724                printf("[Truncated]\n");
725                return;
726        }
727
728        switch (data->ctl.subtype) {
729                case 0: printf("Data"); break;
730                case 1: printf("Data + CF-Ack"); break;
731                case 2: printf("Data + CF-Poll"); break;
732                case 3: printf("Data + CF-Ack + CF-Poll"); break;
733                case 4: printf("Null (no data)"); break;
734                case 5: printf("CF-Ack (no data)"); break;
735                case 6: printf("CF-Poll (no data)"); break;
736                case 7: printf("CF-Ack + CF-Poll (no data)"); break;
737                case 8: printf("QoS Data"); break;
738                case 9: printf("QoS Data + CF-Ack"); break;
739                case 10: printf("QoS Data + CF-Poll"); break;
740                case 11: printf("QoS Data + CF-Ack + CF-Poll"); break;
741                case 12: printf("QoS Null (no data)"); break;
742                         /* subtype 13 is reserved */
743                case 14: printf("QoS CF-Poll (no data)"); break;
744                case 15: printf("Qos CF-Ack + CF-Poll (no data)"); break;
745
746                default: printf("RESERVED"); break;
747        }
748
749        printf("\n 802.11MAC: duration = %u us\n", data->duration);
750        printf(" 802.11MAC: fragment no. = %u, sequence no. = %u\n",
751                        (data->seq_ctrl & 0x000F) ,
752                        (data->seq_ctrl & 0xFFF0) >> 4);
753
754        hdrlen = sizeof(ieee80211_data_frame_3);
755       
756        if (! data->ctl.from_ds && ! data->ctl.to_ds) {
757                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr1));
758                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr2));
759                printf(" 802.11MAC: BSSID   = %s\n", macaddr(data->addr3));
760        } else if ( ! data->ctl.from_ds && data->ctl.to_ds) {
761                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr3));
762                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr2));
763                printf(" 802.11MAC: BSSID   = %s\n", macaddr(data->addr1));
764        } else if ( data->ctl.from_ds && ! data->ctl.to_ds) {
765                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr1));
766                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr3));
767                printf(" 802.11MAC: BSSID   = %s\n", macaddr(data->addr2));
768        } else {
769                /* Check to make sure we have a four-address frame first */
770                if (len < sizeof(ieee80211_data_frame)) {
771                        printf(" 802.11MAC: [Truncated]\n");
772                        return;
773                }
774                printf(" 802.11MAC: DA      = %s\n", macaddr(data->addr3));
775                printf(" 802.11MAC: SA      = %s\n", macaddr(data->addr4));
776                printf(" 802.11MAC: TA      = %s\n", macaddr(data->addr2));
777                printf(" 802.11MAC: RA      = %s\n", macaddr(data->addr1));
778                hdrlen = sizeof(ieee80211_data_frame); /* 4 addr header */
779        }
780
781
782        if (data->ctl.subtype >= 8) { 
783                printf(" 802.11e: QoS = 0x%04x\n", qos->qos);
784                if (len > sizeof(ieee80211_qos_data_frame)) 
785                        hdrlen = sizeof(ieee80211_qos_data_frame);
786        }
787       
788        if (len > hdrlen) {
789                int payload_offset = 0;
790                uint16_t ethertype = 0;
791                pld = (ieee80211_payload *) ((char *)pkt + hdrlen) ;
792                if (ntohs(pld->ethertype) == 0xaaaa) {
793                        /* 802.11 payload contains an 802.2 LLC/SNAP header */
794                        libtrace_llcsnap_t *llcsnap = (libtrace_llcsnap_t *) pld;
795                        printf(" 802.2: DSAP = 0x%x, SSAP = 0x%x, OUI = 0x%x, Type = 0x%x\n", 
796                                        llcsnap->dsap, llcsnap->ssap, llcsnap->oui, ntohs(llcsnap->type));
797                        payload_offset = sizeof(libtrace_llcsnap_t);
798                        ethertype = ntohs(llcsnap->type);
799                } else {
800                        /* 802.11 payload contains an Ethernet II frame */
801                        printf(" 802.11MAC: Payload ethertype = 0x%04x\n", ntohs(pld->ethertype));
802                        payload_offset = sizeof(pld->ethertype);
803                        ethertype = ntohs(pld->ethertype);
804                }
805                decode_next((char *) pkt + hdrlen + payload_offset, 
806                                len - hdrlen - payload_offset, "eth", ethertype);
807        }
808
809       
810}
811
812DLLEXPORT void decode(int link_type UNUSED, const char *pkt, unsigned len) 
813{
814        ieee80211_frame_control *fc;
815       
816        if (len < sizeof(ieee80211_frame_control)) {
817                printf(" 802.11MAC: Truncated at frame control field\n");
818                return;
819        }
820
821        fc = (ieee80211_frame_control *) pkt;   
822
823        printf(" 802.11MAC: ");
824
825        printf("proto = %d, type = %d, subtype = %d, ", fc->version, fc->type, fc->subtype);
826
827        printf("flags =");
828        if (fc->to_ds) printf(" toDS");
829        if (fc->from_ds) printf(" fromDS");
830        if (fc->more_frag) printf(" moreFrag");
831        if (fc->retry) printf(" retry");
832        if (fc->power) printf(" pwrMgmt");
833        if (fc->more_data) printf(" moreData");
834        if (fc->wep) printf(" WEP");
835        if (fc->order) printf(" order");
836
837        printf("\n");
838        switch (fc->type) {
839                case 0:
840                        decode_80211_mgmt(pkt, len);
841                        break;
842                case 1:
843                        decode_80211_ctrl(pkt, len);
844                        break;
845                case 2:
846                        decode_80211_data(pkt, len);
847                        break;
848                case 3:
849                        printf(" Unable to decode frame type %u, dumping rest of packet\n", fc->type);
850                        decode_next(pkt + sizeof(ieee80211_frame_control), len - sizeof(ieee80211_frame_control), "unknown", 0);
851                       
852                        break;
853        }
854
855}
856
857
Note: See TracBrowser for help on using the repository browser.