5cd714c392c174d1013f87de54d988558cebe3e4
[netsniff-ng.git] / src / proto_80211_mac_hdr.c
blob5cd714c392c174d1013f87de54d988558cebe3e4
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>
12 #include <arpa/inet.h> /* for inet_ntop() */
14 #include "proto.h"
15 #include "protos.h"
16 #include "dissector_80211.h"
17 #include "built_in.h"
18 #include "pkt_buff.h"
19 #include "oui.h"
21 #define TU 0.001024
23 /* Note: Fields are encoded in little-endian! */
24 struct ieee80211_frm_ctrl {
25 union {
26 u16 frame_control;
27 struct {
28 #if defined(__LITTLE_ENDIAN_BITFIELD)
29 /* Correct order here ... */
30 __extension__ u16 proto_version:2,
31 type:2,
32 subtype:4,
33 to_ds:1,
34 from_ds:1,
35 more_frags:1,
36 retry:1,
37 power_mgmt:1,
38 more_data:1,
39 wep:1,
40 order:1;
41 #elif defined(__BIG_ENDIAN_BITFIELD)
42 __extension__ u16 subtype:4,
43 type:2,
44 proto_version:2,
45 order:1,
46 wep:1,
47 more_data:1,
48 power_mgmt:1,
49 retry:1,
50 more_frags:1,
51 from_ds:1,
52 to_ds:1;
53 #else
54 # error "Adjust your <asm/byteorder.h> defines"
55 #endif
58 } __packed;
60 /* Management Frame start */
61 /* Note: Fields are encoded in little-endian! */
62 struct ieee80211_mgmt {
63 u16 duration;
64 u8 da[6];
65 u8 sa[6];
66 u8 bssid[6];
67 u16 seq_ctrl;
68 } __packed;
70 struct ieee80211_mgmt_auth {
71 u16 auth_alg;
72 u16 auth_transaction;
73 u16 status_code;
74 /* possibly followed by Challenge text */
75 u8 variable[0];
76 } __packed;
78 struct ieee80211_mgmt_deauth {
79 u16 reason_code;
80 } __packed;
82 struct ieee80211_mgmt_assoc_req {
83 u16 capab_info;
84 u16 listen_interval;
85 /* followed by SSID and Supported rates */
86 u8 variable[0];
87 } __packed;
89 struct ieee80211_mgmt_assoc_resp {
90 u16 capab_info;
91 u16 status_code;
92 u16 aid;
93 /* followed by Supported rates */
94 u8 variable[0];
95 } __packed;
97 struct ieee80211_mgmt_reassoc_resp {
98 u16 capab_info;
99 u16 status_code;
100 u16 aid;
101 /* followed by Supported rates */
102 u8 variable[0];
103 } __packed;
105 struct ieee80211_mgmt_reassoc_req {
106 u16 capab_info;
107 u16 listen_interval;
108 u8 current_ap[6];
109 /* followed by SSID and Supported rates */
110 u8 variable[0];
111 } __packed;
113 struct ieee80211_mgmt_disassoc {
114 u16 reason_code;
115 } __packed;
117 struct ieee80211_mgmt_probe_req {
118 } __packed;
120 struct ieee80211_mgmt_beacon {
121 u64 timestamp;
122 u16 beacon_int;
123 u16 capab_info;
124 /* followed by some of SSID, Supported rates,
125 * FH Params, DS Params, CF Params, IBSS Params, TIM */
126 u8 variable[0];
127 } __packed;
129 struct ieee80211_mgmt_probe_resp {
130 u8 timestamp[8];
131 u16 beacon_int;
132 u16 capab_info;
133 /* followed by some of SSID, Supported rates,
134 * FH Params, DS Params, CF Params, IBSS Params, TIM */
135 u8 variable[0];
136 } __packed;
137 /* Management Frame end */
139 /* Control Frame start */
140 /* Note: Fields are encoded in little-endian! */
141 struct ieee80211_ctrl {
142 } __packed;
144 struct ieee80211_ctrl_rts {
145 u16 duration;
146 u8 da[6];
147 u8 sa[6];
148 } __packed;
150 struct ieee80211_ctrl_cts {
151 u16 duration;
152 u8 da[6];
153 } __packed;
155 struct ieee80211_ctrl_ack {
156 u16 duration;
157 u8 da[6];
158 } __packed;
160 struct ieee80211_ctrl_ps_poll {
161 u16 aid;
162 u8 bssid[6];
163 u8 sa[6];
164 } __packed;
166 struct ieee80211_ctrl_cf_end {
167 u16 duration;
168 u8 bssid[6];
169 u8 sa[6];
170 } __packed;
172 struct ieee80211_ctrl_cf_end_ack {
173 u16 duration;
174 u8 bssid[6];
175 u8 sa[6];
176 } __packed;
177 /* Control Frame end */
179 /* Data Frame start */
180 /* Note: Fields are encoded in little-endian! */
181 struct ieee80211_data {
182 } __packed;
184 /* TODO: Extend */
185 /* Data Frame end */
187 /* http://www.sss-mag.com/pdf/802_11tut.pdf
188 * http://www.scribd.com/doc/78443651/111/Management-Frames
189 * http://www.wildpackets.com/resources/compendium/wireless_lan/wlan_packets
190 * http://www.rhyshaden.com/wireless.htm
193 struct element_reserved {
194 u8 len;
195 } __packed;
197 struct element_ssid {
198 u8 len;
199 u8 SSID[0];
200 } __packed;
202 struct element_supp_rates {
203 u8 len;
204 u8 SSID[0];
205 } __packed;
207 struct element_fh_ps {
208 u8 len;
209 u16 dwell_time;
210 u8 hop_set;
211 u8 hop_pattern;
212 u8 hop_index;
213 } __packed;
215 struct element_dsss_ps {
216 u8 len;
217 u8 curr_ch;
218 } __packed;
220 struct element_cf_ps {
221 u8 len;
222 u8 cfp_cnt;
223 u8 cfp_period;
224 u16 cfp_max_dur;
225 u16 cfp_dur_rem;
226 } __packed;
228 struct element_tim {
229 u8 len;
230 u8 dtim_cnt;
231 u8 dtim_period;
232 u8 bmp_cntrl;
233 u8 part_virt_bmp[0];
234 } __packed;
236 struct element_ibss_ps {
237 u8 len;
238 u16 atim_win;
239 } __packed;
241 struct element_country_tripled {
242 u8 frst_ch;
243 u8 nr_ch;
244 u8 max_trans;
245 } __packed;
247 struct element_country {
248 u8 len;
249 #if defined(__LITTLE_ENDIAN_BITFIELD)
250 /* Correct order here ... */
251 u8 country_first;
252 u8 country_sec;
253 u8 country_third;
254 #elif defined(__BIG_ENDIAN_BITFIELD)
255 u8 country_third;
256 u8 country_sec;
257 u8 country_first;
258 #else
259 # error "Adjust your <asm/byteorder.h> defines"
260 #endif
261 /* triplet may repeat */
262 struct element_country_tripled tripled [0];
263 /* end triplet */
264 u8 pad[0];
265 } __packed;
267 struct element_hop_pp {
268 u8 len;
269 u8 prime_radix;
270 u8 nr_ch;
271 } __packed;
273 struct element_hop_pt {
274 u8 len;
275 u8 flag;
276 u8 nr_sets;
277 u8 modules;
278 u8 offs;
279 u8 rand_tabl[0];
280 } __packed;
282 struct element_req {
283 u8 len;
284 u8 req_elem_idl[0];
285 } __packed;
287 struct element_bss_load {
288 u8 len;
289 u16 station_cnt;
290 u8 ch_util;
291 u16 avlb_adm_cap;
292 } __packed;
294 struct element_edca_ps {
295 u8 len;
296 u8 qos_inf;
297 u8 res;
298 u32 ac_be;
299 u32 ac_bk;
300 u32 ac_vi;
301 u32 ac_vo;
302 } __packed;
304 struct element_tspec {
305 union {
306 u32 len_ts_info;
307 struct {
308 #if defined(__LITTLE_ENDIAN_BITFIELD)
309 /* Correct order here ... */
310 __extension__ u32 len:8,
311 traffic_type:1,
312 tsid:4,
313 direction:2,
314 access_policy:2,
315 aggr:1,
316 apsid:1,
317 user_prior:3,
318 tsinfo_ack_pol:2,
319 schedule:1,
320 res:7;
321 #elif defined(__BIG_ENDIAN_BITFIELD)
322 __extension__ u32 len:8,
323 res:7,
324 schedule:1,
325 tsinfo_ack_pol:2,
326 user_prior:3,
327 apsid:1,
328 aggr:1,
329 access_policy:2,
330 direction:2,
331 tsid:4,
332 traffic_type:1;
333 #else
334 # error "Adjust your <asm/byteorder.h> defines"
335 #endif
338 u16 nom_msdu_size;
339 u16 max_msdu_size;
340 u32 min_srv_intv;
341 u32 max_srv_intv;
342 u32 inactive_intv;
343 u32 susp_intv;
344 u32 srv_start_time;
345 u32 min_data_rate;
346 u32 mean_data_rate;
347 u32 peak_data_rate;
348 u32 burst_size;
349 u32 delay_bound;
350 u32 min_phy_rate;
351 u16 surplus_bandw_allow;
352 u16 med_time;
353 } __packed;
355 struct element_tclas {
356 u8 len;
357 u8 user_priority;
358 u8 frm_class[0];
359 } __packed;
361 struct element_tclas_frm_class {
362 u8 type;
363 u8 mask;
364 u8 param[0];
365 } __packed;
367 struct element_tclas_type0 {
368 u8 sa[6];
369 u8 da[6];
370 u16 type;
371 } __packed;
373 struct element_tclas_type1 {
374 u8 version;
375 u8 subparam[0];
376 } __packed;
378 struct element_tclas_type1_ip4 {
379 u32 sa;
380 u32 da;
381 u16 sp;
382 u16 dp;
383 u8 dscp;
384 u8 proto;
385 u8 reserved;
386 } __packed;
388 struct element_tclas_type1_ip6 {
389 struct in6_addr sa;
390 struct in6_addr da;
391 u16 sp;
392 u16 dp;
393 union {
394 u8 flow_label[3];
395 struct {
396 #if defined(__LITTLE_ENDIAN_BITFIELD)
397 __extension__ u8 flow_label3:8;
398 __extension__ u8 flow_label2:8;
399 __extension__ u8 flow_label1:8;
400 #elif defined(__BIG_ENDIAN_BITFIELD)
401 __extension__ u8 flow_label1:8;
402 __extension__ u8 flow_label2:8;
403 __extension__ u8 flow_label3:8;
405 # error "Adjust your <asm/byteorder.h> defines"
406 #endif
409 } __packed;
411 struct element_tclas_type2 {
412 u16 vlan_tci;
413 } __packed;
415 struct element_tclas_type3 {
416 u16 offs;
417 u8 value[0];
418 u8 mask[0];
419 } __packed;
421 struct element_tclas_type4 {
422 u8 version;
423 u8 subparam[0];
424 } __packed;
426 struct element_tclas_type4_ip4 {
427 u32 sa;
428 u32 da;
429 u16 sp;
430 u16 dp;
431 u8 dscp;
432 u8 proto;
433 u8 reserved;
434 } __packed;
436 struct element_tclas_type4_ip6 {
437 struct in6_addr sa;
438 struct in6_addr da;
439 u16 sp;
440 u16 dp;
441 u8 dscp;
442 u8 nxt_hdr;
443 union {
444 u8 flow_label[3];
445 struct {
446 #if defined(__LITTLE_ENDIAN_BITFIELD)
447 __extension__ u8 flow_label3:8;
448 __extension__ u8 flow_label2:8;
449 __extension__ u8 flow_label1:8;
450 #elif defined(__BIG_ENDIAN_BITFIELD)
451 __extension__ u8 flow_label1:8;
452 __extension__ u8 flow_label2:8;
453 __extension__ u8 flow_label3:8;
455 # error "Adjust your <asm/byteorder.h> defines"
456 #endif
459 } __packed;
461 struct element_tclas_type5 {
462 u8 pcp;
463 u8 cfi;
464 u8 vid;
465 } __packed;
467 struct element_erp {
468 u8 len;
469 u8 param;
470 } __packed;
472 struct element_ext_supp_rates {
473 u8 len;
474 u8 rates[0];
475 } __packed;
477 struct element_vend_spec {
478 u8 len;
479 u8 oui[0];
480 u8 specific[0];
481 } __packed;
483 static int8_t len_neq_error(u8 len, u8 intended)
485 if(intended != len) {
486 tprintf("Length should be %u Bytes", intended);
487 return 1;
490 return 0;
493 static int8_t len_lt_error(u8 len, u8 intended)
495 if(len < intended) {
496 tprintf("Length should be greater %u Bytes", intended);
497 return 1;
500 return 0;
503 static float data_rates(u8 id)
505 /* XXX Why not (id / 2.f)? */
506 switch (id) {
507 case 2: return 1.0f;
508 case 3: return 1.5f;
509 case 4: return 2.0f;
510 case 5: return 2.5f;
511 case 6: return 3.0f;
512 case 9: return 4.5f;
513 case 11: return 5.5f;
514 case 12: return 6.0f;
515 case 18: return 9.0f;
516 case 22: return 11.0f;
517 case 24: return 12.0f;
518 case 27: return 13.5f;
519 case 36: return 18.0f;
520 case 44: return 22.0f;
521 case 48: return 24.0f;
522 case 54: return 27.0f;
523 case 66: return 33.0f;
524 case 72: return 36.0f;
525 case 96: return 48.0f;
526 case 108: return 54.0f;
529 return 0.f;
532 static int8_t inf_reserved(struct pkt_buff *pkt, u8 *id)
534 u8 i;
535 u8 *data;
536 struct element_reserved *reserved;
538 reserved = (struct element_reserved *) pkt_pull(pkt, sizeof(*reserved));
539 if (reserved == NULL)
540 return 0;
542 tprintf("Reserved (%u, Len (%u)): ", *id, reserved->len);
544 data = pkt_pull(pkt, reserved->len);
545 if (data == NULL)
546 return 0;
548 tprintf("Data 0x");
549 for (i = 0; i < reserved->len; i++)
550 tprintf("%.2x", data[i]);
552 return 1;
555 static int8_t inf_ssid(struct pkt_buff *pkt, u8 *id)
557 u8 i;
558 struct element_ssid *ssid;
559 char *ssid_name;
561 ssid = (struct element_ssid *) pkt_pull(pkt, sizeof(*ssid));
562 if (ssid == NULL)
563 return 0;
565 tprintf(" SSID (%u, Len (%u)): ", *id, ssid->len);
567 if ((ssid->len - sizeof(*ssid) + 1) > 0) {
568 ssid_name = (char *) pkt_pull(pkt, ssid->len);
569 if (ssid_name == NULL)
570 return 0;
572 for (i = 0; i < ssid->len; i++)
573 tprintf("%c",ssid_name[i]);
574 } else {
575 tprintf("Wildcard SSID");
578 return 1;
581 static int8_t inf_supp_rates(struct pkt_buff *pkt, u8 *id)
583 u8 i;
584 u8 *rates;
585 struct element_supp_rates *supp_rates;
587 supp_rates = (struct element_supp_rates *)
588 pkt_pull(pkt, sizeof(*supp_rates));
589 if (supp_rates == NULL)
590 return 0;
592 tprintf("Rates (%u, Len (%u)): ", *id, supp_rates->len);
593 if (len_lt_error(supp_rates->len, 1))
594 return 0;
596 if ((supp_rates->len - sizeof(*supp_rates) + 1) > 0) {
597 rates = pkt_pull(pkt, supp_rates->len);
598 if (rates == NULL)
599 return 0;
601 for (i = 0; i < supp_rates->len; i++)
602 tprintf("%g ", (rates[i] & 0x80) ?
603 ((rates[i] & 0x3f) * 0.5) :
604 data_rates(rates[i]));
605 return 1;
608 return 0;
611 static int8_t inf_fh_ps(struct pkt_buff *pkt, u8 *id)
613 struct element_fh_ps *fh_ps;
615 fh_ps = (struct element_fh_ps *) pkt_pull(pkt, sizeof(*fh_ps));
616 if (fh_ps == NULL)
617 return 0;
619 tprintf("FH Param Set (%u, Len(%u)): ", *id, fh_ps->len);
620 if (len_neq_error(fh_ps->len, 5))
621 return 0;
622 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps->dwell_time) * TU);
623 tprintf("HopSet: %u, ", fh_ps->hop_set);
624 tprintf("HopPattern: %u, ", fh_ps->hop_pattern);
625 tprintf("HopIndex: %u", fh_ps->hop_index);
627 return 1;
630 static int8_t inf_dsss_ps(struct pkt_buff *pkt, u8 *id)
632 struct element_dsss_ps *dsss_ps;
634 dsss_ps = (struct element_dsss_ps *) pkt_pull(pkt, sizeof(*dsss_ps));
635 if (dsss_ps == NULL)
636 return 0;
638 tprintf("DSSS Param Set (%u, Len(%u)): ", *id, dsss_ps->len);
639 if (len_neq_error(dsss_ps->len, 1))
640 return 0;
641 tprintf("Current Channel: %u", dsss_ps->curr_ch);
643 return 1;
646 static int8_t inf_cf_ps(struct pkt_buff *pkt, u8 *id)
648 struct element_cf_ps *cf_ps;
650 cf_ps = (struct element_cf_ps *) pkt_pull(pkt, sizeof(*cf_ps));
651 if (cf_ps == NULL)
652 return 0;
654 tprintf("CF Param Set (%u, Len(%u)): ", *id, cf_ps->len);
655 if (len_neq_error(cf_ps->len, 6))
656 return 0;
657 tprintf("CFP Count: %u, ", cf_ps->cfp_cnt);
658 tprintf("CFP Period: %u, ", cf_ps->cfp_period);
659 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps->cfp_max_dur) * TU);
660 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps->cfp_dur_rem) * TU);
662 return 1;
665 static int8_t inf_tim(struct pkt_buff *pkt, u8 *id)
667 struct element_tim *tim;
669 tim = (struct element_tim *) pkt_pull(pkt, sizeof(*tim));
670 if (tim == NULL)
671 return 0;
673 tprintf("TIM (%u, Len(%u)): ", *id, tim->len);
674 if (len_lt_error(tim->len, 3))
675 return 0;
676 tprintf("DTIM Count: %u, ", tim->dtim_cnt);
677 tprintf("DTIM Period: %u, ", tim->dtim_period);
678 tprintf("Bitmap Control: %u, ", tim->bmp_cntrl);
679 if ((tim->len - sizeof(*tim) + 1) > 0) {
680 u8 *bmp = pkt_pull(pkt, (tim->len - sizeof(*tim) + 1));
681 if (bmp == NULL)
682 return 0;
684 tprintf("Partial Virtual Bitmap: 0x");
685 for(u8 i=0; i < (tim->len - sizeof(*tim) + 1); i++)
686 tprintf("%.2x ", bmp[i]);
689 return 1;
692 static int8_t inf_ibss_ps(struct pkt_buff *pkt, u8 *id)
694 struct element_ibss_ps *ibss_ps;
696 ibss_ps = (struct element_ibss_ps *) pkt_pull(pkt, sizeof(*ibss_ps));
697 if (ibss_ps == NULL)
698 return 0;
700 tprintf("IBSS Param Set (%u, Len(%u)): ", *id, ibss_ps->len);
701 if (len_neq_error(ibss_ps->len, 2))
702 return 0;
703 tprintf("ATIM Window: %fs", le16_to_cpu(ibss_ps->atim_win) * TU);
705 return 1;
708 static int8_t inf_country(struct pkt_buff *pkt, u8 *id)
710 u8 i;
711 u8 *pad;
712 struct element_country *country;
714 country = (struct element_country *) pkt_pull(pkt, sizeof(*country));
715 if (country == NULL)
716 return 0;
718 tprintf("Country (%u, Len(%u)): ", *id, country->len);
719 if (len_lt_error(country->len, 6))
720 return 0;
721 tprintf("Country String: %c%c%c", country->country_first,
722 country->country_sec, country->country_third);
724 for (i = 0; i < (country->len - 3); i += 3) {
725 struct element_country_tripled *country_tripled;
727 country_tripled = (struct element_country_tripled *)
728 pkt_pull(pkt, sizeof(*country_tripled));
729 if (country_tripled == NULL)
730 return 0;
732 if(country_tripled->frst_ch >= 201) {
733 tprintf("Oper Ext ID: %u, ", country_tripled->frst_ch);
734 tprintf("Operating Class: %u, ", country_tripled->nr_ch);
735 tprintf("Coverage Class: %u", country_tripled->max_trans);
736 } else {
737 tprintf("First Ch Nr: %u, ", country_tripled->frst_ch);
738 tprintf("Nr of Ch: %u, ", country_tripled->nr_ch);
739 tprintf("Max Transmit Pwr Lvl: %u", country_tripled->max_trans);
743 if(country->len % 2) {
744 pad = pkt_pull(pkt, 1);
745 if (pad == NULL)
746 return 0;
748 tprintf(", Pad: 0x%x", *pad);
751 return 1;
754 static int8_t inf_hop_pp(struct pkt_buff *pkt, u8 *id)
756 struct element_hop_pp *hop_pp;
758 hop_pp = (struct element_hop_pp *) pkt_pull(pkt, sizeof(*hop_pp));
759 if (hop_pp == NULL)
760 return 0;
762 tprintf("Hopping Pattern Param (%u, Len(%u)): ", *id, hop_pp->len);
763 if (len_neq_error(hop_pp->len, 2))
764 return 0;
765 tprintf("Nr of Ch: %u", hop_pp->nr_ch);
767 return 1;
770 static int8_t inf_hop_pt(struct pkt_buff *pkt, u8 *id)
772 int i;
773 u8 *rand_tabl;
774 struct element_hop_pt *hop_pt;
776 hop_pt = (struct element_hop_pt *) pkt_pull(pkt, sizeof(*hop_pt));
777 if (hop_pt == NULL)
778 return 0;
780 tprintf("Hopping Pattern Table (%u, Len(%u)): ", *id, hop_pt->len);
781 if (len_lt_error(hop_pt->len, 4))
782 return 0;
783 tprintf("Flag: %u, ", hop_pt->flag);
784 tprintf("Nr of Sets: %u, ", hop_pt->nr_sets);
785 tprintf("Modules: %u, ", hop_pt->modules);
786 tprintf("Offs: %u", hop_pt->offs);
788 if ((hop_pt->len - sizeof(*hop_pt) + 1) > 0) {
789 rand_tabl = pkt_pull(pkt, (hop_pt->len - sizeof(*hop_pt) + 1));
790 if (rand_tabl == NULL)
791 return 0;
793 tprintf(", Rand table: 0x");
794 for (i = 0; i < (hop_pt->len - sizeof(*hop_pt) + 1); i++)
795 tprintf("%.2x ", rand_tabl[i]);
798 return 1;
801 static int8_t inf_req(struct pkt_buff *pkt, u8 *id)
803 int i;
804 struct element_req *req;
805 u8 *req_ids;
807 req = (struct element_req *) pkt_pull(pkt, sizeof(*req));
808 if (req == NULL)
809 return 0;
811 tprintf("Request Element (%u, Len(%u)): ", *id, req->len);
812 if ((req->len - sizeof(*req) + 1) > 0) {
813 req_ids = pkt_pull(pkt, (req->len - sizeof(*req) + 1));
814 if (req_ids == NULL)
815 return 0;
817 tprintf(", Requested Element IDs: ");
818 for (i = 0; i < (req->len - sizeof(*req) + 1); i++)
819 tprintf("%u ", req_ids[i]);
822 return 1;
825 static int8_t inf_bss_load(struct pkt_buff *pkt, u8 *id)
827 struct element_bss_load *bss_load;
829 bss_load = (struct element_bss_load *) pkt_pull(pkt, sizeof(*bss_load));
830 if (bss_load == NULL)
831 return 0;
833 tprintf("BSS Load element (%u, Len(%u)): ", *id, bss_load->len);
834 if (len_neq_error(bss_load->len, 5))
835 return 0;
836 tprintf("Station Count: %u, ", le16_to_cpu(bss_load->station_cnt));
837 tprintf("Channel Utilization: %u, ", bss_load->ch_util);
838 tprintf("Available Admission Capacity: %uus",
839 bss_load->avlb_adm_cap * 32);
841 return 1;
844 static int8_t inf_edca_ps(struct pkt_buff *pkt, u8 *id)
846 u32 ac_be, ac_bk, ac_vi, ac_vo;
847 struct element_edca_ps *edca_ps;
849 edca_ps = (struct element_edca_ps *) pkt_pull(pkt, sizeof(*edca_ps));
850 if (edca_ps == NULL)
851 return 0;
853 ac_be = le32_to_cpu(edca_ps->ac_be);
854 ac_bk = le32_to_cpu(edca_ps->ac_bk);
855 ac_vi = le32_to_cpu(edca_ps->ac_vi);
856 ac_vo = le32_to_cpu(edca_ps->ac_vo);
858 tprintf("EDCA Param Set (%u, Len(%u)): ", *id, edca_ps->len);
859 if (len_neq_error(edca_ps->len, 18))
860 return 0;
861 tprintf("QoS Info: 0x%x (-> EDCA Param Set Update Count (%u),"
862 "Q-Ack (%u), Queue Re (%u), TXOP Req(%u), Res(%u)), ",
863 edca_ps->qos_inf, edca_ps->qos_inf >> 4,
864 (edca_ps->qos_inf >> 3) & 1, (edca_ps->qos_inf >> 2) & 1,
865 (edca_ps->qos_inf >> 1) & 1, edca_ps->qos_inf & 1);
866 tprintf("Reserved: 0x%x, ", edca_ps->res);
867 tprintf("AC_BE Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
868 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_be,
869 ac_be >> 28, (ac_be >> 27) & 1, (ac_be >> 25) & 3,
870 (ac_be >> 24) & 1, (ac_be >> 20) & 15, (ac_be >> 16) & 15,
871 bswap_16(ac_be & 0xFFFF) * 32);
872 tprintf("AC_BK Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
873 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_bk,
874 ac_bk >> 28, (ac_bk >> 27) & 1, (ac_bk >> 25) & 3,
875 (ac_bk >> 24) & 1, (ac_bk >> 20) & 15, (ac_bk >> 16) & 15,
876 bswap_16(ac_bk & 0xFFFF) * 32);
877 tprintf("AC_VI Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
878 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_vi,
879 ac_vi >> 28, (ac_vi >> 27) & 1, (ac_vi >> 25) & 3,
880 (ac_vi >> 24) & 1, (ac_vi >> 20) & 15, (ac_vi >> 16) & 15,
881 bswap_16(ac_vi & 0xFFFF) * 32);
882 tprintf("AC_VO Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
883 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)", ac_vo,
884 ac_vo >> 28, (ac_vo >> 27) & 1, (ac_vo >> 25) & 3,
885 (ac_vo >> 24) & 1, (ac_vo >> 20) & 15, (ac_vo >> 16) & 15,
886 bswap_16(ac_vo & 0xFFFF) * 32);
888 return 1;
891 static int8_t inf_tspec(struct pkt_buff *pkt, u8 *id)
893 u16 nom_msdu_size, surplus_bandw_allow;
894 struct element_tspec *tspec;
896 tspec = (struct element_tspec *) pkt_pull(pkt, sizeof(*tspec));
897 if (tspec == NULL)
898 return 0;
900 nom_msdu_size = le16_to_cpu(tspec->nom_msdu_size);
901 surplus_bandw_allow = le16_to_cpu(tspec->surplus_bandw_allow);
903 tprintf("TSPEC (%u, Len(%u)): ", *id, tspec->len);
904 if (len_neq_error(tspec->len, 55))
905 return 0;
906 tprintf("Traffic Type: %u, ", tspec->traffic_type);
907 tprintf("TSID: %u, ", tspec->tsid);
908 tprintf("Direction: %u, ", tspec->direction);
909 tprintf("Access Policy: %u, ", tspec->access_policy);
910 tprintf("Aggregation: %u, ", tspec->aggr);
911 tprintf("User Priority: %u, ", tspec->user_prior);
912 tprintf("TSinfo Ack Policy: %u, ", tspec->tsinfo_ack_pol);
913 tprintf("Schedule: %u, ", tspec->schedule);
914 tprintf("Reserved: 0x%x, ", tspec->res);
915 tprintf("Nominal MSDU Size: %uB (Fixed (%u)), ",
916 nom_msdu_size >> 1, nom_msdu_size & 1);
917 tprintf("Maximum MSDU Size: %uB, ", le16_to_cpu(tspec->max_msdu_size));
918 tprintf("Minimum Service Interval: %uus, ",
919 le32_to_cpu(tspec->min_srv_intv));
920 tprintf("Maximum Service Interval: %uus, ",
921 le32_to_cpu(tspec->max_srv_intv));
922 tprintf("Inactivity Interval: %uus, ",
923 le32_to_cpu(tspec->inactive_intv));
924 tprintf("Suspension Interval: %uus, ", le32_to_cpu(tspec->susp_intv));
925 tprintf("Service Start Time: %uus, ",
926 le32_to_cpu(tspec->srv_start_time));
927 tprintf("Minimum Data Rate: %ub/s, ",le32_to_cpu(tspec->min_data_rate));
928 tprintf("Mean Data Rate: %ub/s, ", le32_to_cpu(tspec->mean_data_rate));
929 tprintf("Peak Data Rate: %ub/s, ",le32_to_cpu(tspec->peak_data_rate));
930 tprintf("Burst Size: %uB, ", le32_to_cpu(tspec->burst_size));
931 tprintf("Delay Bound: %uus, ", le32_to_cpu(tspec->delay_bound));
932 tprintf("Minimum PHY Rate: %ub/s, ", le32_to_cpu(tspec->min_phy_rate));
933 tprintf("Surplus Bandwidth: %u.%u, ", surplus_bandw_allow >> 13,
934 surplus_bandw_allow & 0x1FFF);
935 tprintf("Medium Time: %uus", le16_to_cpu(tspec->med_time) * 32);
937 return 1;
940 static const char *class_type(u8 type)
942 switch (type) {
943 case 0: return "Ethernet parameters";
944 case 1: return "TCP/UDP IP parameters";
945 case 2: return "IEEE 802.1Q parameters";
946 case 3: return "Filter Offset parameters";
947 case 4: return "IP and higher layer parameters";
948 case 5: return "IEEE 802.1D/Q parameters";
949 default: return "Reserved";
953 static int8_t inf_tclas(struct pkt_buff *pkt, u8 *id)
955 struct element_tclas *tclas;
956 struct element_tclas_frm_class *frm_class;
958 tclas = (struct element_tclas *) pkt_pull(pkt, sizeof(*tclas));
959 if (tclas == NULL)
960 return 0;
962 frm_class = (struct element_tclas_frm_class *)
963 pkt_pull(pkt, sizeof(*frm_class));
964 if (frm_class == NULL)
965 return 0;
967 tprintf("TCLAS (%u, Len(%u)): ", *id, tclas->len);
968 if (len_lt_error(tclas->len, 3))
969 return 0;
970 tprintf("User Priority: %u, ", tclas->user_priority);
971 tprintf("Classifier Type: %s (%u), ", class_type(frm_class->type),
972 frm_class->type);
973 tprintf("Classifier Mask: 0x%x, ", frm_class->mask);
975 if(frm_class->type == 0) {
976 struct element_tclas_type0 *type0;
978 type0 = (struct element_tclas_type0 *)
979 pkt_pull(pkt, sizeof(*type0));
980 if (type0 == NULL)
981 return 0;
983 /* I think little endian, like the rest */
984 tprintf("Src Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
985 type0->sa[5], type0->sa[4], type0->sa[3],
986 type0->sa[2], type0->sa[1], type0->sa[0]);
987 tprintf("Dst Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
988 type0->da[5], type0->da[4], type0->da[3],
989 type0->da[2], type0->da[1], type0->da[0]);
990 tprintf("Type: 0x%x", le16_to_cpu(type0->type));
992 else if(frm_class->type == 1) {
993 struct element_tclas_type1 *type1;
995 type1 = (struct element_tclas_type1 *)
996 pkt_pull(pkt, sizeof(*type1));
997 if (type1 == NULL)
998 return 0;
1000 tprintf("Version: %u, ", type1->version);
1001 /* big endian format follows */
1002 if(type1->version == 4) {
1003 struct element_tclas_type1_ip4 *type1_ip4;
1004 char src_ip[INET_ADDRSTRLEN];
1005 char dst_ip[INET_ADDRSTRLEN];
1007 type1_ip4 = (struct element_tclas_type1_ip4 *)
1008 pkt_pull(pkt, sizeof(*type1_ip4));
1009 if (type1_ip4 == NULL)
1010 return 0;
1012 inet_ntop(AF_INET, &type1_ip4->sa, src_ip, sizeof(src_ip));
1013 inet_ntop(AF_INET, &type1_ip4->da, dst_ip, sizeof(dst_ip));
1015 tprintf("Src IP: %s, ", src_ip);
1016 tprintf("Dst IP: %s, ", dst_ip);
1017 tprintf("Src Port: %u, ", ntohs(type1_ip4->sp));
1018 tprintf("Dst Port: %u, ", ntohs(type1_ip4->dp));
1019 tprintf("DSCP: 0x%x, ", type1_ip4->dscp);
1020 tprintf("Proto: %u, ", type1_ip4->proto);
1021 tprintf("Res: 0x%x", type1_ip4->reserved);
1023 else if(type1->version == 6) {
1024 struct element_tclas_type1_ip6 *type1_ip6;
1025 char src_ip[INET6_ADDRSTRLEN];
1026 char dst_ip[INET6_ADDRSTRLEN];
1028 type1_ip6 = (struct element_tclas_type1_ip6 *)
1029 pkt_pull(pkt, sizeof(*type1_ip6));
1030 if (type1_ip6 == NULL)
1031 return 0;
1033 inet_ntop(AF_INET6, &type1_ip6->sa,
1034 src_ip, sizeof(src_ip));
1035 inet_ntop(AF_INET6, &type1_ip6->da,
1036 dst_ip, sizeof(dst_ip));
1038 tprintf("Src IP: %s, ", src_ip);
1039 tprintf("Dst IP: %s, ", dst_ip);
1040 tprintf("Src Port: %u, ", ntohs(type1_ip6->sp));
1041 tprintf("Dst Port: %u, ", ntohs(type1_ip6->dp));
1042 tprintf("Flow Label: 0x%x%x%x", type1_ip6->flow_label1,
1043 type1_ip6->flow_label2, type1_ip6->flow_label3);
1045 else {
1046 tprintf("Version (%u) not supported", type1->version);
1047 return 0;
1051 else if(frm_class->type == 2) {
1052 struct element_tclas_type2 *type2;
1054 type2 = (struct element_tclas_type2 *)
1055 pkt_pull(pkt, sizeof(*type2));
1056 if (type2 == NULL)
1057 return 0;
1059 tprintf("802.1Q VLAN TCI: 0x%x", ntohs(type2->vlan_tci));
1061 else if(frm_class->type == 3) {
1062 struct element_tclas_type3 *type3;
1063 u8 len;
1064 u8 *val;
1066 type3 = (struct element_tclas_type3 *)
1067 pkt_pull(pkt, sizeof(*type3));
1068 if (type3 == NULL)
1069 return 0;
1071 len = (tclas->len - 5) / 2;
1073 tprintf("Filter Offset: %u, ", type3->offs);
1075 if((len & 1) || (len_lt_error(tclas->len, 5))) {
1076 tprintf("Length of TCLAS (%u) not correct", tclas->len);
1077 return 0;
1079 else {
1080 val = pkt_pull(pkt, len);
1081 if (val == NULL)
1082 return 0;
1084 tprintf("Filter Value: 0x");
1085 for (u8 i = 0; i < len / 2; i++)
1086 tprintf("%x ", val[i]);
1087 tprintf(", ");
1088 tprintf("Filter Mask: 0x");
1089 for (u8 i = len / 2; i < len; i++)
1090 tprintf("%x ", val[i]);
1094 else if(frm_class->type == 4) {
1095 struct element_tclas_type4 *type4;
1097 type4 = (struct element_tclas_type4 *)
1098 pkt_pull(pkt, sizeof(*type4));
1099 if (type4 == NULL)
1100 return 0;
1102 tprintf("Version: %u, ", type4->version);
1103 /* big endian format follows */
1104 if(type4->version == 4) {
1105 struct element_tclas_type4_ip4 *type4_ip4;
1106 char src_ip[INET_ADDRSTRLEN];
1107 char dst_ip[INET_ADDRSTRLEN];
1109 type4_ip4 = (struct element_tclas_type4_ip4 *)
1110 pkt_pull(pkt, sizeof(*type4_ip4));
1111 if (type4_ip4 == NULL)
1112 return 0;
1114 inet_ntop(AF_INET, &type4_ip4->sa, src_ip, sizeof(src_ip));
1115 inet_ntop(AF_INET, &type4_ip4->da, dst_ip, sizeof(dst_ip));
1117 tprintf("Src IP: %s, ", src_ip);
1118 tprintf("Dst IP: %s, ", dst_ip);
1119 tprintf("Src Port: %u, ", ntohs(type4_ip4->sp));
1120 tprintf("Dst Port: %u, ", ntohs(type4_ip4->dp));
1121 tprintf("DSCP: 0x%x, ", type4_ip4->dscp);
1122 tprintf("Proto: %u, ", type4_ip4->proto);
1123 tprintf("Res: 0x%x", type4_ip4->reserved);
1125 else if(type4->version == 6) {
1126 struct element_tclas_type4_ip6 *type4_ip6;
1127 char src_ip[INET6_ADDRSTRLEN];
1128 char dst_ip[INET6_ADDRSTRLEN];
1130 type4_ip6 = (struct element_tclas_type4_ip6 *)
1131 pkt_pull(pkt, sizeof(*type4_ip6));
1132 if (type4_ip6 == NULL)
1133 return 0;
1135 inet_ntop(AF_INET6, &type4_ip6->sa,
1136 src_ip, sizeof(src_ip));
1137 inet_ntop(AF_INET6, &type4_ip6->da,
1138 dst_ip, sizeof(dst_ip));
1140 tprintf("Src IP: %s, ", src_ip);
1141 tprintf("Dst IP: %s, ", dst_ip);
1142 tprintf("Src Port: %u, ", ntohs(type4_ip6->sp));
1143 tprintf("Dst Port: %u, ", ntohs(type4_ip6->dp));
1144 tprintf("DSCP: 0x%x, ", type4_ip6->dscp);
1145 tprintf("Nxt Hdr: %u, ", type4_ip6->nxt_hdr);
1146 tprintf("Flow Label: 0x%x%x%x", type4_ip6->flow_label1,
1147 type4_ip6->flow_label2, type4_ip6->flow_label3);
1149 else {
1150 tprintf("Version (%u) not supported", type4->version);
1151 return 0;
1154 else if(frm_class->type == 5) {
1155 struct element_tclas_type5 *type5;
1157 type5 = (struct element_tclas_type5 *)
1158 pkt_pull(pkt, sizeof(*type5));
1159 if (type5 == NULL)
1160 return 0;
1162 tprintf("802.1Q PCP: 0x%x, ", type5->pcp);
1163 tprintf("802.1Q CFI: 0x%x, ", type5->cfi);
1164 tprintf("802.1Q VID: 0x%x", type5->vid);
1166 else {
1167 tprintf("Classifier Type (%u) not supported", frm_class->type);
1168 return 0;
1171 return 1;
1174 static int8_t inf_sched(struct pkt_buff *pkt, u8 *id)
1176 return 0;
1179 static int8_t inf_chall_txt(struct pkt_buff *pkt, u8 *id)
1181 return 0;
1184 static int8_t inf_pwr_constr(struct pkt_buff *pkt, u8 *id)
1186 return 0;
1189 static int8_t inf_pwr_cap(struct pkt_buff *pkt, u8 *id)
1191 return 0;
1194 static int8_t inf_tpc_req(struct pkt_buff *pkt, u8 *id)
1196 return 0;
1199 static int8_t inf_tpc_rep(struct pkt_buff *pkt, u8 *id)
1201 return 0;
1204 static int8_t inf_supp_ch(struct pkt_buff *pkt, u8 *id)
1206 return 0;
1209 static int8_t inf_ch_sw_ann(struct pkt_buff *pkt, u8 *id)
1211 return 0;
1214 static int8_t inf_meas_req(struct pkt_buff *pkt, u8 *id)
1216 return 0;
1219 static int8_t inf_meas_rep(struct pkt_buff *pkt, u8 *id)
1221 return 0;
1224 static int8_t inf_quiet(struct pkt_buff *pkt, u8 *id)
1226 return 0;
1229 static int8_t inf_ibss_dfs(struct pkt_buff *pkt, u8 *id)
1231 return 0;
1234 static int8_t inf_erp(struct pkt_buff *pkt, u8 *id)
1236 struct element_erp *erp;
1238 erp = (struct element_erp *) pkt_pull(pkt, sizeof(*erp));
1239 if (erp == NULL)
1240 return 0;
1242 tprintf("ERP (%u, Len(%u)): ", *id, erp->len);
1243 if (len_neq_error(erp->len, 1))
1244 return 0;
1245 tprintf("Non ERP Present (%u), ", erp->param & 0x1);
1246 tprintf("Use Protection (%u), ", (erp->param >> 1) & 0x1);
1247 tprintf("Barker Preamble Mode (%u), ", (erp->param >> 2) & 0x1);
1248 tprintf("Reserved (0x%.5x)", erp->param >> 3);
1250 return 1;
1253 static int8_t inf_ts_del(struct pkt_buff *pkt, u8 *id)
1255 return 0;
1258 static int8_t inf_tclas_proc(struct pkt_buff *pkt, u8 *id)
1260 return 0;
1263 static int8_t inf_ht_cap(struct pkt_buff *pkt, u8 *id)
1265 return 0;
1268 static int8_t inf_qos_cap(struct pkt_buff *pkt, u8 *id)
1270 return 0;
1273 static int8_t inf_rsn(struct pkt_buff *pkt, u8 *id)
1275 return 0;
1278 static int8_t inf_ext_supp_rates(struct pkt_buff *pkt, u8 *id)
1280 u8 i;
1281 u8 *rates;
1282 struct element_ext_supp_rates *ext_supp_rates;
1284 ext_supp_rates = (struct element_ext_supp_rates *)
1285 pkt_pull(pkt, sizeof(*ext_supp_rates));
1286 if (ext_supp_rates == NULL)
1287 return 0;
1289 tprintf("Ext Support Rates (%u, Len(%u)): ", *id, ext_supp_rates->len);
1291 if ((ext_supp_rates->len - sizeof(*ext_supp_rates) + 1) > 0) {
1292 rates = pkt_pull(pkt, ext_supp_rates->len);
1293 if (rates == NULL)
1294 return 0;
1296 for (i = 0; i < ext_supp_rates->len; i++)
1297 tprintf("%g ", (rates[i] & 0x80) ?
1298 ((rates[i] & 0x3f) * 0.5) :
1299 data_rates(rates[i]));
1300 return 1;
1303 return 0;
1306 static int8_t inf_ap_ch_exp(struct pkt_buff *pkt, u8 *id) {
1307 return 0;
1310 static int8_t inf_neighb_rep(struct pkt_buff *pkt, u8 *id) {
1311 return 0;
1314 static int8_t inf_rcpi(struct pkt_buff *pkt, u8 *id) {
1315 return 0;
1318 static int8_t inf_mde(struct pkt_buff *pkt, u8 *id) {
1319 return 0;
1322 static int8_t inf_fte(struct pkt_buff *pkt, u8 *id) {
1323 return 0;
1326 static int8_t inf_time_out_int(struct pkt_buff *pkt, u8 *id) {
1327 return 0;
1330 static int8_t inf_rde(struct pkt_buff *pkt, u8 *id) {
1331 return 0;
1334 static int8_t inf_dse_reg_loc(struct pkt_buff *pkt, u8 *id) {
1335 return 0;
1338 static int8_t inf_supp_op_class(struct pkt_buff *pkt, u8 *id) {
1339 return 0;
1342 static int8_t inf_ext_ch_sw_ann(struct pkt_buff *pkt, u8 *id) {
1343 return 0;
1346 static int8_t inf_ht_op(struct pkt_buff *pkt, u8 *id) {
1347 return 0;
1350 static int8_t inf_sec_ch_offs(struct pkt_buff *pkt, u8 *id) {
1351 return 0;
1354 static int8_t inf_bss_avg_acc_del(struct pkt_buff *pkt, u8 *id) {
1355 return 0;
1358 static int8_t inf_ant(struct pkt_buff *pkt, u8 *id) {
1359 return 0;
1362 static int8_t inf_rsni(struct pkt_buff *pkt, u8 *id) {
1363 return 0;
1366 static int8_t inf_meas_pilot_trans(struct pkt_buff *pkt, u8 *id) {
1367 return 0;
1370 static int8_t inf_bss_avl_adm_cap(struct pkt_buff *pkt, u8 *id) {
1371 return 0;
1374 static int8_t inf_bss_ac_acc_del(struct pkt_buff *pkt, u8 *id) {
1375 return 0;
1378 static int8_t inf_time_adv(struct pkt_buff *pkt, u8 *id) {
1379 return 0;
1382 static int8_t inf_rm_ena_cap(struct pkt_buff *pkt, u8 *id) {
1383 return 0;
1386 static int8_t inf_mult_bssid(struct pkt_buff *pkt, u8 *id) {
1387 return 0;
1390 static int8_t inf_20_40_bss_coex(struct pkt_buff *pkt, u8 *id) {
1391 return 0;
1394 static int8_t inf_20_40_bss_int_ch_rep(struct pkt_buff *pkt, u8 *id) {
1395 return 0;
1398 static int8_t inf_overl_bss_scan_para(struct pkt_buff *pkt, u8 *id) {
1399 return 0;
1402 static int8_t inf_ric_desc(struct pkt_buff *pkt, u8 *id) {
1403 return 0;
1406 static int8_t inf_mgmt_mic(struct pkt_buff *pkt, u8 *id) {
1407 return 0;
1410 static int8_t inf_ev_req(struct pkt_buff *pkt, u8 *id) {
1411 return 0;
1414 static int8_t inf_ev_rep(struct pkt_buff *pkt, u8 *id) {
1415 return 0;
1418 static int8_t inf_diagn_req(struct pkt_buff *pkt, u8 *id) {
1419 return 0;
1422 static int8_t inf_diagn_rep(struct pkt_buff *pkt, u8 *id) {
1423 return 0;
1426 static int8_t inf_loc_para(struct pkt_buff *pkt, u8 *id) {
1427 return 0;
1430 static int8_t inf_nontr_bssid_cap(struct pkt_buff *pkt, u8 *id) {
1431 return 0;
1434 static int8_t inf_ssid_list(struct pkt_buff *pkt, u8 *id) {
1435 return 0;
1438 static int8_t inf_mult_bssid_index(struct pkt_buff *pkt, u8 *id) {
1439 return 0;
1442 static int8_t inf_fms_desc(struct pkt_buff *pkt, u8 *id) {
1443 return 0;
1446 static int8_t inf_fms_req(struct pkt_buff *pkt, u8 *id) {
1447 return 0;
1450 static int8_t inf_fms_resp(struct pkt_buff *pkt, u8 *id) {
1451 return 0;
1454 static int8_t inf_qos_tfc_cap(struct pkt_buff *pkt, u8 *id) {
1455 return 0;
1458 static int8_t inf_bss_max_idle_per(struct pkt_buff *pkt, u8 *id) {
1459 return 0;
1462 static int8_t inf_tfs_req(struct pkt_buff *pkt, u8 *id) {
1463 return 0;
1466 static int8_t inf_tfs_resp(struct pkt_buff *pkt, u8 *id) {
1467 return 0;
1470 static int8_t inf_wnm_sleep_mod(struct pkt_buff *pkt, u8 *id) {
1471 return 0;
1474 static int8_t inf_tim_bcst_req(struct pkt_buff *pkt, u8 *id) {
1475 return 0;
1478 static int8_t inf_tim_bcst_resp(struct pkt_buff *pkt, u8 *id) {
1479 return 0;
1482 static int8_t inf_coll_interf_rep(struct pkt_buff *pkt, u8 *id) {
1483 return 0;
1486 static int8_t inf_ch_usage(struct pkt_buff *pkt, u8 *id) {
1487 return 0;
1490 static int8_t inf_time_zone(struct pkt_buff *pkt, u8 *id) {
1491 return 0;
1494 static int8_t inf_dms_req(struct pkt_buff *pkt, u8 *id) {
1495 return 0;
1498 static int8_t inf_dms_resp(struct pkt_buff *pkt, u8 *id) {
1499 return 0;
1502 static int8_t inf_link_id(struct pkt_buff *pkt, u8 *id) {
1503 return 0;
1506 static int8_t inf_wakeup_sched(struct pkt_buff *pkt, u8 *id) {
1507 return 0;
1510 static int8_t inf_ch_sw_timing(struct pkt_buff *pkt, u8 *id) {
1511 return 0;
1514 static int8_t inf_pti_ctrl(struct pkt_buff *pkt, u8 *id) {
1515 return 0;
1518 static int8_t inf_tpu_buff_status(struct pkt_buff *pkt, u8 *id) {
1519 return 0;
1522 static int8_t inf_interw(struct pkt_buff *pkt, u8 *id) {
1523 return 0;
1526 static int8_t inf_adv_proto(struct pkt_buff *pkt, u8 *id) {
1527 return 0;
1530 static int8_t inf_exp_bandw_req(struct pkt_buff *pkt, u8 *id) {
1531 return 0;
1534 static int8_t inf_qos_map_set(struct pkt_buff *pkt, u8 *id) {
1535 return 0;
1538 static int8_t inf_roam_cons(struct pkt_buff *pkt, u8 *id) {
1539 return 0;
1542 static int8_t inf_emer_alert_id(struct pkt_buff *pkt, u8 *id) {
1543 return 0;
1546 static int8_t inf_mesh_conf(struct pkt_buff *pkt, u8 *id) {
1547 return 0;
1550 static int8_t inf_mesh_id(struct pkt_buff *pkt, u8 *id) {
1551 return 0;
1554 static int8_t inf_mesh_link_metr_rep(struct pkt_buff *pkt, u8 *id) {
1555 return 0;
1558 static int8_t inf_cong_notif(struct pkt_buff *pkt, u8 *id) {
1559 return 0;
1562 static int8_t inf_mesh_peer_mgmt(struct pkt_buff *pkt, u8 *id) {
1563 return 0;
1566 static int8_t inf_mesh_ch_sw_para(struct pkt_buff *pkt, u8 *id) {
1567 return 0;
1570 static int8_t inf_mesh_awake_win(struct pkt_buff *pkt, u8 *id) {
1571 return 0;
1574 static int8_t inf_beacon_timing(struct pkt_buff *pkt, u8 *id) {
1575 return 0;
1578 static int8_t inf_mccaop_setup_req(struct pkt_buff *pkt, u8 *id) {
1579 return 0;
1582 static int8_t inf_mccaop_setup_rep(struct pkt_buff *pkt, u8 *id) {
1583 return 0;
1586 static int8_t inf_mccaop_adv(struct pkt_buff *pkt, u8 *id) {
1587 return 0;
1590 static int8_t inf_mccaop_teardwn(struct pkt_buff *pkt, u8 *id) {
1591 return 0;
1594 static int8_t inf_gann(struct pkt_buff *pkt, u8 *id) {
1595 return 0;
1598 static int8_t inf_rann(struct pkt_buff *pkt, u8 *id) {
1599 return 0;
1602 static int8_t inf_ext_cap(struct pkt_buff *pkt, u8 *id) {
1603 return 0;
1606 static int8_t inf_preq(struct pkt_buff *pkt, u8 *id) {
1607 return 0;
1610 static int8_t inf_prep(struct pkt_buff *pkt, u8 *id) {
1611 return 0;
1614 static int8_t inf_perr(struct pkt_buff *pkt, u8 *id) {
1615 return 0;
1618 static int8_t inf_pxu(struct pkt_buff *pkt, u8 *id) {
1619 return 0;
1622 static int8_t inf_pxuc(struct pkt_buff *pkt, u8 *id) {
1623 return 0;
1626 static int8_t inf_auth_mesh_peer_exch(struct pkt_buff *pkt, u8 *id) {
1627 return 0;
1630 static int8_t inf_mic(struct pkt_buff *pkt, u8 *id) {
1631 return 0;
1634 static int8_t inf_dest_uri(struct pkt_buff *pkt, u8 *id) {
1635 return 0;
1638 static int8_t inf_u_apsd_coex(struct pkt_buff *pkt, u8 *id) {
1639 return 0;
1642 static int8_t inf_mccaop_adv_overv(struct pkt_buff *pkt, u8 *id) {
1643 return 0;
1646 static int8_t inf_vend_spec(struct pkt_buff *pkt, u8 *id)
1648 u8 i;
1649 u8 *data;
1650 struct element_vend_spec *vend_spec;
1652 vend_spec = (struct element_vend_spec *)
1653 pkt_pull(pkt, sizeof(*vend_spec));
1654 if (vend_spec == NULL)
1655 return 0;
1657 tprintf("Vendor Specific (%u, Len (%u)): ", *id, vend_spec->len);
1659 data = pkt_pull(pkt, vend_spec->len);
1660 if (data == NULL)
1661 return 0;
1663 tprintf("Data 0x");
1664 for (i = 0; i < vend_spec->len; i++)
1665 tprintf("%.2x", data[i]);
1667 return 1;
1670 static int8_t inf_elements(struct pkt_buff *pkt)
1672 u8 *id = pkt_pull(pkt, 1);
1673 if (id == NULL)
1674 return 0;
1676 switch (*id) {
1677 case 0: return inf_ssid(pkt, id);
1678 case 1: return inf_supp_rates(pkt, id);
1679 case 2: return inf_fh_ps(pkt, id);
1680 case 3: return inf_dsss_ps(pkt, id);
1681 case 4: return inf_cf_ps(pkt, id);
1682 case 5: return inf_tim(pkt, id);
1683 case 6: return inf_ibss_ps(pkt, id);
1684 case 7: return inf_country(pkt, id);
1685 case 8: return inf_hop_pp(pkt, id);
1686 case 9: return inf_hop_pt(pkt, id);
1687 case 10: return inf_req(pkt, id);
1688 case 11: return inf_bss_load(pkt, id);
1689 case 12: return inf_edca_ps(pkt, id);
1690 case 13: return inf_tspec(pkt, id);
1691 case 14: return inf_tclas(pkt, id);
1692 case 15: return inf_sched(pkt, id);
1693 case 16: return inf_chall_txt(pkt, id);
1694 case 17 ... 31: return inf_reserved(pkt, id);
1695 case 32: return inf_pwr_constr(pkt, id);
1696 case 33: return inf_pwr_cap(pkt, id);
1697 case 34: return inf_tpc_req(pkt, id);
1698 case 35: return inf_tpc_rep(pkt, id);
1699 case 36: return inf_supp_ch(pkt, id);
1700 case 37: return inf_ch_sw_ann(pkt, id);
1701 case 38: return inf_meas_req(pkt, id);
1702 case 39: return inf_meas_rep(pkt, id);
1703 case 40: return inf_quiet(pkt, id);
1704 case 41: return inf_ibss_dfs(pkt, id);
1705 case 42: return inf_erp(pkt, id);
1706 case 43: return inf_ts_del(pkt, id);
1707 case 44: return inf_tclas_proc(pkt, id);
1708 case 45: return inf_ht_cap(pkt, id);
1709 case 46: return inf_qos_cap(pkt, id);
1710 case 47: return inf_reserved(pkt, id);
1711 case 48: return inf_rsn(pkt, id);
1712 case 49: return inf_rsn(pkt, id);
1713 case 50: return inf_ext_supp_rates(pkt, id);
1714 case 51: return inf_ap_ch_exp(pkt, id);
1715 case 52: return inf_neighb_rep(pkt, id);
1716 case 53: return inf_rcpi(pkt, id);
1717 case 54: return inf_mde(pkt, id);
1718 case 55: return inf_fte(pkt, id);
1719 case 56: return inf_time_out_int(pkt, id);
1720 case 57: return inf_rde(pkt, id);
1721 case 58: return inf_dse_reg_loc(pkt, id);
1722 case 59: return inf_supp_op_class(pkt, id);
1723 case 60: return inf_ext_ch_sw_ann(pkt, id);
1724 case 61: return inf_ht_op(pkt, id);
1725 case 62: return inf_sec_ch_offs(pkt, id);
1726 case 63: return inf_bss_avg_acc_del(pkt, id);
1727 case 64: return inf_ant(pkt, id);
1728 case 65: return inf_rsni(pkt, id);
1729 case 66: return inf_meas_pilot_trans(pkt, id);
1730 case 67: return inf_bss_avl_adm_cap(pkt, id);
1731 case 68: return inf_bss_ac_acc_del(pkt, id);
1732 case 69: return inf_time_adv(pkt, id);
1733 case 70: return inf_rm_ena_cap(pkt, id);
1734 case 71: return inf_mult_bssid(pkt, id);
1735 case 72: return inf_20_40_bss_coex(pkt, id);
1736 case 73: return inf_20_40_bss_int_ch_rep(pkt, id);
1737 case 74: return inf_overl_bss_scan_para(pkt, id);
1738 case 75: return inf_ric_desc(pkt, id);
1739 case 76: return inf_mgmt_mic(pkt, id);
1740 case 78: return inf_ev_req(pkt, id);
1741 case 79: return inf_ev_rep(pkt, id);
1742 case 80: return inf_diagn_req(pkt, id);
1743 case 81: return inf_diagn_rep(pkt, id);
1744 case 82: return inf_loc_para(pkt, id);
1745 case 83: return inf_nontr_bssid_cap(pkt, id);
1746 case 84: return inf_ssid_list(pkt, id);
1747 case 85: return inf_mult_bssid_index(pkt, id);
1748 case 86: return inf_fms_desc(pkt, id);
1749 case 87: return inf_fms_req(pkt, id);
1750 case 88: return inf_fms_resp(pkt, id);
1751 case 89: return inf_qos_tfc_cap(pkt, id);
1752 case 90: return inf_bss_max_idle_per(pkt, id);
1753 case 91: return inf_tfs_req(pkt, id);
1754 case 92: return inf_tfs_resp(pkt, id);
1755 case 93: return inf_wnm_sleep_mod(pkt, id);
1756 case 94: return inf_tim_bcst_req(pkt, id);
1757 case 95: return inf_tim_bcst_resp(pkt, id);
1758 case 96: return inf_coll_interf_rep(pkt, id);
1759 case 97: return inf_ch_usage(pkt, id);
1760 case 98: return inf_time_zone(pkt, id);
1761 case 99: return inf_dms_req(pkt, id);
1762 case 100: return inf_dms_resp(pkt, id);
1763 case 101: return inf_link_id(pkt, id);
1764 case 102: return inf_wakeup_sched(pkt, id);
1765 case 104: return inf_ch_sw_timing(pkt, id);
1766 case 105: return inf_pti_ctrl(pkt, id);
1767 case 106: return inf_tpu_buff_status(pkt, id);
1768 case 107: return inf_interw(pkt, id);
1769 case 108: return inf_adv_proto(pkt, id);
1770 case 109: return inf_exp_bandw_req(pkt, id);
1771 case 110: return inf_qos_map_set(pkt, id);
1772 case 111: return inf_roam_cons(pkt, id);
1773 case 112: return inf_emer_alert_id(pkt, id);
1774 case 113: return inf_mesh_conf(pkt, id);
1775 case 114: return inf_mesh_id(pkt, id);
1776 case 115: return inf_mesh_link_metr_rep(pkt, id);
1777 case 116: return inf_cong_notif(pkt, id);
1778 case 117: return inf_mesh_peer_mgmt(pkt, id);
1779 case 118: return inf_mesh_ch_sw_para(pkt, id);
1780 case 119: return inf_mesh_awake_win(pkt, id);
1781 case 120: return inf_beacon_timing(pkt, id);
1782 case 121: return inf_mccaop_setup_req(pkt, id);
1783 case 122: return inf_mccaop_setup_rep(pkt, id);
1784 case 123: return inf_mccaop_adv(pkt, id);
1785 case 124: return inf_mccaop_teardwn(pkt, id);
1786 case 125: return inf_gann(pkt, id);
1787 case 126: return inf_rann(pkt, id);
1788 case 127: return inf_ext_cap(pkt, id);
1789 case 128: return inf_reserved(pkt, id);
1790 case 129: return inf_reserved(pkt, id);
1791 case 130: return inf_preq(pkt, id);
1792 case 131: return inf_prep(pkt, id);
1793 case 132: return inf_perr(pkt, id);
1794 case 133: return inf_reserved(pkt, id);
1795 case 134: return inf_reserved(pkt, id);
1796 case 135: return inf_reserved(pkt, id);
1797 case 136: return inf_reserved(pkt, id);
1798 case 137: return inf_pxu(pkt, id);
1799 case 138: return inf_pxuc(pkt, id);
1800 case 139: return inf_auth_mesh_peer_exch(pkt, id);
1801 case 140: return inf_mic(pkt, id);
1802 case 141: return inf_dest_uri(pkt, id);
1803 case 142: return inf_u_apsd_coex(pkt, id);
1804 case 143 ... 173: return inf_reserved(pkt, id);
1805 case 174: return inf_mccaop_adv_overv(pkt, id);
1806 case 221: return inf_vend_spec(pkt, id);
1809 return 0;
1812 #define ESS 0b0000000000000001
1813 #define IBSS 0b0000000000000010
1814 #define CF_Pollable 0b0000000000000100
1815 #define CF_Poll_Req 0b0000000000001000
1816 #define Privacy 0b0000000000010000
1817 #define Short_Pre 0b0000000000100000
1818 #define PBCC 0b0000000001000000
1819 #define Ch_Agility 0b0000000010000000
1820 #define Spec_Mgmt 0b0000000100000000
1821 #define QoS 0b0000001000000000
1822 #define Short_Slot_t 0b0000010000000000
1823 #define APSD 0b0000100000000000
1824 #define Radio_Meas 0b0001000000000000
1825 #define DSSS_OFDM 0b0010000000000000
1826 #define Del_Block_ACK 0b0100000000000000
1827 #define Imm_Block_ACK 0b1000000000000000
1829 static int8_t cap_field(u16 cap_inf)
1831 if (ESS & cap_inf)
1832 tprintf(" ESS;");
1833 if (IBSS & cap_inf)
1834 tprintf(" IBSS;");
1835 if (CF_Pollable & cap_inf)
1836 tprintf(" CF Pollable;");
1837 if (CF_Poll_Req & cap_inf)
1838 tprintf(" CF-Poll Request;");
1839 if (Privacy & cap_inf)
1840 tprintf(" Privacy;");
1841 if (Short_Pre & cap_inf)
1842 tprintf(" Short Preamble;");
1843 if (PBCC & cap_inf)
1844 tprintf(" PBCC;");
1845 if (Ch_Agility & cap_inf)
1846 tprintf(" Channel Agility;");
1847 if (Spec_Mgmt & cap_inf)
1848 tprintf(" Spectrum Management;");
1849 if (QoS & cap_inf)
1850 tprintf(" QoS;");
1851 if (Short_Slot_t & cap_inf)
1852 tprintf(" Short Slot Time;");
1853 if (APSD & cap_inf)
1854 tprintf(" APSD;");
1855 if (Radio_Meas & cap_inf)
1856 tprintf(" Radio Measurement;");
1857 if (DSSS_OFDM & cap_inf)
1858 tprintf(" DSSS-OFDM;");
1859 if (Del_Block_ACK & cap_inf)
1860 tprintf(" Delayed Block Ack;");
1861 if (Imm_Block_ACK & cap_inf)
1862 tprintf(" Immediate Block Ack;");
1864 return 1;
1867 /* Management Dissectors */
1868 static int8_t assoc_req(struct pkt_buff *pkt) {
1869 return 0;
1872 static int8_t assoc_resp(struct pkt_buff *pkt) {
1873 return 0;
1876 static int8_t reassoc_req(struct pkt_buff *pkt) {
1877 return 0;
1880 static int8_t reassoc_resp(struct pkt_buff *pkt) {
1881 return 0;
1884 static int8_t probe_req(struct pkt_buff *pkt) {
1885 return 0;
1888 static int8_t probe_resp(struct pkt_buff *pkt) {
1889 return 0;
1892 static int8_t beacon(struct pkt_buff *pkt)
1894 struct ieee80211_mgmt_beacon *beacon;
1896 beacon = (struct ieee80211_mgmt_beacon *)
1897 pkt_pull(pkt, sizeof(*beacon));
1898 if (beacon == NULL)
1899 return 0;
1901 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon->timestamp));
1902 tprintf("Beacon Interval (%fs), ", le16_to_cpu(beacon->beacon_int)*TU);
1903 tprintf("Capabilities (0x%x <->", le16_to_cpu(beacon->capab_info));
1904 cap_field(le16_to_cpu(beacon->capab_info));
1905 tprintf(")");
1907 if(pkt_len(pkt)) {
1908 tprintf("\n\tParameters:");
1909 while (inf_elements(pkt)) {
1910 tprintf("\n\t");
1914 if(pkt_len(pkt))
1915 return 0;
1916 return 1;
1919 static int8_t atim(struct pkt_buff *pkt) {
1920 return 0;
1923 static int8_t disassoc(struct pkt_buff *pkt) {
1924 return 0;
1927 static int8_t auth(struct pkt_buff *pkt) {
1928 return 0;
1931 static int8_t deauth(struct pkt_buff *pkt) {
1932 return 0;
1934 /* End Management Dissectors */
1936 /* Control Dissectors */
1937 static int8_t ps_poll(struct pkt_buff *pkt) {
1938 return 0;
1941 static int8_t rts(struct pkt_buff *pkt) {
1942 return 0;
1945 static int8_t cts(struct pkt_buff *pkt) {
1946 return 0;
1949 static int8_t ack(struct pkt_buff *pkt) {
1950 return 0;
1953 static int8_t cf_end(struct pkt_buff *pkt) {
1954 return 0;
1957 static int8_t cf_end_ack(struct pkt_buff *pkt) {
1958 return 0;
1960 /* End Control Dissectors */
1962 /* Data Dissectors */
1963 static int8_t data(struct pkt_buff *pkt) {
1964 return 0;
1967 static int8_t data_cf_ack(struct pkt_buff *pkt) {
1968 return 0;
1971 static int8_t data_cf_poll(struct pkt_buff *pkt) {
1972 return 0;
1975 static int8_t data_cf_ack_poll(struct pkt_buff *pkt) {
1976 return 0;
1979 static int8_t null(struct pkt_buff *pkt) {
1980 return 0;
1983 static int8_t cf_ack(struct pkt_buff *pkt) {
1984 return 0;
1987 static int8_t cf_poll(struct pkt_buff *pkt) {
1988 return 0;
1991 static int8_t cf_ack_poll(struct pkt_buff *pkt) {
1992 return 0;
1994 /* End Data Dissectors */
1996 static const char *mgt_sub(u8 subtype, struct pkt_buff *pkt,
1997 int8_t (**get_content)(struct pkt_buff *pkt))
1999 u16 seq_ctrl;
2000 struct ieee80211_mgmt *mgmt;
2001 const char *dst, *src, *bssid;
2003 mgmt = (struct ieee80211_mgmt *) pkt_pull(pkt, sizeof(*mgmt));
2004 if (mgmt == NULL)
2005 return 0;
2007 dst = lookup_vendor((mgmt->da[0] << 16) |
2008 (mgmt->da[1] << 8) |
2009 mgmt->da[2]);
2010 src = lookup_vendor((mgmt->sa[0] << 16) |
2011 (mgmt->sa[1] << 8) |
2012 mgmt->sa[2]);
2014 bssid = lookup_vendor((mgmt->bssid[0] << 16) |
2015 (mgmt->bssid[1] << 8) |
2016 mgmt->bssid[2]);
2017 seq_ctrl = le16_to_cpu(mgmt->seq_ctrl);
2019 tprintf("Duration (%u),", le16_to_cpu(mgmt->duration));
2020 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
2021 mgmt->da[0], mgmt->da[1], mgmt->da[2],
2022 mgmt->da[3], mgmt->da[4], mgmt->da[5]);
2023 if (dst) {
2024 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst,
2025 mgmt->da[3], mgmt->da[4], mgmt->da[5]);
2028 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
2029 mgmt->sa[0], mgmt->sa[1], mgmt->sa[2],
2030 mgmt->sa[3], mgmt->sa[4], mgmt->sa[5]);
2031 if (src) {
2032 tprintf("=> (%s:%.2x:%.2x:%.2x)", src,
2033 mgmt->sa[3], mgmt->sa[4], mgmt->sa[5]);
2036 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
2037 mgmt->bssid[0], mgmt->bssid[1], mgmt->bssid[2],
2038 mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5]);
2039 if(bssid) {
2040 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid,
2041 mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5]);
2044 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ",
2045 seq_ctrl & 0xf, seq_ctrl >> 4);
2047 switch (subtype) {
2048 case 0b0000:
2049 *get_content = assoc_req;
2050 return "Association Request";
2051 case 0b0001:
2052 *get_content = assoc_resp;
2053 return "Association Response";
2054 case 0b0010:
2055 *get_content = reassoc_req;
2056 return "Reassociation Request";
2057 case 0b0011:
2058 *get_content = reassoc_resp;
2059 return "Reassociation Response";
2060 case 0b0100:
2061 *get_content = probe_req;
2062 return "Probe Request";
2063 case 0b0101:
2064 *get_content = probe_resp;
2065 return "Probe Response";
2066 case 0b1000:
2067 *get_content = beacon;
2068 return "Beacon";
2069 case 0b1001:
2070 *get_content = atim;
2071 return "ATIM";
2072 case 0b1010:
2073 *get_content = disassoc;
2074 return "Disassociation";
2075 case 0b1011:
2076 *get_content = auth;
2077 return "Authentication";
2078 case 0b1100:
2079 *get_content = deauth;
2080 return "Deauthentication";
2081 case 0b0110 ... 0b0111:
2082 case 0b1101 ... 0b1111:
2083 *get_content = NULL;
2084 return "Reserved";
2085 default:
2086 *get_content = NULL;
2087 return "Management SubType unknown";
2091 static const char *ctrl_sub(u8 subtype, struct pkt_buff *pkt,
2092 int8_t (**get_content)(struct pkt_buff *pkt))
2094 switch (subtype) {
2095 case 0b1010:
2096 *get_content = ps_poll;
2097 return "PS-Poll";
2098 case 0b1011:
2099 *get_content = rts;
2100 return "RTS";
2101 case 0b1100:
2102 *get_content = cts;
2103 return "CTS";
2104 case 0b1101:
2105 *get_content = ack;
2106 return "ACK";
2107 case 0b1110:
2108 *get_content = cf_end;
2109 return "CF End";
2110 case 0b1111:
2111 *get_content = cf_end_ack;
2112 return "CF End + CF-ACK";
2113 case 0b0000 ... 0b1001:
2114 *get_content = NULL;
2115 return "Reserved";
2116 default:
2117 return "Control SubType unkown";
2121 static const char *data_sub(u8 subtype, struct pkt_buff *pkt,
2122 int8_t (**get_content)(struct pkt_buff *pkt))
2124 switch (subtype) {
2125 case 0b0000:
2126 *get_content = data;
2127 return "Data";
2128 case 0b0001:
2129 *get_content = data_cf_ack;
2130 return "Data + CF-ACK";
2131 case 0b0010:
2132 *get_content = data_cf_poll;
2133 return "Data + CF-Poll";
2134 case 0b0011:
2135 *get_content = data_cf_ack_poll;
2136 return "Data + CF-ACK + CF-Poll";
2137 case 0b0100:
2138 *get_content = null;
2139 return "Null";
2140 case 0b0101:
2141 *get_content = cf_ack;
2142 return "CF-ACK";
2143 case 0b0110:
2144 *get_content = cf_poll;
2145 return "CF-Poll";
2146 case 0b0111:
2147 *get_content = cf_ack_poll;
2148 return "CF-ACK + CF-Poll";
2149 case 0b1000 ... 0b1111:
2150 *get_content = NULL;
2151 return "Reserved";
2152 default:
2153 *get_content = NULL;
2154 return "Data SubType unkown";
2158 static const char *
2159 frame_control_type(u8 type, const char *(**get_subtype)(u8 subtype,
2160 struct pkt_buff *pkt, int8_t (**get_content)(struct pkt_buff *pkt)))
2162 switch (type) {
2163 case 0b00:
2164 *get_subtype = mgt_sub;
2165 return "Management";
2166 case 0b01:
2167 *get_subtype = ctrl_sub;
2168 return "Control";
2169 case 0b10:
2170 *get_subtype = data_sub;
2171 return "Data";
2172 case 0b11:
2173 *get_subtype = NULL;
2174 return "Reserved";
2175 default:
2176 *get_subtype = NULL;
2177 return "Control Type unkown";
2181 static void ieee80211(struct pkt_buff *pkt)
2183 int8_t (*get_content)(struct pkt_buff *pkt) = NULL;
2184 const char *(*get_subtype)(u8 subtype, struct pkt_buff *pkt,
2185 int8_t (**get_content)(struct pkt_buff *pkt)) = NULL;
2186 const char *subtype = NULL;
2187 struct ieee80211_frm_ctrl *frm_ctrl;
2189 frm_ctrl = (struct ieee80211_frm_ctrl *)
2190 pkt_pull(pkt, sizeof(*frm_ctrl));
2191 if (frm_ctrl == NULL)
2192 return;
2194 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
2195 le16_to_cpu(frm_ctrl->frame_control));
2197 tprintf(" [ Proto Version (%u), ", frm_ctrl->proto_version);
2198 tprintf("Type (%u, %s), ", frm_ctrl->type,
2199 frame_control_type(frm_ctrl->type, &get_subtype));
2200 if (get_subtype) {
2201 subtype = (*get_subtype)(frm_ctrl->subtype, pkt, &get_content);
2202 tprintf("Subtype (%u, %s)", frm_ctrl->subtype, subtype);
2203 } else {
2204 tprintf("%s%s%s", colorize_start_full(black, red),
2205 "No SubType Data available", colorize_end());
2208 tprintf("%s%s", frm_ctrl->to_ds ? ", Frame goes to DS" : "",
2209 frm_ctrl->from_ds ? ", Frame comes from DS" : "");
2210 tprintf("%s", frm_ctrl->more_frags ? ", More Fragments" : "");
2211 tprintf("%s", frm_ctrl->retry ? ", Frame is retransmitted" : "");
2212 tprintf("%s", frm_ctrl->power_mgmt ? ", In Power Saving Mode" : "");
2213 tprintf("%s", frm_ctrl->more_data ? ", More Data" : "");
2214 tprintf("%s", frm_ctrl->wep ? ", Needs WEP" : "");
2215 tprintf("%s", frm_ctrl->order ? ", Order" : "");
2216 tprintf(" ]\n");
2218 if (get_content) {
2219 tprintf(" [ Subtype %s: ", subtype);
2220 if (!((*get_content) (pkt)))
2221 tprintf("%s%s%s", colorize_start_full(black, red),
2222 "Failed to dissect Subtype", colorize_end());
2223 tprintf(" ]");
2224 } else {
2225 tprintf("%s%s%s", colorize_start_full(black, red),
2226 "No SubType Data available", colorize_end());
2229 tprintf("\n");
2231 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
2234 static void ieee80211_less(struct pkt_buff *pkt)
2236 tprintf("802.11 frame (more on todo)");
2239 struct protocol ieee80211_ops = {
2240 .key = 0,
2241 .print_full = ieee80211,
2242 .print_less = ieee80211_less,
2245 EXPORT_SYMBOL(ieee80211_ops);