source: libpacketdump/link_4.c @ eade363

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since eade363 was eade363, checked in by Perry Lorier <perry@…>, 11 years ago

Tidy up thousands of little warnings

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