docs: add todo's from Sibir's repo
[netsniff-ng.git] / src / proto_80211_mac_hdr.c
blob75ca86f5df0076afeeab6c96f135bdef42149647
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>
4 * Copyright 2012 Daniel Borkmann <daniel@netsniff-ng.org>
5 * Subject to the GPL, version 2.
6 */
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <netinet/in.h> /* for ntohs() */
11 #include <asm/byteorder.h>
13 #include "proto.h"
14 #include "protos.h"
15 #include "dissector_80211.h"
16 #include "built_in.h"
17 #include "pkt_buff.h"
18 #include "oui.h"
20 #define TU 0.001024
22 /* Note: Fields are encoded in little-endian! */
23 struct ieee80211_frm_ctrl {
24 union {
25 u16 frame_control;
26 struct {
27 #if defined(__LITTLE_ENDIAN_BITFIELD)
28 /* Correct order here ... */
29 __extension__ u16 proto_version:2,
30 type:2,
31 subtype:4,
32 to_ds:1,
33 from_ds:1,
34 more_frags:1,
35 retry:1,
36 power_mgmt:1,
37 more_data:1,
38 wep:1,
39 order:1;
40 #elif defined(__BIG_ENDIAN_BITFIELD)
41 __extension__ u16 subtype:4,
42 type:2,
43 proto_version:2,
44 order:1,
45 wep:1,
46 more_data:1,
47 power_mgmt:1,
48 retry:1,
49 more_frags:1,
50 from_ds:1,
51 to_ds:1;
52 #else
53 # error "Adjust your <asm/byteorder.h> defines"
54 #endif
57 } __packed;
59 /* Management Frame start */
60 /* Note: Fields are encoded in little-endian! */
61 struct ieee80211_mgmt {
62 u16 duration;
63 u8 da[6];
64 u8 sa[6];
65 u8 bssid[6];
66 u16 seq_ctrl;
67 } __packed;
69 struct ieee80211_mgmt_auth {
70 u16 auth_alg;
71 u16 auth_transaction;
72 u16 status_code;
73 /* possibly followed by Challenge text */
74 u8 variable[0];
75 } __packed;
77 struct ieee80211_mgmt_deauth {
78 u16 reason_code;
79 } __packed;
81 struct ieee80211_mgmt_assoc_req {
82 u16 capab_info;
83 u16 listen_interval;
84 /* followed by SSID and Supported rates */
85 u8 variable[0];
86 } __packed;
88 struct ieee80211_mgmt_assoc_resp {
89 u16 capab_info;
90 u16 status_code;
91 u16 aid;
92 /* followed by Supported rates */
93 u8 variable[0];
94 } __packed;
96 struct ieee80211_mgmt_reassoc_resp {
97 u16 capab_info;
98 u16 status_code;
99 u16 aid;
100 /* followed by Supported rates */
101 u8 variable[0];
102 } __packed;
104 struct ieee80211_mgmt_reassoc_req {
105 u16 capab_info;
106 u16 listen_interval;
107 u8 current_ap[6];
108 /* followed by SSID and Supported rates */
109 u8 variable[0];
110 } __packed;
112 struct ieee80211_mgmt_disassoc {
113 u16 reason_code;
114 } __packed;
116 struct ieee80211_mgmt_probe_req {
117 } __packed;
119 struct ieee80211_mgmt_beacon {
120 u64 timestamp;
121 u16 beacon_int;
122 u16 capab_info;
123 /* followed by some of SSID, Supported rates,
124 * FH Params, DS Params, CF Params, IBSS Params, TIM */
125 u8 variable[0];
126 } __packed;
128 struct ieee80211_mgmt_probe_resp {
129 u8 timestamp[8];
130 u16 beacon_int;
131 u16 capab_info;
132 /* followed by some of SSID, Supported rates,
133 * FH Params, DS Params, CF Params, IBSS Params, TIM */
134 u8 variable[0];
135 } __packed;
136 /* Management Frame end */
138 /* Control Frame start */
139 /* Note: Fields are encoded in little-endian! */
140 struct ieee80211_ctrl {
141 } __packed;
143 struct ieee80211_ctrl_rts {
144 u16 duration;
145 u8 da[6];
146 u8 sa[6];
147 } __packed;
149 struct ieee80211_ctrl_cts {
150 u16 duration;
151 u8 da[6];
152 } __packed;
154 struct ieee80211_ctrl_ack {
155 u16 duration;
156 u8 da[6];
157 } __packed;
159 struct ieee80211_ctrl_ps_poll {
160 u16 aid;
161 u8 bssid[6];
162 u8 sa[6];
163 } __packed;
165 struct ieee80211_ctrl_cf_end {
166 u16 duration;
167 u8 bssid[6];
168 u8 sa[6];
169 } __packed;
171 struct ieee80211_ctrl_cf_end_ack {
172 u16 duration;
173 u8 bssid[6];
174 u8 sa[6];
175 } __packed;
176 /* Control Frame end */
178 /* Data Frame start */
179 /* Note: Fields are encoded in little-endian! */
180 struct ieee80211_data {
181 } __packed;
183 /* TODO: Extend */
184 /* Data Frame end */
186 /* http://www.sss-mag.com/pdf/802_11tut.pdf
187 * http://www.scribd.com/doc/78443651/111/Management-Frames
188 * http://www.wildpackets.com/resources/compendium/wireless_lan/wlan_packets
189 * http://www.rhyshaden.com/wireless.htm
192 struct element_reserved {
193 u8 len;
194 } __packed;
196 struct element_ssid {
197 u8 len;
198 u8 SSID[0];
199 } __packed;
201 struct element_supp_rates {
202 u8 len;
203 u8 SSID[0];
204 } __packed;
206 struct element_fh_ps {
207 u8 len;
208 u16 dwell_time;
209 u8 hop_set;
210 u8 hop_pattern;
211 u8 hop_index;
212 } __packed;
214 struct element_dsss_ps {
215 u8 len;
216 u8 curr_ch;
217 } __packed;
219 struct element_cf_ps {
220 u8 len;
221 u8 cfp_cnt;
222 u8 cfp_period;
223 u16 cfp_max_dur;
224 u16 cfp_dur_rem;
225 } __packed;
227 struct element_tim {
228 u8 len;
229 u8 dtim_cnt;
230 u8 dtim_period;
231 u8 bmp_cntrl;
232 u8 part_virt_bmp[0];
233 } __packed;
235 struct element_ibss_ps {
236 u8 len;
237 u16 atim_win;
238 } __packed;
240 struct element_country_tripled {
241 u8 frst_ch;
242 u8 nr_ch;
243 u8 max_trans;
244 } __packed;
246 struct element_country {
247 u8 len;
248 #if defined(__LITTLE_ENDIAN_BITFIELD)
249 /* Correct order here ... */
250 u8 country_first;
251 u8 country_sec;
252 u8 country_third;
253 #elif defined(__BIG_ENDIAN_BITFIELD)
254 u8 country_third;
255 u8 country_sec;
256 u8 country_first;
257 #else
258 # error "Adjust your <asm/byteorder.h> defines"
259 #endif
260 /* triplet may repeat */
261 struct element_country_tripled tripled [0];
262 /* end triplet */
263 u8 pad[0];
264 } __packed;
266 struct element_hop_pp {
267 u8 len;
268 u8 prime_radix;
269 u8 nr_ch;
270 } __packed;
272 struct element_hop_pt {
273 u8 len;
274 u8 flag;
275 u8 nr_sets;
276 u8 modules;
277 u8 offs;
278 u8 rand_tabl[0];
279 } __packed;
281 struct element_req {
282 u8 len;
283 u8 req_elem_idl[0];
284 } __packed;
286 struct element_bss_load {
287 u8 len;
288 u16 station_cnt;
289 u8 ch_util;
290 u16 avlb_adm_cap;
291 } __packed;
293 struct element_edca_ps {
294 u8 len;
295 u8 qos_inf;
296 u8 res;
297 u32 ac_be;
298 u32 ac_bk;
299 u32 ac_vi;
300 u32 ac_vo;
301 } __packed;
303 struct element_tspec {
304 union {
305 u32 len_ts_info;
306 struct {
307 #if defined(__LITTLE_ENDIAN_BITFIELD)
308 /* Correct order here ... */
309 __extension__ u32 len:8,
310 traffic_type:1,
311 tsid:4,
312 direction:2,
313 access_policy:2,
314 aggr:1,
315 apsid:1,
316 user_prior:3,
317 tsinfo_ack_pol:2,
318 schedule:1,
319 res:7;
320 #elif defined(__BIG_ENDIAN_BITFIELD)
321 __extension__ u32 len:8,
322 res:7,
323 schedule:1,
324 tsinfo_ack_pol:2,
325 user_prior:3,
326 apsid:1,
327 aggr:1,
328 access_policy:2,
329 direction:2,
330 tsid:4,
331 traffic_type:1;
332 #else
333 # error "Adjust your <asm/byteorder.h> defines"
334 #endif
337 u16 nom_msdu_size;
338 u16 max_msdu_size;
339 u32 min_srv_intv;
340 u32 max_srv_intv;
341 u32 inactive_intv;
342 u32 susp_intv;
343 u32 srv_start_time;
344 u32 min_data_rate;
345 u32 mean_data_rate;
346 u32 peak_data_rate;
347 u32 burst_size;
348 u32 delay_bound;
349 u32 min_phy_rate;
350 u16 surplus_bandw_allow;
351 u16 med_time;
352 } __packed;
354 struct element_tclas {
355 u8 len;
356 u8 user_priority;
357 u8 frame_class[0];
358 } __packed;
360 struct element_erp {
361 u8 len;
362 u8 param;
363 } __packed;
365 struct element_ext_supp_rates {
366 u8 len;
367 u8 rates[0];
368 } __packed;
370 struct element_vend_spec {
371 u8 len;
372 u8 oui[0];
373 u8 specific[0];
374 } __packed;
376 static int8_t len_neq_error(u8 len, u8 intended)
378 if(intended != len) {
379 tprintf("Length should be %u Bytes", intended);
380 return 1;
383 return 0;
386 static int8_t len_gt_error(u8 len, u8 intended)
388 if(intended > len) {
389 tprintf("Length should be greater %u Bytes", intended);
390 return 1;
393 return 0;
396 static float data_rates(u8 id)
398 /* XXX Why not (id / 2.f)? */
399 switch (id) {
400 case 2: return 1.0f;
401 case 3: return 1.5f;
402 case 4: return 2.0f;
403 case 5: return 2.5f;
404 case 6: return 3.0f;
405 case 9: return 4.5f;
406 case 11: return 5.5f;
407 case 12: return 6.0f;
408 case 18: return 9.0f;
409 case 22: return 11.0f;
410 case 24: return 12.0f;
411 case 27: return 13.5f;
412 case 36: return 18.0f;
413 case 44: return 22.0f;
414 case 48: return 24.0f;
415 case 54: return 27.0f;
416 case 66: return 33.0f;
417 case 72: return 36.0f;
418 case 96: return 48.0f;
419 case 108: return 54.0f;
422 return 0.f;
425 static int8_t inf_reserved(struct pkt_buff *pkt, u8 *id)
427 u8 i;
428 u8 *data;
429 struct element_reserved *reserved;
431 reserved = (struct element_reserved *) pkt_pull(pkt, sizeof(*reserved));
432 if (reserved == NULL)
433 return 0;
435 tprintf("Reserved (%u, Len (%u)): ", *id, reserved->len);
437 data = pkt_pull(pkt, reserved->len);
438 if (data == NULL)
439 return 0;
441 tprintf("Data 0x");
442 for (i = 0; i < reserved->len; i++)
443 tprintf("%.2x", data[i]);
445 return 1;
448 static int8_t inf_ssid(struct pkt_buff *pkt, u8 *id)
450 u8 i;
451 struct element_ssid *ssid;
452 char *ssid_name;
454 ssid = (struct element_ssid *) pkt_pull(pkt, sizeof(*ssid));
455 if (ssid == NULL)
456 return 0;
458 tprintf(" SSID (%u, Len (%u)): ", *id, ssid->len);
460 if ((ssid->len - sizeof(*ssid) + 1) > 0) {
461 ssid_name = (char *) pkt_pull(pkt, ssid->len);
462 if (ssid_name == NULL)
463 return 0;
465 for (i = 0; i < ssid->len; i++)
466 tprintf("%c",ssid_name[i]);
467 } else {
468 tprintf("Wildcard SSID");
471 return 1;
474 static int8_t inf_supp_rates(struct pkt_buff *pkt, u8 *id)
476 u8 i;
477 u8 *rates;
478 struct element_supp_rates *supp_rates;
480 supp_rates = (struct element_supp_rates *)
481 pkt_pull(pkt, sizeof(*supp_rates));
482 if (supp_rates == NULL)
483 return 0;
485 tprintf("Rates (%u, Len (%u)): ", *id, supp_rates->len);
486 if (len_gt_error(supp_rates->len, 1))
487 return 0;
489 if ((supp_rates->len - sizeof(*supp_rates) + 1) > 0) {
490 rates = pkt_pull(pkt, supp_rates->len);
491 if (rates == NULL)
492 return 0;
494 for (i = 0; i < supp_rates->len; i++)
495 tprintf("%g ", (rates[i] & 0x80) ?
496 ((rates[i] & 0x3f) * 0.5) :
497 data_rates(rates[i]));
498 return 1;
501 return 0;
504 static int8_t inf_fh_ps(struct pkt_buff *pkt, u8 *id)
506 struct element_fh_ps *fh_ps;
508 fh_ps = (struct element_fh_ps *) pkt_pull(pkt, sizeof(*fh_ps));
509 if (fh_ps == NULL)
510 return 0;
512 tprintf("FH Param Set (%u, Len(%u)): ", *id, fh_ps->len);
513 if (len_neq_error(fh_ps->len, 5))
514 return 0;
515 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps->dwell_time) * TU);
516 tprintf("HopSet: %u, ", fh_ps->hop_set);
517 tprintf("HopPattern: %u, ", fh_ps->hop_pattern);
518 tprintf("HopIndex: %u", fh_ps->hop_index);
520 return 1;
523 static int8_t inf_dsss_ps(struct pkt_buff *pkt, u8 *id)
525 struct element_dsss_ps *dsss_ps;
527 dsss_ps = (struct element_dsss_ps *) pkt_pull(pkt, sizeof(*dsss_ps));
528 if (dsss_ps == NULL)
529 return 0;
531 tprintf("DSSS Param Set (%u, Len(%u)): ", *id, dsss_ps->len);
532 if (len_neq_error(dsss_ps->len, 1))
533 return 0;
534 tprintf("Current Channel: %u", dsss_ps->curr_ch);
536 return 1;
539 static int8_t inf_cf_ps(struct pkt_buff *pkt, u8 *id)
541 struct element_cf_ps *cf_ps;
543 cf_ps = (struct element_cf_ps *) pkt_pull(pkt, sizeof(*cf_ps));
544 if (cf_ps == NULL)
545 return 0;
547 tprintf("CF Param Set (%u, Len(%u)): ", *id, cf_ps->len);
548 if (len_neq_error(cf_ps->len, 6))
549 return 0;
550 tprintf("CFP Count: %u, ", cf_ps->cfp_cnt);
551 tprintf("CFP Period: %u, ", cf_ps->cfp_period);
552 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps->cfp_max_dur) * TU);
553 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps->cfp_dur_rem) * TU);
555 return 1;
558 static int8_t inf_tim(struct pkt_buff *pkt, u8 *id)
560 struct element_tim *tim;
562 tim = (struct element_tim *) pkt_pull(pkt, sizeof(*tim));
563 if (tim == NULL)
564 return 0;
566 tprintf("TIM (%u, Len(%u)): ", *id, tim->len);
567 if (len_gt_error(tim->len, 3))
568 return 0;
569 tprintf("DTIM Count: %u, ", tim->dtim_cnt);
570 tprintf("DTIM Period: %u, ", tim->dtim_period);
571 tprintf("Bitmap Control: %u, ", tim->bmp_cntrl);
572 if ((tim->len - sizeof(*tim) + 1) > 0) {
573 u8 *bmp = pkt_pull(pkt, (tim->len - sizeof(*tim) + 1));
574 if (bmp == NULL)
575 return 0;
577 tprintf("Partial Virtual Bitmap: 0x");
578 for(u8 i=0; i < (tim->len - sizeof(*tim) + 1); i++)
579 tprintf("%.2x ", bmp[i]);
582 return 1;
585 static int8_t inf_ibss_ps(struct pkt_buff *pkt, u8 *id)
587 struct element_ibss_ps *ibss_ps;
589 ibss_ps = (struct element_ibss_ps *) pkt_pull(pkt, sizeof(*ibss_ps));
590 if (ibss_ps == NULL)
591 return 0;
593 tprintf("IBSS Param Set (%u, Len(%u)): ", *id, ibss_ps->len);
594 if (len_neq_error(ibss_ps->len, 2))
595 return 0;
596 tprintf("ATIM Window: %fs", le16_to_cpu(ibss_ps->atim_win) * TU);
598 return 1;
601 static int8_t inf_country(struct pkt_buff *pkt, u8 *id)
603 u8 i;
604 u8 *pad;
605 struct element_country *country;
607 country = (struct element_country *) pkt_pull(pkt, sizeof(*country));
608 if (country == NULL)
609 return 0;
611 tprintf("Country (%u, Len(%u)): ", *id, country->len);
612 if (len_gt_error(country->len, 6))
613 return 0;
614 tprintf("Country String: %c%c%c", country->country_first,
615 country->country_sec, country->country_third);
617 for (i = 0; i < (country->len - 3); i += 3) {
618 struct element_country_tripled *country_tripled;
620 country_tripled = (struct element_country_tripled *)
621 pkt_pull(pkt, sizeof(*country_tripled));
622 if (country_tripled == NULL)
623 return 0;
625 if(country_tripled->frst_ch >= 201) {
626 tprintf("Oper Ext ID: %u, ", country_tripled->frst_ch);
627 tprintf("Operating Class: %u, ", country_tripled->nr_ch);
628 tprintf("Coverage Class: %u", country_tripled->max_trans);
629 } else {
630 tprintf("First Ch Nr: %u, ", country_tripled->frst_ch);
631 tprintf("Nr of Ch: %u, ", country_tripled->nr_ch);
632 tprintf("Max Transmit Pwr Lvl: %u", country_tripled->max_trans);
636 if(country->len % 2) {
637 pad = pkt_pull(pkt, 1);
638 if (pad == NULL)
639 return 0;
641 tprintf(", Pad: 0x%x", *pad);
644 return 1;
647 static int8_t inf_hop_pp(struct pkt_buff *pkt, u8 *id)
649 struct element_hop_pp *hop_pp;
651 hop_pp = (struct element_hop_pp *) pkt_pull(pkt, sizeof(*hop_pp));
652 if (hop_pp == NULL)
653 return 0;
655 tprintf("Hopping Pattern Param (%u, Len(%u)): ", *id, hop_pp->len);
656 if (len_neq_error(hop_pp->len, 2))
657 return 0;
658 tprintf("Nr of Ch: %u", hop_pp->nr_ch);
660 return 1;
663 static int8_t inf_hop_pt(struct pkt_buff *pkt, u8 *id)
665 int i;
666 u8 *rand_tabl;
667 struct element_hop_pt *hop_pt;
669 hop_pt = (struct element_hop_pt *) pkt_pull(pkt, sizeof(*hop_pt));
670 if (hop_pt == NULL)
671 return 0;
673 tprintf("Hopping Pattern Table (%u, Len(%u)): ", *id, hop_pt->len);
674 if (len_gt_error(hop_pt->len, 4))
675 return 0;
676 tprintf("Flag: %u, ", hop_pt->flag);
677 tprintf("Nr of Sets: %u, ", hop_pt->nr_sets);
678 tprintf("Modules: %u, ", hop_pt->modules);
679 tprintf("Offs: %u", hop_pt->offs);
681 if ((hop_pt->len - sizeof(*hop_pt) + 1) > 0) {
682 rand_tabl = pkt_pull(pkt, (hop_pt->len - sizeof(*hop_pt) + 1));
683 if (rand_tabl == NULL)
684 return 0;
686 tprintf(", Rand table: 0x");
687 for (i = 0; i < (hop_pt->len - sizeof(*hop_pt) + 1); i++)
688 tprintf("%.2x ", rand_tabl[i]);
691 return 1;
694 static int8_t inf_req(struct pkt_buff *pkt, u8 *id)
696 int i;
697 struct element_req *req;
698 u8 *req_ids;
700 req = (struct element_req *) pkt_pull(pkt, sizeof(*req));
701 if (req == NULL)
702 return 0;
704 tprintf("Request Element (%u, Len(%u)): ", *id, req->len);
705 if ((req->len - sizeof(*req) + 1) > 0) {
706 req_ids = pkt_pull(pkt, (req->len - sizeof(*req) + 1));
707 if (req_ids == NULL)
708 return 0;
710 tprintf(", Requested Element IDs: ");
711 for (i = 0; i < (req->len - sizeof(*req) + 1); i++)
712 tprintf("%u ", req_ids[i]);
715 return 1;
718 static int8_t inf_bss_load(struct pkt_buff *pkt, u8 *id)
720 struct element_bss_load *bss_load;
722 bss_load = (struct element_bss_load *) pkt_pull(pkt, sizeof(*bss_load));
723 if (bss_load == NULL)
724 return 0;
726 tprintf("BSS Load element (%u, Len(%u)): ", *id, bss_load->len);
727 if (len_neq_error(bss_load->len, 5))
728 return 0;
729 tprintf("Station Count: %u, ", le16_to_cpu(bss_load->station_cnt));
730 tprintf("Channel Utilization: %u, ", bss_load->ch_util);
731 tprintf("Available Admission Capacity: %uus",
732 bss_load->avlb_adm_cap * 32);
734 return 1;
737 static int8_t inf_edca_ps(struct pkt_buff *pkt, u8 *id)
739 u32 ac_be, ac_bk, ac_vi, ac_vo;
740 struct element_edca_ps *edca_ps;
742 edca_ps = (struct element_edca_ps *) pkt_pull(pkt, sizeof(*edca_ps));
743 if (edca_ps == NULL)
744 return 0;
746 ac_be = le32_to_cpu(edca_ps->ac_be);
747 ac_bk = le32_to_cpu(edca_ps->ac_bk);
748 ac_vi = le32_to_cpu(edca_ps->ac_vi);
749 ac_vo = le32_to_cpu(edca_ps->ac_vo);
751 tprintf("EDCA Param Set (%u, Len(%u)): ", *id, edca_ps->len);
752 if (len_neq_error(edca_ps->len, 18))
753 return 0;
754 tprintf("QoS Info: 0x%x (-> EDCA Param Set Update Count (%u),"
755 "Q-Ack (%u), Queue Re (%u), TXOP Req(%u), Res(%u)), ",
756 edca_ps->qos_inf, edca_ps->qos_inf >> 4,
757 (edca_ps->qos_inf >> 3) & 1, (edca_ps->qos_inf >> 2) & 1,
758 (edca_ps->qos_inf >> 1) & 1, edca_ps->qos_inf & 1);
759 tprintf("Reserved: 0x%x, ", edca_ps->res);
760 tprintf("AC_BE Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
761 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_be,
762 ac_be >> 28, (ac_be >> 27) & 1, (ac_be >> 25) & 3,
763 (ac_be >> 24) & 1, (ac_be >> 20) & 15, (ac_be >> 16) & 15,
764 bswap_16(ac_be & 0xFFFF) * 32);
765 tprintf("AC_BK Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
766 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_bk,
767 ac_bk >> 28, (ac_bk >> 27) & 1, (ac_bk >> 25) & 3,
768 (ac_bk >> 24) & 1, (ac_bk >> 20) & 15, (ac_bk >> 16) & 15,
769 bswap_16(ac_bk & 0xFFFF) * 32);
770 tprintf("AC_VI Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
771 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_vi,
772 ac_vi >> 28, (ac_vi >> 27) & 1, (ac_vi >> 25) & 3,
773 (ac_vi >> 24) & 1, (ac_vi >> 20) & 15, (ac_vi >> 16) & 15,
774 bswap_16(ac_vi & 0xFFFF) * 32);
775 tprintf("AC_VO Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
776 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)", ac_vo,
777 ac_vo >> 28, (ac_vo >> 27) & 1, (ac_vo >> 25) & 3,
778 (ac_vo >> 24) & 1, (ac_vo >> 20) & 15, (ac_vo >> 16) & 15,
779 bswap_16(ac_vo & 0xFFFF) * 32);
781 return 1;
784 static int8_t inf_tspec(struct pkt_buff *pkt, u8 *id)
786 u16 nom_msdu_size, surplus_bandw_allow;
787 struct element_tspec *tspec;
789 tspec = (struct element_tspec *) pkt_pull(pkt, sizeof(*tspec));
790 if (tspec == NULL)
791 return 0;
793 nom_msdu_size = le16_to_cpu(tspec->nom_msdu_size);
794 surplus_bandw_allow = le16_to_cpu(tspec->surplus_bandw_allow);
796 tprintf("TSPEC (%u, Len(%u)): ", *id, tspec->len);
797 if (len_neq_error(tspec->len, 55))
798 return 0;
799 tprintf("Traffic Type: %u, ", tspec->traffic_type);
800 tprintf("TSID: %u, ", tspec->tsid);
801 tprintf("Direction: %u, ", tspec->direction);
802 tprintf("Access Policy: %u, ", tspec->access_policy);
803 tprintf("Aggregation: %u, ", tspec->aggr);
804 tprintf("User Priority: %u, ", tspec->user_prior);
805 tprintf("TSinfo Ack Policy: %u, ", tspec->tsinfo_ack_pol);
806 tprintf("Schedule: %u, ", tspec->schedule);
807 tprintf("Reserved: 0x%x, ", tspec->res);
808 tprintf("Nominal MSDU Size: %uB (Fixed (%u)), ",
809 nom_msdu_size >> 1, nom_msdu_size & 1);
810 tprintf("Maximum MSDU Size: %uB, ", le16_to_cpu(tspec->max_msdu_size));
811 tprintf("Minimum Service Interval: %uus, ",
812 le32_to_cpu(tspec->min_srv_intv));
813 tprintf("Maximum Service Interval: %uus, ",
814 le32_to_cpu(tspec->max_srv_intv));
815 tprintf("Inactivity Interval: %uus, ",
816 le32_to_cpu(tspec->inactive_intv));
817 tprintf("Suspension Interval: %uus, ", le32_to_cpu(tspec->susp_intv));
818 tprintf("Service Start Time: %uus, ",
819 le32_to_cpu(tspec->srv_start_time));
820 tprintf("Minimum Data Rate: %ub/s, ",le32_to_cpu(tspec->min_data_rate));
821 tprintf("Mean Data Rate: %ub/s, ", le32_to_cpu(tspec->mean_data_rate));
822 tprintf("Peak Data Rate: %ub/s, ",le32_to_cpu(tspec->peak_data_rate));
823 tprintf("Burst Size: %uB, ", le32_to_cpu(tspec->burst_size));
824 tprintf("Delay Bound: %uus, ", le32_to_cpu(tspec->delay_bound));
825 tprintf("Minimum PHY Rate: %ub/s, ", le32_to_cpu(tspec->min_phy_rate));
826 tprintf("Surplus Bandwidth: %u.%u, ", surplus_bandw_allow >> 13,
827 surplus_bandw_allow & 0x1FFF);
828 tprintf("Medium Time: %uus, ", le16_to_cpu(tspec->med_time) * 32);
830 return 1;
833 static int8_t inf_tclas(struct pkt_buff *pkt, u8 *id)
835 struct element_tclas *tclas;
837 tclas = (struct element_tclas *) pkt_pull(pkt, sizeof(*tclas));
838 if (tclas == NULL)
839 return 0;
841 tprintf("TCLAS (%u, Len(%u)): ", *id, tclas->len);
842 if (len_gt_error(tclas->len, 1))
843 return 0;
844 tprintf("User Priority: %u, ", tclas->user_priority);
846 /*TODO add Classifier p.574*/
848 return 0;
851 static int8_t inf_sched(struct pkt_buff *pkt, u8 *id)
853 return 0;
856 static int8_t inf_chall_txt(struct pkt_buff *pkt, u8 *id)
858 return 0;
861 static int8_t inf_pwr_constr(struct pkt_buff *pkt, u8 *id)
863 return 0;
866 static int8_t inf_pwr_cap(struct pkt_buff *pkt, u8 *id)
868 return 0;
871 static int8_t inf_tpc_req(struct pkt_buff *pkt, u8 *id)
873 return 0;
876 static int8_t inf_tpc_rep(struct pkt_buff *pkt, u8 *id)
878 return 0;
881 static int8_t inf_supp_ch(struct pkt_buff *pkt, u8 *id)
883 return 0;
886 static int8_t inf_ch_sw_ann(struct pkt_buff *pkt, u8 *id)
888 return 0;
891 static int8_t inf_meas_req(struct pkt_buff *pkt, u8 *id)
893 return 0;
896 static int8_t inf_meas_rep(struct pkt_buff *pkt, u8 *id)
898 return 0;
901 static int8_t inf_quiet(struct pkt_buff *pkt, u8 *id)
903 return 0;
906 static int8_t inf_ibss_dfs(struct pkt_buff *pkt, u8 *id)
908 return 0;
911 static int8_t inf_erp(struct pkt_buff *pkt, u8 *id)
913 struct element_erp *erp;
915 erp = (struct element_erp *) pkt_pull(pkt, sizeof(*erp));
916 if (erp == NULL)
917 return 0;
919 tprintf("ERP (%u, Len(%u)): ", *id, erp->len);
920 if (len_neq_error(erp->len, 1))
921 return 0;
922 tprintf("Non ERP Present (%u), ", erp->param & 0x1);
923 tprintf("Use Protection (%u), ", (erp->param >> 1) & 0x1);
924 tprintf("Barker Preamble Mode (%u), ", (erp->param >> 2) & 0x1);
925 tprintf("Reserved (0x%.5x)", erp->param >> 3);
927 return 1;
930 static int8_t inf_ts_del(struct pkt_buff *pkt, u8 *id)
932 return 0;
935 static int8_t inf_tclas_proc(struct pkt_buff *pkt, u8 *id)
937 return 0;
940 static int8_t inf_ht_cap(struct pkt_buff *pkt, u8 *id)
942 return 0;
945 static int8_t inf_qos_cap(struct pkt_buff *pkt, u8 *id)
947 return 0;
950 static int8_t inf_rsn(struct pkt_buff *pkt, u8 *id)
952 return 0;
955 static int8_t inf_ext_supp_rates(struct pkt_buff *pkt, u8 *id)
957 u8 i;
958 u8 *rates;
959 struct element_ext_supp_rates *ext_supp_rates;
961 ext_supp_rates = (struct element_ext_supp_rates *)
962 pkt_pull(pkt, sizeof(*ext_supp_rates));
963 if (ext_supp_rates == NULL)
964 return 0;
966 tprintf("Ext Support Rates (%u, Len(%u)): ", *id, ext_supp_rates->len);
968 if ((ext_supp_rates->len - sizeof(*ext_supp_rates) + 1) > 0) {
969 rates = pkt_pull(pkt, ext_supp_rates->len);
970 if (rates == NULL)
971 return 0;
973 for (i = 0; i < ext_supp_rates->len; i++)
974 tprintf("%g ", (rates[i] & 0x80) ?
975 ((rates[i] & 0x3f) * 0.5) :
976 data_rates(rates[i]));
977 return 1;
980 return 0;
983 static int8_t inf_ap_ch_exp(struct pkt_buff *pkt, u8 *id) {
984 return 0;
987 static int8_t inf_neighb_rep(struct pkt_buff *pkt, u8 *id) {
988 return 0;
991 static int8_t inf_rcpi(struct pkt_buff *pkt, u8 *id) {
992 return 0;
995 static int8_t inf_mde(struct pkt_buff *pkt, u8 *id) {
996 return 0;
999 static int8_t inf_fte(struct pkt_buff *pkt, u8 *id) {
1000 return 0;
1003 static int8_t inf_time_out_int(struct pkt_buff *pkt, u8 *id) {
1004 return 0;
1007 static int8_t inf_rde(struct pkt_buff *pkt, u8 *id) {
1008 return 0;
1011 static int8_t inf_dse_reg_loc(struct pkt_buff *pkt, u8 *id) {
1012 return 0;
1015 static int8_t inf_supp_op_class(struct pkt_buff *pkt, u8 *id) {
1016 return 0;
1019 static int8_t inf_ext_ch_sw_ann(struct pkt_buff *pkt, u8 *id) {
1020 return 0;
1023 static int8_t inf_ht_op(struct pkt_buff *pkt, u8 *id) {
1024 return 0;
1027 static int8_t inf_sec_ch_offs(struct pkt_buff *pkt, u8 *id) {
1028 return 0;
1031 static int8_t inf_bss_avg_acc_del(struct pkt_buff *pkt, u8 *id) {
1032 return 0;
1035 static int8_t inf_ant(struct pkt_buff *pkt, u8 *id) {
1036 return 0;
1039 static int8_t inf_rsni(struct pkt_buff *pkt, u8 *id) {
1040 return 0;
1043 static int8_t inf_meas_pilot_trans(struct pkt_buff *pkt, u8 *id) {
1044 return 0;
1047 static int8_t inf_bss_avl_adm_cap(struct pkt_buff *pkt, u8 *id) {
1048 return 0;
1051 static int8_t inf_bss_ac_acc_del(struct pkt_buff *pkt, u8 *id) {
1052 return 0;
1055 static int8_t inf_time_adv(struct pkt_buff *pkt, u8 *id) {
1056 return 0;
1059 static int8_t inf_rm_ena_cap(struct pkt_buff *pkt, u8 *id) {
1060 return 0;
1063 static int8_t inf_mult_bssid(struct pkt_buff *pkt, u8 *id) {
1064 return 0;
1067 static int8_t inf_20_40_bss_coex(struct pkt_buff *pkt, u8 *id) {
1068 return 0;
1071 static int8_t inf_20_40_bss_int_ch_rep(struct pkt_buff *pkt, u8 *id) {
1072 return 0;
1075 static int8_t inf_overl_bss_scan_para(struct pkt_buff *pkt, u8 *id) {
1076 return 0;
1079 static int8_t inf_ric_desc(struct pkt_buff *pkt, u8 *id) {
1080 return 0;
1083 static int8_t inf_mgmt_mic(struct pkt_buff *pkt, u8 *id) {
1084 return 0;
1087 static int8_t inf_ev_req(struct pkt_buff *pkt, u8 *id) {
1088 return 0;
1091 static int8_t inf_ev_rep(struct pkt_buff *pkt, u8 *id) {
1092 return 0;
1095 static int8_t inf_diagn_req(struct pkt_buff *pkt, u8 *id) {
1096 return 0;
1099 static int8_t inf_diagn_rep(struct pkt_buff *pkt, u8 *id) {
1100 return 0;
1103 static int8_t inf_loc_para(struct pkt_buff *pkt, u8 *id) {
1104 return 0;
1107 static int8_t inf_nontr_bssid_cap(struct pkt_buff *pkt, u8 *id) {
1108 return 0;
1111 static int8_t inf_ssid_list(struct pkt_buff *pkt, u8 *id) {
1112 return 0;
1115 static int8_t inf_mult_bssid_index(struct pkt_buff *pkt, u8 *id) {
1116 return 0;
1119 static int8_t inf_fms_desc(struct pkt_buff *pkt, u8 *id) {
1120 return 0;
1123 static int8_t inf_fms_req(struct pkt_buff *pkt, u8 *id) {
1124 return 0;
1127 static int8_t inf_fms_resp(struct pkt_buff *pkt, u8 *id) {
1128 return 0;
1131 static int8_t inf_qos_tfc_cap(struct pkt_buff *pkt, u8 *id) {
1132 return 0;
1135 static int8_t inf_bss_max_idle_per(struct pkt_buff *pkt, u8 *id) {
1136 return 0;
1139 static int8_t inf_tfs_req(struct pkt_buff *pkt, u8 *id) {
1140 return 0;
1143 static int8_t inf_tfs_resp(struct pkt_buff *pkt, u8 *id) {
1144 return 0;
1147 static int8_t inf_wnm_sleep_mod(struct pkt_buff *pkt, u8 *id) {
1148 return 0;
1151 static int8_t inf_tim_bcst_req(struct pkt_buff *pkt, u8 *id) {
1152 return 0;
1155 static int8_t inf_tim_bcst_resp(struct pkt_buff *pkt, u8 *id) {
1156 return 0;
1159 static int8_t inf_coll_interf_rep(struct pkt_buff *pkt, u8 *id) {
1160 return 0;
1163 static int8_t inf_ch_usage(struct pkt_buff *pkt, u8 *id) {
1164 return 0;
1167 static int8_t inf_time_zone(struct pkt_buff *pkt, u8 *id) {
1168 return 0;
1171 static int8_t inf_dms_req(struct pkt_buff *pkt, u8 *id) {
1172 return 0;
1175 static int8_t inf_dms_resp(struct pkt_buff *pkt, u8 *id) {
1176 return 0;
1179 static int8_t inf_link_id(struct pkt_buff *pkt, u8 *id) {
1180 return 0;
1183 static int8_t inf_wakeup_sched(struct pkt_buff *pkt, u8 *id) {
1184 return 0;
1187 static int8_t inf_ch_sw_timing(struct pkt_buff *pkt, u8 *id) {
1188 return 0;
1191 static int8_t inf_pti_ctrl(struct pkt_buff *pkt, u8 *id) {
1192 return 0;
1195 static int8_t inf_tpu_buff_status(struct pkt_buff *pkt, u8 *id) {
1196 return 0;
1199 static int8_t inf_interw(struct pkt_buff *pkt, u8 *id) {
1200 return 0;
1203 static int8_t inf_adv_proto(struct pkt_buff *pkt, u8 *id) {
1204 return 0;
1207 static int8_t inf_exp_bandw_req(struct pkt_buff *pkt, u8 *id) {
1208 return 0;
1211 static int8_t inf_qos_map_set(struct pkt_buff *pkt, u8 *id) {
1212 return 0;
1215 static int8_t inf_roam_cons(struct pkt_buff *pkt, u8 *id) {
1216 return 0;
1219 static int8_t inf_emer_alert_id(struct pkt_buff *pkt, u8 *id) {
1220 return 0;
1223 static int8_t inf_mesh_conf(struct pkt_buff *pkt, u8 *id) {
1224 return 0;
1227 static int8_t inf_mesh_id(struct pkt_buff *pkt, u8 *id) {
1228 return 0;
1231 static int8_t inf_mesh_link_metr_rep(struct pkt_buff *pkt, u8 *id) {
1232 return 0;
1235 static int8_t inf_cong_notif(struct pkt_buff *pkt, u8 *id) {
1236 return 0;
1239 static int8_t inf_mesh_peer_mgmt(struct pkt_buff *pkt, u8 *id) {
1240 return 0;
1243 static int8_t inf_mesh_ch_sw_para(struct pkt_buff *pkt, u8 *id) {
1244 return 0;
1247 static int8_t inf_mesh_awake_win(struct pkt_buff *pkt, u8 *id) {
1248 return 0;
1251 static int8_t inf_beacon_timing(struct pkt_buff *pkt, u8 *id) {
1252 return 0;
1255 static int8_t inf_mccaop_setup_req(struct pkt_buff *pkt, u8 *id) {
1256 return 0;
1259 static int8_t inf_mccaop_setup_rep(struct pkt_buff *pkt, u8 *id) {
1260 return 0;
1263 static int8_t inf_mccaop_adv(struct pkt_buff *pkt, u8 *id) {
1264 return 0;
1267 static int8_t inf_mccaop_teardwn(struct pkt_buff *pkt, u8 *id) {
1268 return 0;
1271 static int8_t inf_gann(struct pkt_buff *pkt, u8 *id) {
1272 return 0;
1275 static int8_t inf_rann(struct pkt_buff *pkt, u8 *id) {
1276 return 0;
1279 static int8_t inf_ext_cap(struct pkt_buff *pkt, u8 *id) {
1280 return 0;
1283 static int8_t inf_preq(struct pkt_buff *pkt, u8 *id) {
1284 return 0;
1287 static int8_t inf_prep(struct pkt_buff *pkt, u8 *id) {
1288 return 0;
1291 static int8_t inf_perr(struct pkt_buff *pkt, u8 *id) {
1292 return 0;
1295 static int8_t inf_pxu(struct pkt_buff *pkt, u8 *id) {
1296 return 0;
1299 static int8_t inf_pxuc(struct pkt_buff *pkt, u8 *id) {
1300 return 0;
1303 static int8_t inf_auth_mesh_peer_exch(struct pkt_buff *pkt, u8 *id) {
1304 return 0;
1307 static int8_t inf_mic(struct pkt_buff *pkt, u8 *id) {
1308 return 0;
1311 static int8_t inf_dest_uri(struct pkt_buff *pkt, u8 *id) {
1312 return 0;
1315 static int8_t inf_u_apsd_coex(struct pkt_buff *pkt, u8 *id) {
1316 return 0;
1319 static int8_t inf_mccaop_adv_overv(struct pkt_buff *pkt, u8 *id) {
1320 return 0;
1323 static int8_t inf_vend_spec(struct pkt_buff *pkt, u8 *id)
1325 u8 i;
1326 u8 *data;
1327 struct element_vend_spec *vend_spec;
1329 vend_spec = (struct element_vend_spec *)
1330 pkt_pull(pkt, sizeof(*vend_spec));
1331 if (vend_spec == NULL)
1332 return 0;
1334 tprintf("Vendor Specific (%u, Len (%u)): ", *id, vend_spec->len);
1336 data = pkt_pull(pkt, vend_spec->len);
1337 if (data == NULL)
1338 return 0;
1340 tprintf("Data 0x");
1341 for (i = 0; i < vend_spec->len; i++)
1342 tprintf("%.2x", data[i]);
1344 return 1;
1347 static int8_t inf_elements(struct pkt_buff *pkt)
1349 u8 *id = pkt_pull(pkt, 1);
1350 if (id == NULL)
1351 return 0;
1353 switch (*id) {
1354 case 0: return inf_ssid(pkt, id);
1355 case 1: return inf_supp_rates(pkt, id);
1356 case 2: return inf_fh_ps(pkt, id);
1357 case 3: return inf_dsss_ps(pkt, id);
1358 case 4: return inf_cf_ps(pkt, id);
1359 case 5: return inf_tim(pkt, id);
1360 case 6: return inf_ibss_ps(pkt, id);
1361 case 7: return inf_country(pkt, id);
1362 case 8: return inf_hop_pp(pkt, id);
1363 case 9: return inf_hop_pt(pkt, id);
1364 case 10: return inf_req(pkt, id);
1365 case 11: return inf_bss_load(pkt, id);
1366 case 12: return inf_edca_ps(pkt, id);
1367 case 13: return inf_tspec(pkt, id);
1368 case 14: return inf_tclas(pkt, id);
1369 case 15: return inf_sched(pkt, id);
1370 case 16: return inf_chall_txt(pkt, id);
1371 case 17 ... 31: return inf_reserved(pkt, id);
1372 case 32: return inf_pwr_constr(pkt, id);
1373 case 33: return inf_pwr_cap(pkt, id);
1374 case 34: return inf_tpc_req(pkt, id);
1375 case 35: return inf_tpc_rep(pkt, id);
1376 case 36: return inf_supp_ch(pkt, id);
1377 case 37: return inf_ch_sw_ann(pkt, id);
1378 case 38: return inf_meas_req(pkt, id);
1379 case 39: return inf_meas_rep(pkt, id);
1380 case 40: return inf_quiet(pkt, id);
1381 case 41: return inf_ibss_dfs(pkt, id);
1382 case 42: return inf_erp(pkt, id);
1383 case 43: return inf_ts_del(pkt, id);
1384 case 44: return inf_tclas_proc(pkt, id);
1385 case 45: return inf_ht_cap(pkt, id);
1386 case 46: return inf_qos_cap(pkt, id);
1387 case 47: return inf_reserved(pkt, id);
1388 case 48: return inf_rsn(pkt, id);
1389 case 49: return inf_rsn(pkt, id);
1390 case 50: return inf_ext_supp_rates(pkt, id);
1391 case 51: return inf_ap_ch_exp(pkt, id);
1392 case 52: return inf_neighb_rep(pkt, id);
1393 case 53: return inf_rcpi(pkt, id);
1394 case 54: return inf_mde(pkt, id);
1395 case 55: return inf_fte(pkt, id);
1396 case 56: return inf_time_out_int(pkt, id);
1397 case 57: return inf_rde(pkt, id);
1398 case 58: return inf_dse_reg_loc(pkt, id);
1399 case 59: return inf_supp_op_class(pkt, id);
1400 case 60: return inf_ext_ch_sw_ann(pkt, id);
1401 case 61: return inf_ht_op(pkt, id);
1402 case 62: return inf_sec_ch_offs(pkt, id);
1403 case 63: return inf_bss_avg_acc_del(pkt, id);
1404 case 64: return inf_ant(pkt, id);
1405 case 65: return inf_rsni(pkt, id);
1406 case 66: return inf_meas_pilot_trans(pkt, id);
1407 case 67: return inf_bss_avl_adm_cap(pkt, id);
1408 case 68: return inf_bss_ac_acc_del(pkt, id);
1409 case 69: return inf_time_adv(pkt, id);
1410 case 70: return inf_rm_ena_cap(pkt, id);
1411 case 71: return inf_mult_bssid(pkt, id);
1412 case 72: return inf_20_40_bss_coex(pkt, id);
1413 case 73: return inf_20_40_bss_int_ch_rep(pkt, id);
1414 case 74: return inf_overl_bss_scan_para(pkt, id);
1415 case 75: return inf_ric_desc(pkt, id);
1416 case 76: return inf_mgmt_mic(pkt, id);
1417 case 78: return inf_ev_req(pkt, id);
1418 case 79: return inf_ev_rep(pkt, id);
1419 case 80: return inf_diagn_req(pkt, id);
1420 case 81: return inf_diagn_rep(pkt, id);
1421 case 82: return inf_loc_para(pkt, id);
1422 case 83: return inf_nontr_bssid_cap(pkt, id);
1423 case 84: return inf_ssid_list(pkt, id);
1424 case 85: return inf_mult_bssid_index(pkt, id);
1425 case 86: return inf_fms_desc(pkt, id);
1426 case 87: return inf_fms_req(pkt, id);
1427 case 88: return inf_fms_resp(pkt, id);
1428 case 89: return inf_qos_tfc_cap(pkt, id);
1429 case 90: return inf_bss_max_idle_per(pkt, id);
1430 case 91: return inf_tfs_req(pkt, id);
1431 case 92: return inf_tfs_resp(pkt, id);
1432 case 93: return inf_wnm_sleep_mod(pkt, id);
1433 case 94: return inf_tim_bcst_req(pkt, id);
1434 case 95: return inf_tim_bcst_resp(pkt, id);
1435 case 96: return inf_coll_interf_rep(pkt, id);
1436 case 97: return inf_ch_usage(pkt, id);
1437 case 98: return inf_time_zone(pkt, id);
1438 case 99: return inf_dms_req(pkt, id);
1439 case 100: return inf_dms_resp(pkt, id);
1440 case 101: return inf_link_id(pkt, id);
1441 case 102: return inf_wakeup_sched(pkt, id);
1442 case 104: return inf_ch_sw_timing(pkt, id);
1443 case 105: return inf_pti_ctrl(pkt, id);
1444 case 106: return inf_tpu_buff_status(pkt, id);
1445 case 107: return inf_interw(pkt, id);
1446 case 108: return inf_adv_proto(pkt, id);
1447 case 109: return inf_exp_bandw_req(pkt, id);
1448 case 110: return inf_qos_map_set(pkt, id);
1449 case 111: return inf_roam_cons(pkt, id);
1450 case 112: return inf_emer_alert_id(pkt, id);
1451 case 113: return inf_mesh_conf(pkt, id);
1452 case 114: return inf_mesh_id(pkt, id);
1453 case 115: return inf_mesh_link_metr_rep(pkt, id);
1454 case 116: return inf_cong_notif(pkt, id);
1455 case 117: return inf_mesh_peer_mgmt(pkt, id);
1456 case 118: return inf_mesh_ch_sw_para(pkt, id);
1457 case 119: return inf_mesh_awake_win(pkt, id);
1458 case 120: return inf_beacon_timing(pkt, id);
1459 case 121: return inf_mccaop_setup_req(pkt, id);
1460 case 122: return inf_mccaop_setup_rep(pkt, id);
1461 case 123: return inf_mccaop_adv(pkt, id);
1462 case 124: return inf_mccaop_teardwn(pkt, id);
1463 case 125: return inf_gann(pkt, id);
1464 case 126: return inf_rann(pkt, id);
1465 case 127: return inf_ext_cap(pkt, id);
1466 case 128: return inf_reserved(pkt, id);
1467 case 129: return inf_reserved(pkt, id);
1468 case 130: return inf_preq(pkt, id);
1469 case 131: return inf_prep(pkt, id);
1470 case 132: return inf_perr(pkt, id);
1471 case 133: return inf_reserved(pkt, id);
1472 case 134: return inf_reserved(pkt, id);
1473 case 135: return inf_reserved(pkt, id);
1474 case 136: return inf_reserved(pkt, id);
1475 case 137: return inf_pxu(pkt, id);
1476 case 138: return inf_pxuc(pkt, id);
1477 case 139: return inf_auth_mesh_peer_exch(pkt, id);
1478 case 140: return inf_mic(pkt, id);
1479 case 141: return inf_dest_uri(pkt, id);
1480 case 142: return inf_u_apsd_coex(pkt, id);
1481 case 143 ... 173: return inf_reserved(pkt, id);
1482 case 174: return inf_mccaop_adv_overv(pkt, id);
1483 case 221: return inf_vend_spec(pkt, id);
1486 return 0;
1489 #define ESS 0b0000000000000001
1490 #define IBSS 0b0000000000000010
1491 #define CF_Pollable 0b0000000000000100
1492 #define CF_Poll_Req 0b0000000000001000
1493 #define Privacy 0b0000000000010000
1494 #define Short_Pre 0b0000000000100000
1495 #define PBCC 0b0000000001000000
1496 #define Ch_Agility 0b0000000010000000
1497 #define Spec_Mgmt 0b0000000100000000
1498 #define QoS 0b0000001000000000
1499 #define Short_Slot_t 0b0000010000000000
1500 #define APSD 0b0000100000000000
1501 #define Radio_Meas 0b0001000000000000
1502 #define DSSS_OFDM 0b0010000000000000
1503 #define Del_Block_ACK 0b0100000000000000
1504 #define Imm_Block_ACK 0b1000000000000000
1506 static int8_t cap_field(u16 cap_inf)
1508 if (ESS & cap_inf)
1509 tprintf(" ESS;");
1510 if (IBSS & cap_inf)
1511 tprintf(" IBSS;");
1512 if (CF_Pollable & cap_inf)
1513 tprintf(" CF Pollable;");
1514 if (CF_Poll_Req & cap_inf)
1515 tprintf(" CF-Poll Request;");
1516 if (Privacy & cap_inf)
1517 tprintf(" Privacy;");
1518 if (Short_Pre & cap_inf)
1519 tprintf(" Short Preamble;");
1520 if (PBCC & cap_inf)
1521 tprintf(" PBCC;");
1522 if (Ch_Agility & cap_inf)
1523 tprintf(" Channel Agility;");
1524 if (Spec_Mgmt & cap_inf)
1525 tprintf(" Spectrum Management;");
1526 if (QoS & cap_inf)
1527 tprintf(" QoS;");
1528 if (Short_Slot_t & cap_inf)
1529 tprintf(" Short Slot Time;");
1530 if (APSD & cap_inf)
1531 tprintf(" APSD;");
1532 if (Radio_Meas & cap_inf)
1533 tprintf(" Radio Measurement;");
1534 if (DSSS_OFDM & cap_inf)
1535 tprintf(" DSSS-OFDM;");
1536 if (Del_Block_ACK & cap_inf)
1537 tprintf(" Delayed Block Ack;");
1538 if (Imm_Block_ACK & cap_inf)
1539 tprintf(" Immediate Block Ack;");
1541 return 1;
1544 /* Management Dissectors */
1545 static int8_t assoc_req(struct pkt_buff *pkt) {
1546 return 0;
1549 static int8_t assoc_resp(struct pkt_buff *pkt) {
1550 return 0;
1553 static int8_t reassoc_req(struct pkt_buff *pkt) {
1554 return 0;
1557 static int8_t reassoc_resp(struct pkt_buff *pkt) {
1558 return 0;
1561 static int8_t probe_req(struct pkt_buff *pkt) {
1562 return 0;
1565 static int8_t probe_resp(struct pkt_buff *pkt) {
1566 return 0;
1569 static int8_t beacon(struct pkt_buff *pkt)
1571 struct ieee80211_mgmt_beacon *beacon;
1573 beacon = (struct ieee80211_mgmt_beacon *)
1574 pkt_pull(pkt, sizeof(*beacon));
1575 if (beacon == NULL)
1576 return 0;
1578 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon->timestamp));
1579 tprintf("Beacon Interval (%fs), ", le16_to_cpu(beacon->beacon_int)*TU);
1580 tprintf("Capabilities (0x%x <->", le16_to_cpu(beacon->capab_info));
1581 cap_field(le16_to_cpu(beacon->capab_info));
1582 tprintf(")");
1584 if(pkt_len(pkt)) {
1585 tprintf("\n\tParameters:");
1586 while (inf_elements(pkt)) {
1587 tprintf("\n\t");
1591 if(pkt_len(pkt))
1592 return 0;
1593 return 1;
1596 static int8_t atim(struct pkt_buff *pkt) {
1597 return 0;
1600 static int8_t disassoc(struct pkt_buff *pkt) {
1601 return 0;
1604 static int8_t auth(struct pkt_buff *pkt) {
1605 return 0;
1608 static int8_t deauth(struct pkt_buff *pkt) {
1609 return 0;
1611 /* End Management Dissectors */
1613 /* Control Dissectors */
1614 static int8_t ps_poll(struct pkt_buff *pkt) {
1615 return 0;
1618 static int8_t rts(struct pkt_buff *pkt) {
1619 return 0;
1622 static int8_t cts(struct pkt_buff *pkt) {
1623 return 0;
1626 static int8_t ack(struct pkt_buff *pkt) {
1627 return 0;
1630 static int8_t cf_end(struct pkt_buff *pkt) {
1631 return 0;
1634 static int8_t cf_end_ack(struct pkt_buff *pkt) {
1635 return 0;
1637 /* End Control Dissectors */
1639 /* Data Dissectors */
1640 static int8_t data(struct pkt_buff *pkt) {
1641 return 0;
1644 static int8_t data_cf_ack(struct pkt_buff *pkt) {
1645 return 0;
1648 static int8_t data_cf_poll(struct pkt_buff *pkt) {
1649 return 0;
1652 static int8_t data_cf_ack_poll(struct pkt_buff *pkt) {
1653 return 0;
1656 static int8_t null(struct pkt_buff *pkt) {
1657 return 0;
1660 static int8_t cf_ack(struct pkt_buff *pkt) {
1661 return 0;
1664 static int8_t cf_poll(struct pkt_buff *pkt) {
1665 return 0;
1668 static int8_t cf_ack_poll(struct pkt_buff *pkt) {
1669 return 0;
1671 /* End Data Dissectors */
1673 static const char *mgt_sub(u8 subtype, struct pkt_buff *pkt,
1674 int8_t (**get_content)(struct pkt_buff *pkt))
1676 u16 seq_ctrl;
1677 struct ieee80211_mgmt *mgmt;
1678 const char *dst, *src, *bssid;
1680 mgmt = (struct ieee80211_mgmt *) pkt_pull(pkt, sizeof(*mgmt));
1681 if (mgmt == NULL)
1682 return 0;
1684 dst = lookup_vendor((mgmt->da[0] << 16) |
1685 (mgmt->da[1] << 8) |
1686 mgmt->da[2]);
1687 src = lookup_vendor((mgmt->sa[0] << 16) |
1688 (mgmt->sa[1] << 8) |
1689 mgmt->sa[2]);
1691 bssid = lookup_vendor((mgmt->bssid[0] << 16) |
1692 (mgmt->bssid[1] << 8) |
1693 mgmt->bssid[2]);
1694 seq_ctrl = le16_to_cpu(mgmt->seq_ctrl);
1696 tprintf("Duration (%u),", le16_to_cpu(mgmt->duration));
1697 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1698 mgmt->da[0], mgmt->da[1], mgmt->da[2],
1699 mgmt->da[3], mgmt->da[4], mgmt->da[5]);
1700 if (dst) {
1701 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst,
1702 mgmt->da[3], mgmt->da[4], mgmt->da[5]);
1705 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1706 mgmt->sa[0], mgmt->sa[1], mgmt->sa[2],
1707 mgmt->sa[3], mgmt->sa[4], mgmt->sa[5]);
1708 if (src) {
1709 tprintf("=> (%s:%.2x:%.2x:%.2x)", src,
1710 mgmt->sa[3], mgmt->sa[4], mgmt->sa[5]);
1713 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1714 mgmt->bssid[0], mgmt->bssid[1], mgmt->bssid[2],
1715 mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5]);
1716 if(bssid) {
1717 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid,
1718 mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5]);
1721 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ",
1722 seq_ctrl & 0xf, seq_ctrl >> 4);
1724 switch (subtype) {
1725 case 0b0000:
1726 *get_content = assoc_req;
1727 return "Association Request";
1728 case 0b0001:
1729 *get_content = assoc_resp;
1730 return "Association Response";
1731 case 0b0010:
1732 *get_content = reassoc_req;
1733 return "Reassociation Request";
1734 case 0b0011:
1735 *get_content = reassoc_resp;
1736 return "Reassociation Response";
1737 case 0b0100:
1738 *get_content = probe_req;
1739 return "Probe Request";
1740 case 0b0101:
1741 *get_content = probe_resp;
1742 return "Probe Response";
1743 case 0b1000:
1744 *get_content = beacon;
1745 return "Beacon";
1746 case 0b1001:
1747 *get_content = atim;
1748 return "ATIM";
1749 case 0b1010:
1750 *get_content = disassoc;
1751 return "Disassociation";
1752 case 0b1011:
1753 *get_content = auth;
1754 return "Authentication";
1755 case 0b1100:
1756 *get_content = deauth;
1757 return "Deauthentication";
1758 case 0b0110 ... 0b0111:
1759 case 0b1101 ... 0b1111:
1760 *get_content = NULL;
1761 return "Reserved";
1762 default:
1763 *get_content = NULL;
1764 return "Management SubType unknown";
1768 static const char *ctrl_sub(u8 subtype, struct pkt_buff *pkt,
1769 int8_t (**get_content)(struct pkt_buff *pkt))
1771 switch (subtype) {
1772 case 0b1010:
1773 *get_content = ps_poll;
1774 return "PS-Poll";
1775 case 0b1011:
1776 *get_content = rts;
1777 return "RTS";
1778 case 0b1100:
1779 *get_content = cts;
1780 return "CTS";
1781 case 0b1101:
1782 *get_content = ack;
1783 return "ACK";
1784 case 0b1110:
1785 *get_content = cf_end;
1786 return "CF End";
1787 case 0b1111:
1788 *get_content = cf_end_ack;
1789 return "CF End + CF-ACK";
1790 case 0b0000 ... 0b1001:
1791 *get_content = NULL;
1792 return "Reserved";
1793 default:
1794 return "Control SubType unkown";
1798 static const char *data_sub(u8 subtype, struct pkt_buff *pkt,
1799 int8_t (**get_content)(struct pkt_buff *pkt))
1801 switch (subtype) {
1802 case 0b0000:
1803 *get_content = data;
1804 return "Data";
1805 case 0b0001:
1806 *get_content = data_cf_ack;
1807 return "Data + CF-ACK";
1808 case 0b0010:
1809 *get_content = data_cf_poll;
1810 return "Data + CF-Poll";
1811 case 0b0011:
1812 *get_content = data_cf_ack_poll;
1813 return "Data + CF-ACK + CF-Poll";
1814 case 0b0100:
1815 *get_content = null;
1816 return "Null";
1817 case 0b0101:
1818 *get_content = cf_ack;
1819 return "CF-ACK";
1820 case 0b0110:
1821 *get_content = cf_poll;
1822 return "CF-Poll";
1823 case 0b0111:
1824 *get_content = cf_ack_poll;
1825 return "CF-ACK + CF-Poll";
1826 case 0b1000 ... 0b1111:
1827 *get_content = NULL;
1828 return "Reserved";
1829 default:
1830 *get_content = NULL;
1831 return "Data SubType unkown";
1835 static const char *
1836 frame_control_type(u8 type, const char *(**get_subtype)(u8 subtype,
1837 struct pkt_buff *pkt, int8_t (**get_content)(struct pkt_buff *pkt)))
1839 switch (type) {
1840 case 0b00:
1841 *get_subtype = mgt_sub;
1842 return "Management";
1843 case 0b01:
1844 *get_subtype = ctrl_sub;
1845 return "Control";
1846 case 0b10:
1847 *get_subtype = data_sub;
1848 return "Data";
1849 case 0b11:
1850 *get_subtype = NULL;
1851 return "Reserved";
1852 default:
1853 *get_subtype = NULL;
1854 return "Control Type unkown";
1858 static void ieee80211(struct pkt_buff *pkt)
1860 int8_t (*get_content)(struct pkt_buff *pkt) = NULL;
1861 const char *(*get_subtype)(u8 subtype, struct pkt_buff *pkt,
1862 int8_t (**get_content)(struct pkt_buff *pkt)) = NULL;
1863 const char *subtype = NULL;
1864 struct ieee80211_frm_ctrl *frm_ctrl;
1866 frm_ctrl = (struct ieee80211_frm_ctrl *)
1867 pkt_pull(pkt, sizeof(*frm_ctrl));
1868 if (frm_ctrl == NULL)
1869 return;
1871 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
1872 le16_to_cpu(frm_ctrl->frame_control));
1874 tprintf(" [ Proto Version (%u), ", frm_ctrl->proto_version);
1875 tprintf("Type (%u, %s), ", frm_ctrl->type,
1876 frame_control_type(frm_ctrl->type, &get_subtype));
1877 if (get_subtype) {
1878 subtype = (*get_subtype)(frm_ctrl->subtype, pkt, &get_content);
1879 tprintf("Subtype (%u, %s)", frm_ctrl->subtype, subtype);
1880 } else {
1881 tprintf("%s%s%s", colorize_start_full(black, red),
1882 "No SubType Data available", colorize_end());
1885 tprintf("%s%s", frm_ctrl->to_ds ? ", Frame goes to DS" : "",
1886 frm_ctrl->from_ds ? ", Frame comes from DS" : "");
1887 tprintf("%s", frm_ctrl->more_frags ? ", More Fragments" : "");
1888 tprintf("%s", frm_ctrl->retry ? ", Frame is retransmitted" : "");
1889 tprintf("%s", frm_ctrl->power_mgmt ? ", In Power Saving Mode" : "");
1890 tprintf("%s", frm_ctrl->more_data ? ", More Data" : "");
1891 tprintf("%s", frm_ctrl->wep ? ", Needs WEP" : "");
1892 tprintf("%s", frm_ctrl->order ? ", Order" : "");
1893 tprintf(" ]\n");
1895 if (get_content) {
1896 tprintf(" [ Subtype %s: ", subtype);
1897 if (!((*get_content) (pkt)))
1898 tprintf("%s%s%s", colorize_start_full(black, red),
1899 "Failed to dissect Subtype", colorize_end());
1900 tprintf(" ]");
1901 } else {
1902 tprintf("%s%s%s", colorize_start_full(black, red),
1903 "No SubType Data available", colorize_end());
1906 tprintf("\n");
1908 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
1911 static void ieee80211_less(struct pkt_buff *pkt)
1913 tprintf("802.11 frame (more on todo)");
1916 struct protocol ieee80211_ops = {
1917 .key = 0,
1918 .print_full = ieee80211,
1919 .print_less = ieee80211_less,
1922 EXPORT_SYMBOL(ieee80211_ops);