Merge pull request #59 from electronjoe/graceful-SIGTERM-handling
[netsniff-ng-old.git] / proto_80211_mac_hdr.c
bloba496a1e87ec32e30bcb438e3d21ac4634d3f3a52
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012, 2013 Markus Amend <markus@netsniff-ng.org>
4 * Copyright 2012 Daniel Borkmann <daniel@netsniff-ng.org>
5 * Subject to the GPL, version 2.
6 */
8 /* TODO
9 * check all possible frame combinations for their behavior
10 * with respect to endianess (little / big)
13 #include <stdio.h>
14 #include <stdint.h>
15 #include <netinet/in.h> /* for ntohs() */
16 #include <asm/byteorder.h>
17 #include <arpa/inet.h> /* for inet_ntop() */
19 #include "proto.h"
20 #include "protos.h"
21 #include "dissector_80211.h"
22 #include "built_in.h"
23 #include "pkt_buff.h"
24 #include "oui.h"
26 #define TU 0.001024
28 /* Note: Fields are encoded in little-endian! */
29 struct ieee80211_frm_ctrl {
30 union {
31 u16 frame_control;
32 struct {
33 #if defined(__LITTLE_ENDIAN_BITFIELD)
34 /* Correct order here ... */
35 __extension__ u16 proto_version:2,
36 type:2,
37 subtype:4,
38 to_ds:1,
39 from_ds:1,
40 more_frags:1,
41 retry:1,
42 power_mgmt:1,
43 more_data:1,
44 wep:1,
45 order:1;
46 #elif defined(__BIG_ENDIAN_BITFIELD)
47 __extension__ u16 subtype:4,
48 type:2,
49 proto_version:2,
50 order:1,
51 wep:1,
52 more_data:1,
53 power_mgmt:1,
54 retry:1,
55 more_frags:1,
56 from_ds:1,
57 to_ds:1;
58 #else
59 # error "Adjust your <asm/byteorder.h> defines"
60 #endif
63 } __packed;
65 /* Management Frame start */
66 /* Note: Fields are encoded in little-endian! */
67 struct ieee80211_mgmt {
68 u16 duration;
69 u8 da[6];
70 u8 sa[6];
71 u8 bssid[6];
72 u16 seq_ctrl;
73 } __packed;
75 struct ieee80211_mgmt_auth {
76 u16 auth_alg;
77 u16 auth_transaction;
78 u16 status_code;
79 /* possibly followed by Challenge text */
80 u8 variable[0];
81 } __packed;
83 struct ieee80211_mgmt_deauth {
84 u16 reason_code;
85 } __packed;
87 struct ieee80211_mgmt_assoc_req {
88 u16 capab_info;
89 u16 listen_interval;
90 /* followed by SSID and Supported rates */
91 u8 variable[0];
92 } __packed;
94 struct ieee80211_mgmt_assoc_resp {
95 u16 capab_info;
96 u16 status_code;
97 u16 aid;
98 /* followed by Supported rates */
99 u8 variable[0];
100 } __packed;
102 struct ieee80211_mgmt_reassoc_resp {
103 u16 capab_info;
104 u16 status_code;
105 u16 aid;
106 /* followed by Supported rates */
107 u8 variable[0];
108 } __packed;
110 struct ieee80211_mgmt_reassoc_req {
111 u16 capab_info;
112 u16 listen_interval;
113 u8 current_ap[6];
114 /* followed by SSID and Supported rates */
115 u8 variable[0];
116 } __packed;
118 struct ieee80211_mgmt_disassoc {
119 u16 reason_code;
120 } __packed;
122 struct ieee80211_mgmt_probe_req {
123 } __packed;
125 struct ieee80211_mgmt_beacon {
126 u64 timestamp;
127 u16 beacon_int;
128 u16 capab_info;
129 /* followed by some of SSID, Supported rates,
130 * FH Params, DS Params, CF Params, IBSS Params, TIM */
131 u8 variable[0];
132 } __packed;
134 struct ieee80211_mgmt_probe_resp {
135 u8 timestamp[8];
136 u16 beacon_int;
137 u16 capab_info;
138 /* followed by some of SSID, Supported rates,
139 * FH Params, DS Params, CF Params, IBSS Params, TIM */
140 u8 variable[0];
141 } __packed;
142 /* Management Frame end */
144 /* Control Frame start */
145 /* Note: Fields are encoded in little-endian! */
146 struct ieee80211_ctrl {
147 } __packed;
149 struct ieee80211_ctrl_rts {
150 u16 duration;
151 u8 da[6];
152 u8 sa[6];
153 } __packed;
155 struct ieee80211_ctrl_cts {
156 u16 duration;
157 u8 da[6];
158 } __packed;
160 struct ieee80211_ctrl_ack {
161 u16 duration;
162 u8 da[6];
163 } __packed;
165 struct ieee80211_ctrl_ps_poll {
166 u16 aid;
167 u8 bssid[6];
168 u8 sa[6];
169 } __packed;
171 struct ieee80211_ctrl_cf_end {
172 u16 duration;
173 u8 bssid[6];
174 u8 sa[6];
175 } __packed;
177 struct ieee80211_ctrl_cf_end_ack {
178 u16 duration;
179 u8 bssid[6];
180 u8 sa[6];
181 } __packed;
182 /* Control Frame end */
184 /* Data Frame start */
185 /* Note: Fields are encoded in little-endian! */
186 struct ieee80211_data {
187 } __packed;
189 /* TODO: Extend */
190 /* Data Frame end */
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 rates[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 apsd: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 apsd: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 frm_class[0];
358 } __packed;
360 struct element_tclas_frm_class {
361 u8 type;
362 u8 mask;
363 u8 param[0];
364 } __packed;
366 struct element_tclas_type0 {
367 u8 sa[6];
368 u8 da[6];
369 u16 type;
370 } __packed;
372 struct element_tclas_type1 {
373 u8 version;
374 u8 subparam[0];
375 } __packed;
377 struct element_tclas_type1_ip4 {
378 u32 sa;
379 u32 da;
380 u16 sp;
381 u16 dp;
382 u8 dscp;
383 u8 proto;
384 u8 reserved;
385 } __packed;
387 struct element_tclas_type1_ip6 {
388 struct in6_addr sa;
389 struct in6_addr da;
390 u16 sp;
391 u16 dp;
392 union {
393 u8 flow_label[3];
394 struct {
395 #if defined(__LITTLE_ENDIAN_BITFIELD)
396 __extension__ u8 flow_label3:8;
397 __extension__ u8 flow_label2:8;
398 __extension__ u8 flow_label1:8;
399 #elif defined(__BIG_ENDIAN_BITFIELD)
400 __extension__ u8 flow_label1:8;
401 __extension__ u8 flow_label2:8;
402 __extension__ u8 flow_label3:8;
403 #else
404 # error "Adjust your <asm/byteorder.h> defines"
405 #endif
408 } __packed;
410 struct element_tclas_type2 {
411 u16 vlan_tci;
412 } __packed;
414 struct element_tclas_type3 {
415 u16 offs;
416 u8 value[0];
417 u8 mask[0];
418 } __packed;
420 struct element_tclas_type4 {
421 u8 version;
422 u8 subparam[0];
423 } __packed;
425 struct element_tclas_type4_ip4 {
426 u32 sa;
427 u32 da;
428 u16 sp;
429 u16 dp;
430 u8 dscp;
431 u8 proto;
432 u8 reserved;
433 } __packed;
435 struct element_tclas_type4_ip6 {
436 struct in6_addr sa;
437 struct in6_addr da;
438 u16 sp;
439 u16 dp;
440 u8 dscp;
441 u8 nxt_hdr;
442 union {
443 u8 flow_label[3];
444 struct {
445 #if defined(__LITTLE_ENDIAN_BITFIELD)
446 __extension__ u8 flow_label3:8;
447 __extension__ u8 flow_label2:8;
448 __extension__ u8 flow_label1:8;
449 #elif defined(__BIG_ENDIAN_BITFIELD)
450 __extension__ u8 flow_label1:8;
451 __extension__ u8 flow_label2:8;
452 __extension__ u8 flow_label3:8;
453 #else
454 # error "Adjust your <asm/byteorder.h> defines"
455 #endif
458 } __packed;
460 struct element_tclas_type5 {
461 u8 pcp;
462 u8 cfi;
463 u8 vid;
464 } __packed;
466 struct element_schedule {
467 u8 len;
468 u16 inf;
469 u32 start;
470 u32 serv_intv;
471 u16 spec_intv;
472 } __packed;
474 struct element_chall_txt {
475 u8 len;
476 u8 chall_txt[0];
477 } __packed;
479 struct element_pwr_constr {
480 u8 len;
481 u8 local_pwr_constr;
482 } __packed;
484 struct element_pwr_cap {
485 u8 len;
486 u8 min_pwr_cap;
487 u8 max_pwr_cap;
488 } __packed;
490 struct element_tpc_req {
491 u8 len;
492 } __packed;
494 struct element_tpc_rep {
495 u8 len;
496 u8 trans_pwr;
497 u8 link_marg;
498 } __packed;
500 struct element_supp_ch {
501 u8 len;
502 u8 first_ch_nr[0];
503 u8 nr_ch[0];
504 } __packed;
506 struct element_supp_ch_tuple {
507 u8 first_ch_nr;
508 u8 nr_ch;
509 } __packed;
511 struct element_ch_sw_ann {
512 u8 len;
513 u8 switch_mode;
514 u8 new_nr;
515 u8 switch_cnt;
516 } __packed;
518 struct element_meas_basic {
519 u8 ch_nr;
520 u64 start;
521 u16 dur;
522 } __packed;
524 struct element_meas_cca {
525 u8 ch_nr;
526 u64 start;
527 u16 dur;
528 } __packed;
530 struct element_meas_rpi {
531 u8 ch_nr;
532 u64 start;
533 u16 dur;
534 } __packed;
536 struct element_meas_ch_load {
537 u8 op_class;
538 u8 ch_nr;
539 u16 rand_intv;
540 u16 dur;
541 u8 sub[0];
542 } __packed;
544 struct element_meas_noise {
545 u8 op_class;
546 u8 ch_nr;
547 u16 rand_intv;
548 u16 dur;
549 u8 sub[0];
550 } __packed;
552 struct element_meas_beacon {
553 u8 op_class;
554 u8 ch_nr;
555 u16 rand_intv;
556 u16 dur;
557 u8 mode;
558 u8 bssid[6];
559 u8 sub[0];
560 } __packed;
562 struct element_meas_frame {
563 u8 op_class;
564 u8 ch_nr;
565 u16 rand_intv;
566 u16 dur;
567 u8 frame;
568 u8 mac[6];
569 u8 sub[0];
570 } __packed;
572 struct element_meas_sta {
573 u8 peer_mac[6];
574 u16 rand_intv;
575 u16 dur;
576 u8 group_id;
577 u8 sub[0];
578 } __packed;
580 struct element_meas_lci {
581 u8 loc_subj;
582 u8 latitude_req_res;
583 u8 longitude_req_res;
584 u8 altitude_req_res;
585 u8 sub[0];
586 } __packed;
588 struct element_meas_trans_str_cat {
589 u16 rand_intv;
590 u16 dur;
591 u8 peer_sta_addr[6];
592 u8 traffic_id;
593 u8 bin_0_range;
594 u8 sub[0];
595 } __packed;
597 struct element_meas_mcast_diag {
598 u16 rand_intv;
599 u16 dur;
600 u8 group_mac[6];
601 u8 mcast_triggered[0];
602 u8 sub[0];
603 } __packed;
605 struct element_meas_loc_civic {
606 u8 loc_subj;
607 u8 civic_loc;
608 u8 loc_srv_intv_unit;
609 u16 loc_srv_intv;
610 u8 sub[0];
611 } __packed;
613 struct element_meas_loc_id {
614 u8 loc_subj;
615 u8 loc_srv_intv_unit;
616 u16 loc_srv_intv;
617 u8 sub[0];
618 } __packed;
620 struct element_meas_pause {
621 u8 time;
622 u8 sub[0];
623 } __packed;
625 struct element_meas_req {
626 u8 len;
627 u8 token;
628 u8 req_mode;
629 u8 type;
630 u8 req[0];
631 } __packed;
633 struct element_meas_rep {
634 u8 len;
635 u8 token;
636 u8 rep_mode;
637 u8 type;
638 u8 rep[0];
639 } __packed;
641 struct element_quiet {
642 u8 len;
643 u8 cnt;
644 u8 period;
645 u16 dur;
646 u16 offs;
647 } __packed;
649 struct element_ibss_dfs {
650 u8 len;
651 u8 owner[6];
652 u8 rec_intv;
653 u8 ch_map[0];
654 } __packed;
656 struct element_ibss_dfs_tuple {
657 u8 ch_nr;
658 u8 map;
659 } __packed;
661 struct element_erp {
662 u8 len;
663 u8 param;
664 } __packed;
666 struct element_ts_del {
667 u8 len;
668 u32 delay;
669 } __packed;
671 struct element_tclas_proc {
672 u8 len;
673 u8 proc;
674 } __packed;
676 struct element_ht_cap {
677 u8 len;
678 union {
679 u16 info;
680 struct {
681 #if defined(__LITTLE_ENDIAN_BITFIELD)
682 /* Correct order here ... */
683 __extension__ u16 ldpc:1,
684 supp_width:1,
685 sm_pwr:2,
686 ht_green:1,
687 gi_20mhz:1,
688 gi_40mhz:1,
689 tx_stbc:1,
690 rx_stbc:2,
691 ht_ack:1,
692 max_msdu_length:1,
693 dsss_ck_mode:1,
694 res:1,
695 forty_int:1,
696 prot_supp:1;
697 #elif defined(__BIG_ENDIAN_BITFIELD)
698 __extension__ u16 rx_stbc:2,
699 ht_ack:1,
700 max_msdu_length:1,
701 dsss_ck_mode:1,
702 res:1,
703 forty_int:1,
704 prot_supp:1,
705 ldpc:1,
706 supp_width:1,
707 sm_pwr:2,
708 ht_green:1,
709 gi_20mhz:1,
710 gi_40mhz:1,
711 tx_stbc:1;
712 #else
713 # error "Adjust your <asm/byteorder.h> defines"
714 #endif
717 u8 param;
718 union {
719 u8 mcs_set[16];
720 struct {
721 #if defined(__LITTLE_ENDIAN_BITFIELD)
722 /* Correct order here ... */
723 __extension__ u8 bitmask1:8;
724 __extension__ u8 bitmask2:8;
725 __extension__ u8 bitmask3:8;
726 __extension__ u8 bitmask4:8;
727 __extension__ u8 bitmask5:8;
728 __extension__ u8 bitmask6:8;
729 __extension__ u8 bitmask7:8;
730 __extension__ u8 bitmask8:8;
731 __extension__ u8 bitmask9:8;
732 __extension__ u8 bitmask10_res:8;
733 __extension__ u16 supp_rate_res:16;
734 __extension__ u32 tx_param_res:32;
736 #elif defined(__BIG_ENDIAN_BITFIELD)
737 __extension__ u32 tx_param_res:32;
738 __extension__ u16 supp_rate_res:16;
739 __extension__ u8 bitmask10_res:8;
740 __extension__ u8 bitmask9:8;
741 __extension__ u8 bitmask8:8;
742 __extension__ u8 bitmask7:8;
743 __extension__ u8 bitmask6:8;
744 __extension__ u8 bitmask5:8;
745 __extension__ u8 bitmask4:8;
746 __extension__ u8 bitmask3:8;
747 __extension__ u8 bitmask2:8;
748 __extension__ u8 bitmask1:8;
749 #else
750 # error "Adjust your <asm/byteorder.h> defines"
751 #endif
754 u16 ext_cap;
755 u32 beam_cap;
756 u8 asel_cap;
757 } __packed;
759 struct element_qos_cap {
760 u8 len;
761 u8 info;
762 } __packed;
764 struct element_ext_supp_rates {
765 u8 len;
766 u8 rates[0];
767 } __packed;
769 struct element_vend_spec {
770 u8 len;
771 u8 oui[0];
772 u8 specific[0];
773 } __packed;
775 static int8_t len_neq_error(u8 len, u8 intended)
777 if(intended != len) {
778 tprintf("Length should be %u Bytes", intended);
779 return 1;
782 return 0;
785 static int8_t len_lt_error(u8 len, u8 intended)
787 if(len < intended) {
788 tprintf("Length should be greater %u Bytes", intended);
789 return 1;
792 return 0;
795 static float data_rates(u8 id)
797 /* XXX Why not (id / 2.f)? */
798 switch (id) {
799 case 2: return 1.0f;
800 case 3: return 1.5f;
801 case 4: return 2.0f;
802 case 5: return 2.5f;
803 case 6: return 3.0f;
804 case 9: return 4.5f;
805 case 11: return 5.5f;
806 case 12: return 6.0f;
807 case 18: return 9.0f;
808 case 22: return 11.0f;
809 case 24: return 12.0f;
810 case 27: return 13.5f;
811 case 36: return 18.0f;
812 case 44: return 22.0f;
813 case 48: return 24.0f;
814 case 54: return 27.0f;
815 case 66: return 33.0f;
816 case 72: return 36.0f;
817 case 96: return 48.0f;
818 case 108: return 54.0f;
821 return 0.f;
824 struct subelement {
825 u8 id;
826 u8 len;
827 u8 data[0];
828 } __packed;
831 static int8_t subelements(struct pkt_buff *pkt, u8 len)
833 u8 i, j;
834 u8 *data;
836 for (i=0; i<len;) {
837 struct subelement *sub;
839 sub = (struct subelement *) pkt_pull(pkt, sizeof(*sub));
840 if (sub == NULL)
841 return 0;
843 tprintf(", Subelement ID %u, ", sub->id);
844 tprintf("Length %u, ", sub->len);
846 data = pkt_pull(pkt, sub->len);
847 if (data == NULL)
848 return 0;
850 tprintf("Data: 0x");
851 for(j=0; j < sub->len; j++)
852 tprintf("%.2x ", data[j]);
854 i += sub->len + 1;
857 /* Not needed ?! Should break before*/
859 *if (i != len) {
860 * tprintf("Length error");
861 * return 0;
865 return 1;
868 static int8_t inf_reserved(struct pkt_buff *pkt, u8 *id)
870 u8 i;
871 u8 *data;
872 struct element_reserved *reserved;
874 reserved = (struct element_reserved *) pkt_pull(pkt, sizeof(*reserved));
875 if (reserved == NULL)
876 return 0;
878 tprintf("Reserved (%u, Len (%u)): ", *id, reserved->len);
880 data = pkt_pull(pkt, reserved->len);
881 if (data == NULL)
882 return 0;
884 tprintf("Data 0x");
885 for (i = 0; i < reserved->len; i++)
886 tprintf("%.2x", data[i]);
888 return 1;
891 static int8_t inf_ssid(struct pkt_buff *pkt, u8 *id)
893 u8 i;
894 struct element_ssid *ssid;
895 char *ssid_name;
897 ssid = (struct element_ssid *) pkt_pull(pkt, sizeof(*ssid));
898 if (ssid == NULL)
899 return 0;
901 tprintf(" SSID (%u, Len (%u)): ", *id, ssid->len);
903 if ((ssid->len - sizeof(*ssid) + 1) > 0) {
904 ssid_name = (char *) pkt_pull(pkt, ssid->len);
905 if (ssid_name == NULL)
906 return 0;
908 for (i = 0; i < ssid->len; i++)
909 tprintf("%c",ssid_name[i]);
910 } else {
911 tprintf("Wildcard SSID");
914 return 1;
917 static int8_t inf_supp_rates(struct pkt_buff *pkt, u8 *id)
919 u8 i;
920 u8 *rates;
921 struct element_supp_rates *supp_rates;
923 supp_rates = (struct element_supp_rates *)
924 pkt_pull(pkt, sizeof(*supp_rates));
925 if (supp_rates == NULL)
926 return 0;
928 tprintf(" Supp. Rates (%u, Len (%u)): ", *id, supp_rates->len);
929 if (len_lt_error(supp_rates->len, 1))
930 return 0;
932 if ((supp_rates->len - sizeof(*supp_rates) + 1) > 0) {
933 rates = pkt_pull(pkt, supp_rates->len);
934 if (rates == NULL)
935 return 0;
937 for (i = 0; i < supp_rates->len; i++)
938 tprintf("%g%s ", ((rates[i] & 0x80) >> 7) ?
939 data_rates(rates[i] & 0x3f) :
940 ((rates[i] & 0x3f) * 0.5),
941 ((rates[i] & 0x80) >> 7) ? "(B)" : "");
942 return 1;
945 return 0;
948 static int8_t inf_fh_ps(struct pkt_buff *pkt, u8 *id)
950 struct element_fh_ps *fh_ps;
952 fh_ps = (struct element_fh_ps *) pkt_pull(pkt, sizeof(*fh_ps));
953 if (fh_ps == NULL)
954 return 0;
956 tprintf(" FH Param Set (%u, Len(%u)): ", *id, fh_ps->len);
957 if (len_neq_error(fh_ps->len, 5))
958 return 0;
959 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps->dwell_time) * TU);
960 tprintf("HopSet: %u, ", fh_ps->hop_set);
961 tprintf("HopPattern: %u, ", fh_ps->hop_pattern);
962 tprintf("HopIndex: %u", fh_ps->hop_index);
964 return 1;
967 static int8_t inf_dsss_ps(struct pkt_buff *pkt, u8 *id)
969 struct element_dsss_ps *dsss_ps;
971 dsss_ps = (struct element_dsss_ps *) pkt_pull(pkt, sizeof(*dsss_ps));
972 if (dsss_ps == NULL)
973 return 0;
975 tprintf(" DSSS Param Set (%u, Len(%u)): ", *id, dsss_ps->len);
976 if (len_neq_error(dsss_ps->len, 1))
977 return 0;
978 tprintf("Current Channel: %u", dsss_ps->curr_ch);
980 return 1;
983 static int8_t inf_cf_ps(struct pkt_buff *pkt, u8 *id)
985 struct element_cf_ps *cf_ps;
987 cf_ps = (struct element_cf_ps *) pkt_pull(pkt, sizeof(*cf_ps));
988 if (cf_ps == NULL)
989 return 0;
991 tprintf(" CF Param Set (%u, Len(%u)): ", *id, cf_ps->len);
992 if (len_neq_error(cf_ps->len, 6))
993 return 0;
994 tprintf("CFP Count: %u, ", cf_ps->cfp_cnt);
995 tprintf("CFP Period: %u, ", cf_ps->cfp_period);
996 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps->cfp_max_dur) * TU);
997 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps->cfp_dur_rem) * TU);
999 return 1;
1002 static int8_t inf_tim(struct pkt_buff *pkt, u8 *id)
1004 struct element_tim *tim;
1005 u8 i;
1007 tim = (struct element_tim *) pkt_pull(pkt, sizeof(*tim));
1008 if (tim == NULL)
1009 return 0;
1011 tprintf(" TIM (%u, Len(%u)): ", *id, tim->len);
1012 if (len_lt_error(tim->len, 3))
1013 return 0;
1014 tprintf("DTIM Count: %u, ", tim->dtim_cnt);
1015 tprintf("DTIM Period: %u, ", tim->dtim_period);
1016 tprintf("Bitmap Control: %u, ", tim->bmp_cntrl);
1017 if ((tim->len - sizeof(*tim) + 1) > 0) {
1018 u8 *bmp = pkt_pull(pkt, (tim->len - sizeof(*tim) + 1));
1019 if (bmp == NULL)
1020 return 0;
1022 tprintf("Partial Virtual Bitmap: 0x");
1023 for (i = 0; i < (tim->len - sizeof(*tim) + 1); i++)
1024 tprintf("%.2x", bmp[i]);
1027 return 1;
1030 static int8_t inf_ibss_ps(struct pkt_buff *pkt, u8 *id)
1032 struct element_ibss_ps *ibss_ps;
1034 ibss_ps = (struct element_ibss_ps *) pkt_pull(pkt, sizeof(*ibss_ps));
1035 if (ibss_ps == NULL)
1036 return 0;
1038 tprintf(" IBSS Param Set (%u, Len(%u)): ", *id, ibss_ps->len);
1039 if (len_neq_error(ibss_ps->len, 2))
1040 return 0;
1041 tprintf("ATIM Window: %fs", le16_to_cpu(ibss_ps->atim_win) * TU);
1043 return 1;
1046 static int8_t inf_country(struct pkt_buff *pkt, u8 *id)
1048 u8 i;
1049 u8 *pad;
1050 struct element_country *country;
1052 country = (struct element_country *) pkt_pull(pkt, sizeof(*country));
1053 if (country == NULL)
1054 return 0;
1056 tprintf(" Country (%u, Len(%u)): ", *id, country->len);
1057 if (len_lt_error(country->len, 6))
1058 return 0;
1059 tprintf("Country String: %c%c%c", country->country_first,
1060 country->country_sec, country->country_third);
1062 for (i = country->len % 3; i < (country->len - 3); i += 3) {
1063 struct element_country_tripled *country_tripled;
1065 country_tripled = (struct element_country_tripled *)
1066 pkt_pull(pkt, sizeof(*country_tripled));
1067 if (country_tripled == NULL)
1068 return 0;
1070 if(country_tripled->frst_ch >= 201) {
1071 tprintf("Oper Ext ID: %u, ", country_tripled->frst_ch);
1072 tprintf("Operating Class: %u, ", country_tripled->nr_ch);
1073 tprintf("Coverage Class: %u", country_tripled->max_trans);
1074 } else {
1075 tprintf("First Ch Nr: %u, ", country_tripled->frst_ch);
1076 tprintf("Nr of Ch: %u, ", country_tripled->nr_ch);
1077 tprintf("Max Transmit Pwr Lvl: %u", country_tripled->max_trans);
1081 if(country->len % 3) {
1082 pad = pkt_pull(pkt, 1);
1083 if (pad == NULL)
1084 return 0;
1086 tprintf(", Pad: 0x%x", *pad);
1089 return 1;
1092 static int8_t inf_hop_pp(struct pkt_buff *pkt, u8 *id)
1094 struct element_hop_pp *hop_pp;
1096 hop_pp = (struct element_hop_pp *) pkt_pull(pkt, sizeof(*hop_pp));
1097 if (hop_pp == NULL)
1098 return 0;
1100 tprintf(" Hopping Pattern Param (%u, Len(%u)): ", *id, hop_pp->len);
1101 if (len_neq_error(hop_pp->len, 2))
1102 return 0;
1103 tprintf("Prime Radix: %u, ", hop_pp->prime_radix);
1104 tprintf("Nr of Ch: %u", hop_pp->nr_ch);
1106 return 1;
1109 static int8_t inf_hop_pt(struct pkt_buff *pkt, u8 *id)
1111 int i;
1112 u8 *rand_tabl;
1113 struct element_hop_pt *hop_pt;
1115 hop_pt = (struct element_hop_pt *) pkt_pull(pkt, sizeof(*hop_pt));
1116 if (hop_pt == NULL)
1117 return 0;
1119 tprintf(" Hopping Pattern Table (%u, Len(%u)): ", *id, hop_pt->len);
1120 if (len_lt_error(hop_pt->len, 4))
1121 return 0;
1122 tprintf("Flag: %u, ", hop_pt->flag);
1123 tprintf("Nr of Sets: %u, ", hop_pt->nr_sets);
1124 tprintf("Modulus: %u, ", hop_pt->modules);
1125 tprintf("Offs: %u", hop_pt->offs);
1127 if ((hop_pt->len - sizeof(*hop_pt) + 1) > 0) {
1128 rand_tabl = pkt_pull(pkt, (hop_pt->len - sizeof(*hop_pt) + 1));
1129 if (rand_tabl == NULL)
1130 return 0;
1132 tprintf(", Rand table: 0x");
1133 for (i = 0; i < (hop_pt->len - sizeof(*hop_pt) + 1); i++)
1134 tprintf("%.2x", rand_tabl[i]);
1137 return 1;
1140 static int8_t inf_req(struct pkt_buff *pkt, u8 *id)
1142 int i;
1143 struct element_req *req;
1144 u8 *req_ids;
1146 req = (struct element_req *) pkt_pull(pkt, sizeof(*req));
1147 if (req == NULL)
1148 return 0;
1150 tprintf(" Request Element (%u, Len(%u)): ", *id, req->len);
1151 if ((req->len - sizeof(*req) + 1) > 0) {
1152 req_ids = pkt_pull(pkt, (req->len - sizeof(*req) + 1));
1153 if (req_ids == NULL)
1154 return 0;
1156 tprintf(", Requested Element IDs: ");
1157 for (i = 0; i < (req->len - sizeof(*req) + 1); i++)
1158 tprintf("%u ", req_ids[i]);
1161 return 1;
1164 static int8_t inf_bss_load(struct pkt_buff *pkt, u8 *id)
1166 struct element_bss_load *bss_load;
1168 bss_load = (struct element_bss_load *) pkt_pull(pkt, sizeof(*bss_load));
1169 if (bss_load == NULL)
1170 return 0;
1172 tprintf(" BSS Load element (%u, Len(%u)): ", *id, bss_load->len);
1173 if (len_neq_error(bss_load->len, 5))
1174 return 0;
1175 tprintf("Station Count: %u, ", le16_to_cpu(bss_load->station_cnt));
1176 tprintf("Channel Utilization: %u, ", bss_load->ch_util);
1177 tprintf("Available Admission Capacity: %uus",
1178 bss_load->avlb_adm_cap * 32);
1180 return 1;
1183 static int8_t inf_edca_ps(struct pkt_buff *pkt, u8 *id)
1185 u32 ac_be, ac_bk, ac_vi, ac_vo;
1186 struct element_edca_ps *edca_ps;
1188 edca_ps = (struct element_edca_ps *) pkt_pull(pkt, sizeof(*edca_ps));
1189 if (edca_ps == NULL)
1190 return 0;
1192 ac_be = le32_to_cpu(edca_ps->ac_be);
1193 ac_bk = le32_to_cpu(edca_ps->ac_bk);
1194 ac_vi = le32_to_cpu(edca_ps->ac_vi);
1195 ac_vo = le32_to_cpu(edca_ps->ac_vo);
1197 tprintf(" EDCA Param Set (%u, Len(%u)): ", *id, edca_ps->len);
1198 if (len_neq_error(edca_ps->len, 18))
1199 return 0;
1200 tprintf("QoS Info: 0x%x (-> EDCA Param Set Update Count (%u),"
1201 "Q-Ack (%u), Queue Re (%u), TXOP Req(%u), Res(%u)), ",
1202 edca_ps->qos_inf, edca_ps->qos_inf >> 4,
1203 (edca_ps->qos_inf >> 3) & 1, (edca_ps->qos_inf >> 2) & 1,
1204 (edca_ps->qos_inf >> 1) & 1, edca_ps->qos_inf & 1);
1205 tprintf("Reserved: 0x%x, ", edca_ps->res);
1206 tprintf("AC_BE Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1207 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_be,
1208 ac_be >> 28, (ac_be >> 27) & 1, (ac_be >> 25) & 3,
1209 (ac_be >> 24) & 1, (ac_be >> 20) & 15, (ac_be >> 16) & 15,
1210 bswap_16(ac_be & 0xFFFF) * 32);
1211 tprintf("AC_BK Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1212 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_bk,
1213 ac_bk >> 28, (ac_bk >> 27) & 1, (ac_bk >> 25) & 3,
1214 (ac_bk >> 24) & 1, (ac_bk >> 20) & 15, (ac_bk >> 16) & 15,
1215 bswap_16(ac_bk & 0xFFFF) * 32);
1216 tprintf("AC_VI Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1217 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_vi,
1218 ac_vi >> 28, (ac_vi >> 27) & 1, (ac_vi >> 25) & 3,
1219 (ac_vi >> 24) & 1, (ac_vi >> 20) & 15, (ac_vi >> 16) & 15,
1220 bswap_16(ac_vi & 0xFFFF) * 32);
1221 tprintf("AC_VO Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1222 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)", ac_vo,
1223 ac_vo >> 28, (ac_vo >> 27) & 1, (ac_vo >> 25) & 3,
1224 (ac_vo >> 24) & 1, (ac_vo >> 20) & 15, (ac_vo >> 16) & 15,
1225 bswap_16(ac_vo & 0xFFFF) * 32);
1227 return 1;
1230 static int8_t inf_tspec(struct pkt_buff *pkt, u8 *id)
1232 u16 nom_msdu_size, surplus_bandw_allow;
1233 struct element_tspec *tspec;
1235 tspec = (struct element_tspec *) pkt_pull(pkt, sizeof(*tspec));
1236 if (tspec == NULL)
1237 return 0;
1239 nom_msdu_size = le16_to_cpu(tspec->nom_msdu_size);
1240 surplus_bandw_allow = le16_to_cpu(tspec->surplus_bandw_allow);
1242 tprintf(" TSPEC (%u, Len(%u)): ", *id, tspec->len);
1243 if (len_neq_error(tspec->len, 55))
1244 return 0;
1245 tprintf("Traffic Type: %u, ", tspec->traffic_type);
1246 tprintf("TSID: %u, ", tspec->tsid);
1247 tprintf("Direction: %u, ", tspec->direction);
1248 tprintf("Access Policy: %u, ", tspec->access_policy);
1249 tprintf("Aggregation: %u, ", tspec->aggr);
1250 tprintf("APSD: %u, ", tspec->apsd);
1251 tprintf("User Priority: %u, ", tspec->user_prior);
1252 tprintf("TSinfo Ack Policy: %u, ", tspec->tsinfo_ack_pol);
1253 tprintf("Schedule: %u, ", tspec->schedule);
1254 tprintf("Reserved: 0x%x, ", tspec->res);
1255 tprintf("Nominal MSDU Size: %uB (Fixed (%u)), ",
1256 nom_msdu_size >> 1, nom_msdu_size & 1);
1257 tprintf("Maximum MSDU Size: %uB, ", le16_to_cpu(tspec->max_msdu_size));
1258 tprintf("Minimum Service Interval: %uus, ",
1259 le32_to_cpu(tspec->min_srv_intv));
1260 tprintf("Maximum Service Interval: %uus, ",
1261 le32_to_cpu(tspec->max_srv_intv));
1262 tprintf("Inactivity Interval: %uus, ",
1263 le32_to_cpu(tspec->inactive_intv));
1264 tprintf("Suspension Interval: %uus, ", le32_to_cpu(tspec->susp_intv));
1265 tprintf("Service Start Time: %uus, ",
1266 le32_to_cpu(tspec->srv_start_time));
1267 tprintf("Minimum Data Rate: %ub/s, ",le32_to_cpu(tspec->min_data_rate));
1268 tprintf("Mean Data Rate: %ub/s, ", le32_to_cpu(tspec->mean_data_rate));
1269 tprintf("Peak Data Rate: %ub/s, ",le32_to_cpu(tspec->peak_data_rate));
1270 tprintf("Burst Size: %uB, ", le32_to_cpu(tspec->burst_size));
1271 tprintf("Delay Bound: %uus, ", le32_to_cpu(tspec->delay_bound));
1272 tprintf("Minimum PHY Rate: %ub/s, ", le32_to_cpu(tspec->min_phy_rate));
1273 tprintf("Surplus Bandwidth: %u.%u, ", surplus_bandw_allow >> 13,
1274 surplus_bandw_allow & 0x1FFF);
1275 tprintf("Medium Time: %uus", le16_to_cpu(tspec->med_time) * 32);
1277 return 1;
1280 static const char *class_type(u8 type)
1282 switch (type) {
1283 case 0: return "Ethernet parameters";
1284 case 1: return "TCP/UDP IP parameters";
1285 case 2: return "IEEE 802.1Q parameters";
1286 case 3: return "Filter Offset parameters";
1287 case 4: return "IP and higher layer parameters";
1288 case 5: return "IEEE 802.1D/Q parameters";
1289 default: return "Reserved";
1293 static int8_t inf_tclas(struct pkt_buff *pkt, u8 *id)
1295 struct element_tclas *tclas;
1296 struct element_tclas_frm_class *frm_class;
1298 tclas = (struct element_tclas *) pkt_pull(pkt, sizeof(*tclas));
1299 if (tclas == NULL)
1300 return 0;
1302 frm_class = (struct element_tclas_frm_class *)
1303 pkt_pull(pkt, sizeof(*frm_class));
1304 if (frm_class == NULL)
1305 return 0;
1307 tprintf(" TCLAS (%u, Len(%u)): ", *id, tclas->len);
1308 if (len_lt_error(tclas->len, 3))
1309 return 0;
1310 tprintf("User Priority: %u, ", tclas->user_priority);
1311 tprintf("Classifier Type: %s (%u), ", class_type(frm_class->type),
1312 frm_class->type);
1313 tprintf("Classifier Mask: 0x%x, ", frm_class->mask);
1315 if(frm_class->type == 0) {
1316 struct element_tclas_type0 *type0;
1318 type0 = (struct element_tclas_type0 *)
1319 pkt_pull(pkt, sizeof(*type0));
1320 if (type0 == NULL)
1321 return 0;
1323 /* I think little endian, like the rest */
1324 tprintf("Src Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1325 type0->sa[5], type0->sa[4], type0->sa[3],
1326 type0->sa[2], type0->sa[1], type0->sa[0]);
1327 tprintf("Dst Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1328 type0->da[5], type0->da[4], type0->da[3],
1329 type0->da[2], type0->da[1], type0->da[0]);
1330 tprintf("Type: 0x%x", le16_to_cpu(type0->type));
1332 else if(frm_class->type == 1) {
1333 struct element_tclas_type1 *type1;
1335 type1 = (struct element_tclas_type1 *)
1336 pkt_pull(pkt, sizeof(*type1));
1337 if (type1 == NULL)
1338 return 0;
1340 tprintf("Version: %u, ", type1->version);
1341 /* big endian format follows */
1342 if(type1->version == 4) {
1343 struct element_tclas_type1_ip4 *type1_ip4;
1344 char src_ip[INET_ADDRSTRLEN];
1345 char dst_ip[INET_ADDRSTRLEN];
1347 type1_ip4 = (struct element_tclas_type1_ip4 *)
1348 pkt_pull(pkt, sizeof(*type1_ip4));
1349 if (type1_ip4 == NULL)
1350 return 0;
1352 inet_ntop(AF_INET, &type1_ip4->sa, src_ip, sizeof(src_ip));
1353 inet_ntop(AF_INET, &type1_ip4->da, dst_ip, sizeof(dst_ip));
1355 tprintf("Src IP: %s, ", src_ip);
1356 tprintf("Dst IP: %s, ", dst_ip);
1357 tprintf("Src Port: %u, ", ntohs(type1_ip4->sp));
1358 tprintf("Dst Port: %u, ", ntohs(type1_ip4->dp));
1359 tprintf("DSCP: 0x%x, ", type1_ip4->dscp);
1360 tprintf("Proto: %u, ", type1_ip4->proto);
1361 tprintf("Res: 0x%x", type1_ip4->reserved);
1363 else if(type1->version == 6) {
1364 struct element_tclas_type1_ip6 *type1_ip6;
1365 char src_ip[INET6_ADDRSTRLEN];
1366 char dst_ip[INET6_ADDRSTRLEN];
1368 type1_ip6 = (struct element_tclas_type1_ip6 *)
1369 pkt_pull(pkt, sizeof(*type1_ip6));
1370 if (type1_ip6 == NULL)
1371 return 0;
1373 inet_ntop(AF_INET6, &type1_ip6->sa,
1374 src_ip, sizeof(src_ip));
1375 inet_ntop(AF_INET6, &type1_ip6->da,
1376 dst_ip, sizeof(dst_ip));
1378 tprintf("Src IP: %s, ", src_ip);
1379 tprintf("Dst IP: %s, ", dst_ip);
1380 tprintf("Src Port: %u, ", ntohs(type1_ip6->sp));
1381 tprintf("Dst Port: %u, ", ntohs(type1_ip6->dp));
1382 tprintf("Flow Label: 0x%x%x%x", type1_ip6->flow_label1,
1383 type1_ip6->flow_label2, type1_ip6->flow_label3);
1385 else {
1386 tprintf("Version (%u) not supported", type1->version);
1387 return 0;
1391 else if(frm_class->type == 2) {
1392 struct element_tclas_type2 *type2;
1394 type2 = (struct element_tclas_type2 *)
1395 pkt_pull(pkt, sizeof(*type2));
1396 if (type2 == NULL)
1397 return 0;
1399 tprintf("802.1Q VLAN TCI: 0x%x", ntohs(type2->vlan_tci));
1401 else if(frm_class->type == 3) {
1402 struct element_tclas_type3 *type3;
1403 u8 len, i;
1404 u8 *val;
1406 type3 = (struct element_tclas_type3 *)
1407 pkt_pull(pkt, sizeof(*type3));
1408 if (type3 == NULL)
1409 return 0;
1411 len = (tclas->len - 5) / 2;
1413 tprintf("Filter Offset: %u, ", type3->offs);
1415 if((len & 1) || (len_lt_error(tclas->len, 5))) {
1416 tprintf("Length of TCLAS (%u) not correct", tclas->len);
1417 return 0;
1419 else {
1420 val = pkt_pull(pkt, len);
1421 if (val == NULL)
1422 return 0;
1424 tprintf("Filter Value: 0x");
1425 for (i = 0; i < len / 2; i++)
1426 tprintf("%x ", val[i]);
1427 tprintf(", ");
1428 tprintf("Filter Mask: 0x");
1429 for (i = len / 2; i < len; i++)
1430 tprintf("%x ", val[i]);
1434 else if(frm_class->type == 4) {
1435 struct element_tclas_type4 *type4;
1437 type4 = (struct element_tclas_type4 *)
1438 pkt_pull(pkt, sizeof(*type4));
1439 if (type4 == NULL)
1440 return 0;
1442 tprintf("Version: %u, ", type4->version);
1443 /* big endian format follows */
1444 if(type4->version == 4) {
1445 struct element_tclas_type4_ip4 *type4_ip4;
1446 char src_ip[INET_ADDRSTRLEN];
1447 char dst_ip[INET_ADDRSTRLEN];
1449 type4_ip4 = (struct element_tclas_type4_ip4 *)
1450 pkt_pull(pkt, sizeof(*type4_ip4));
1451 if (type4_ip4 == NULL)
1452 return 0;
1454 inet_ntop(AF_INET, &type4_ip4->sa, src_ip, sizeof(src_ip));
1455 inet_ntop(AF_INET, &type4_ip4->da, dst_ip, sizeof(dst_ip));
1457 tprintf("Src IP: %s, ", src_ip);
1458 tprintf("Dst IP: %s, ", dst_ip);
1459 tprintf("Src Port: %u, ", ntohs(type4_ip4->sp));
1460 tprintf("Dst Port: %u, ", ntohs(type4_ip4->dp));
1461 tprintf("DSCP: 0x%x, ", type4_ip4->dscp);
1462 tprintf("Proto: %u, ", type4_ip4->proto);
1463 tprintf("Res: 0x%x", type4_ip4->reserved);
1465 else if(type4->version == 6) {
1466 struct element_tclas_type4_ip6 *type4_ip6;
1467 char src_ip[INET6_ADDRSTRLEN];
1468 char dst_ip[INET6_ADDRSTRLEN];
1470 type4_ip6 = (struct element_tclas_type4_ip6 *)
1471 pkt_pull(pkt, sizeof(*type4_ip6));
1472 if (type4_ip6 == NULL)
1473 return 0;
1475 inet_ntop(AF_INET6, &type4_ip6->sa,
1476 src_ip, sizeof(src_ip));
1477 inet_ntop(AF_INET6, &type4_ip6->da,
1478 dst_ip, sizeof(dst_ip));
1480 tprintf("Src IP: %s, ", src_ip);
1481 tprintf("Dst IP: %s, ", dst_ip);
1482 tprintf("Src Port: %u, ", ntohs(type4_ip6->sp));
1483 tprintf("Dst Port: %u, ", ntohs(type4_ip6->dp));
1484 tprintf("DSCP: 0x%x, ", type4_ip6->dscp);
1485 tprintf("Nxt Hdr: %u, ", type4_ip6->nxt_hdr);
1486 tprintf("Flow Label: 0x%x%x%x", type4_ip6->flow_label1,
1487 type4_ip6->flow_label2, type4_ip6->flow_label3);
1489 else {
1490 tprintf("Version (%u) not supported", type4->version);
1491 return 0;
1494 else if(frm_class->type == 5) {
1495 struct element_tclas_type5 *type5;
1497 type5 = (struct element_tclas_type5 *)
1498 pkt_pull(pkt, sizeof(*type5));
1499 if (type5 == NULL)
1500 return 0;
1502 tprintf("802.1Q PCP: 0x%x, ", type5->pcp);
1503 tprintf("802.1Q CFI: 0x%x, ", type5->cfi);
1504 tprintf("802.1Q VID: 0x%x", type5->vid);
1506 else {
1507 tprintf("Classifier Type (%u) not supported", frm_class->type);
1508 return 0;
1511 return 1;
1514 static int8_t inf_sched(struct pkt_buff *pkt, u8 *id)
1516 struct element_schedule *schedule;
1517 u16 info;
1519 schedule = (struct element_schedule *) pkt_pull(pkt, sizeof(*schedule));
1520 if (schedule == NULL)
1521 return 0;
1523 info = le16_to_cpu(schedule->inf);
1525 tprintf(" Schedule (%u, Len(%u)): ", *id, schedule->len);
1526 if (len_neq_error(schedule->len, 12))
1527 return 0;
1529 tprintf("Aggregation: %u, ", info >> 15);
1530 tprintf("TSID: %u, ", (info >> 11) & 0xF);
1531 tprintf("Direction: %u, ", (info >> 9) & 0x3);
1532 tprintf("Res: %u, ", info & 0x1FF);
1533 tprintf("Serv Start Time: %uus, ", le32_to_cpu(schedule->start));
1534 tprintf("Serv Interval: %uus, ", le32_to_cpu(schedule->serv_intv));
1535 tprintf("Spec Interval: %fs", le32_to_cpu(schedule->spec_intv) * TU);
1537 return 1;
1540 static int8_t inf_chall_txt(struct pkt_buff *pkt, u8 *id)
1542 struct element_chall_txt *chall_txt;
1543 u8 i;
1544 u8 *txt;
1546 chall_txt = (struct element_chall_txt *)
1547 pkt_pull(pkt, sizeof(*chall_txt));
1548 if (chall_txt == NULL)
1549 return 0;
1551 tprintf(" Challenge Text (%u, Len(%u)): ", *id, chall_txt->len);
1552 if ((chall_txt->len - sizeof(*chall_txt) + 1) > 0) {
1553 txt = pkt_pull(pkt, (chall_txt->len - sizeof(*chall_txt) + 1));
1554 if (txt == NULL)
1555 return 0;
1557 tprintf("0x");
1558 for (i = 0; i < (chall_txt->len - sizeof(*chall_txt) + 1); i++)
1559 tprintf("%x", txt[i]);
1562 return 1;
1565 static int8_t inf_pwr_constr(struct pkt_buff *pkt, u8 *id)
1567 struct element_pwr_constr *pwr_constr;
1569 pwr_constr = (struct element_pwr_constr *) pkt_pull(pkt, sizeof(*pwr_constr));
1570 if (pwr_constr == NULL)
1571 return 0;
1573 tprintf(" Power Constraint (%u, Len(%u)): ", *id, pwr_constr->len);
1574 if (len_neq_error(pwr_constr->len, 1))
1575 return 0;
1577 tprintf("Local Power Constraint: %udB", pwr_constr->local_pwr_constr);
1579 return 1;
1582 static int8_t inf_pwr_cap(struct pkt_buff *pkt, u8 *id)
1584 struct element_pwr_cap *pwr_cap;
1586 pwr_cap = (struct element_pwr_cap *) pkt_pull(pkt, sizeof(*pwr_cap));
1587 if (pwr_cap == NULL)
1588 return 0;
1590 tprintf(" Power Capability (%u, Len(%u)): ", *id, pwr_cap->len);
1591 if (len_neq_error(pwr_cap->len, 2))
1592 return 0;
1594 tprintf("Min. Transm. Pwr Cap.: %ddBm, ", (int8_t)pwr_cap->min_pwr_cap);
1595 tprintf("Max. Transm. Pwr Cap.: %ddBm", (int8_t)pwr_cap->max_pwr_cap);
1597 return 1;
1600 static int8_t inf_tpc_req(struct pkt_buff *pkt, u8 *id)
1602 struct element_tpc_req *tpc_req;
1604 tpc_req = (struct element_tpc_req *) pkt_pull(pkt, sizeof(*tpc_req));
1605 if (tpc_req == NULL)
1606 return 0;
1608 tprintf(" TPC Request (%u, Len(%u))", *id, tpc_req->len);
1609 if (len_neq_error(tpc_req->len, 0))
1610 return 0;
1612 return 1;
1615 static int8_t inf_tpc_rep(struct pkt_buff *pkt, u8 *id)
1617 struct element_tpc_rep *tpc_rep;
1619 tpc_rep = (struct element_tpc_rep *) pkt_pull(pkt, sizeof(*tpc_rep));
1620 if (tpc_rep == NULL)
1621 return 0;
1623 tprintf(" TPC Report (%u, Len(%u)): ", *id, tpc_rep->len);
1624 if (len_neq_error(tpc_rep->len, 2))
1625 return 0;
1627 tprintf("Transmit Power: %udBm, ", (int8_t)tpc_rep->trans_pwr);
1628 tprintf("Link Margin: %udB", (int8_t)tpc_rep->trans_pwr);
1630 return 1;
1633 static int8_t inf_supp_ch(struct pkt_buff *pkt, u8 *id)
1635 struct element_supp_ch *supp_ch;
1636 u8 i;
1638 supp_ch = (struct element_supp_ch *) pkt_pull(pkt, sizeof(*supp_ch));
1639 if (supp_ch == NULL)
1640 return 0;
1642 tprintf(" Supp Channels (%u, Len(%u)): ", *id, supp_ch->len);
1643 if (len_lt_error(supp_ch->len, 2))
1644 return 0;
1646 if(supp_ch->len & 1) {
1647 tprintf("Length should be even");
1648 return 0;
1651 for (i = 0; i < supp_ch->len; i += 2) {
1652 struct element_supp_ch_tuple *supp_ch_tuple;
1654 supp_ch_tuple = (struct element_supp_ch_tuple *)
1655 pkt_pull(pkt, sizeof(*supp_ch_tuple));
1656 if (supp_ch_tuple == NULL)
1657 return 0;
1659 tprintf("First Channel Nr: %u, ", supp_ch_tuple->first_ch_nr);
1660 tprintf("Nr of Channels: %u, ", supp_ch_tuple->nr_ch);
1663 return 1;
1666 static int8_t inf_ch_sw_ann(struct pkt_buff *pkt, u8 *id)
1668 struct element_ch_sw_ann *ch_sw_ann;
1670 ch_sw_ann = (struct element_ch_sw_ann *)
1671 pkt_pull(pkt, sizeof(*ch_sw_ann));
1672 if (ch_sw_ann == NULL)
1673 return 0;
1675 tprintf(" Channel Switch Announc (%u, Len(%u)): ", *id, ch_sw_ann->len);
1676 if (len_neq_error(ch_sw_ann->len, 3))
1677 return 0;
1679 tprintf("Switch Mode: %u, ", ch_sw_ann->switch_mode);
1680 tprintf("New Nr: %u, ", ch_sw_ann->new_nr);
1681 tprintf("Switch Count: %u", ch_sw_ann->switch_cnt);
1683 return 1;
1686 static const char *meas_type(u8 type)
1688 switch (type) {
1689 case 0: return "Basic";
1690 case 1: return "Clear Channel assesment (CCA)";
1691 case 2: return "Receive power indication (RPI) histogram";
1692 case 3: return "Channel load";
1693 case 4: return "Noise histogram";
1694 case 5: return "Beacon";
1695 case 6: return "Frame";
1696 case 7: return "STA statistics";
1697 case 8: return "LCI";
1698 case 9: return "Transmit stream/category measurement";
1699 case 10: return "Multicast diagnostics";
1700 case 11: return "Location Civic";
1701 case 12: return "Location Identifier";
1702 case 13 ... 255: return "Reserved";
1706 static int8_t inf_meas_req(struct pkt_buff *pkt, u8 *id)
1708 struct element_meas_req *meas_req;
1710 meas_req = (struct element_meas_req *) pkt_pull(pkt, sizeof(*meas_req));
1711 if (meas_req == NULL)
1712 return 0;
1714 tprintf(" Measurement Req (%u, Len(%u)): ", *id, meas_req->len);
1715 if (len_lt_error(meas_req->len, 3))
1716 return 0;
1718 tprintf("Token: %u, ", meas_req->token);
1719 tprintf("Req Mode: 0x%x (Parallel (%u), Enable(%u), Request(%u), "
1720 "Report(%u), Dur Mand(%u), Res(0x%x)), ", meas_req->req_mode,
1721 meas_req->req_mode & 0x1,
1722 (meas_req->req_mode >> 1) & 0x1,
1723 (meas_req->req_mode >> 2) & 0x1,
1724 (meas_req->req_mode >> 3) & 0x1,
1725 (meas_req->req_mode >> 4) & 0x1,
1726 meas_req->req_mode >> 7);
1727 tprintf("Type: %s (%u), ", meas_type(meas_req->type), meas_req->type);
1729 if(meas_req->len > 3) {
1730 if(meas_req->type == 0) {
1731 struct element_meas_basic *basic;
1733 basic = (struct element_meas_basic *)
1734 pkt_pull(pkt, sizeof(*basic));
1735 if (basic == NULL)
1736 return 0;
1738 if ((meas_req->len - 3 - sizeof(*basic)) != 0) {
1739 tprintf("Length of Req matchs not Type %u",
1740 meas_req->type);
1741 return 0;
1744 tprintf("Ch Nr: %uus, ", basic->ch_nr);
1745 tprintf("Meas Start Time: %lu, ",
1746 le64_to_cpu(basic->start));
1747 tprintf("Meas Duration: %fs",
1748 le16_to_cpu(basic->dur) * TU);
1751 else if(meas_req->type == 1) {
1752 struct element_meas_cca *cca;
1754 cca = (struct element_meas_cca *)
1755 pkt_pull(pkt, sizeof(*cca));
1756 if (cca == NULL)
1757 return 0;
1759 if ((meas_req->len - 3 - sizeof(*cca)) != 0) {
1760 tprintf("Length of Req matchs not Type %u",
1761 meas_req->type);
1762 return 0;
1765 tprintf("Ch Nr: %uus, ", cca->ch_nr);
1766 tprintf("Meas Start Time: %lu, ",
1767 le64_to_cpu(cca->start));
1768 tprintf("Meas Duration: %fs",
1769 le16_to_cpu(cca->dur) * TU);
1771 else if(meas_req->type == 2) {
1772 struct element_meas_rpi *rpi;
1774 rpi = (struct element_meas_rpi *)
1775 pkt_pull(pkt, sizeof(*rpi));
1776 if (rpi == NULL)
1777 return 0;
1779 if ((meas_req->len - 3 - sizeof(*rpi)) != 0) {
1780 tprintf("Length of Req matchs not Type %u",
1781 meas_req->type);
1782 return 0;
1785 tprintf("Ch Nr: %uus, ", rpi->ch_nr);
1786 tprintf("Meas Start Time: %lu, ",
1787 le64_to_cpu(rpi->start));
1788 tprintf("Meas Duration: %fs",
1789 le16_to_cpu(rpi->dur) * TU);
1791 else if(meas_req->type == 3) {
1792 struct element_meas_ch_load *ch_load;
1794 ch_load = (struct element_meas_ch_load *)
1795 pkt_pull(pkt, sizeof(*ch_load));
1796 if (ch_load == NULL)
1797 return 0;
1799 if ((ssize_t)(meas_req->len - 3 - sizeof(*ch_load)) < 0) {
1800 tprintf("Length of Req matchs not Type %u",
1801 meas_req->type);
1802 return 0;
1805 tprintf("OP Class: %u, ", ch_load->op_class);
1806 tprintf("Ch Nr: %u, ", ch_load->ch_nr);
1807 tprintf("Rand Intv: %fs, ",
1808 le16_to_cpu(ch_load->rand_intv) * TU);
1809 tprintf("Meas Duration: %fs",
1810 le16_to_cpu(ch_load->dur) * TU);
1812 if(!subelements(pkt,
1813 meas_req->len - 3 - sizeof(*ch_load)))
1814 return 0;
1816 else if(meas_req->type == 4) {
1817 struct element_meas_noise *noise;
1819 noise = (struct element_meas_noise *)
1820 pkt_pull(pkt, sizeof(*noise));
1821 if (noise == NULL)
1822 return 0;
1824 if ((ssize_t)(meas_req->len - 3 - sizeof(*noise)) < 0) {
1825 tprintf("Length of Req matchs not Type %u",
1826 meas_req->type);
1827 return 0;
1830 tprintf("OP Class: %u, ", noise->op_class);
1831 tprintf("Ch Nr: %u, ", noise->ch_nr);
1832 tprintf("Rand Intv: %fs, ",
1833 le16_to_cpu(noise->rand_intv) * TU);
1834 tprintf("Meas Duration: %fs",
1835 le16_to_cpu(noise->dur) * TU);
1837 if(!subelements(pkt,
1838 meas_req->len - 3 - sizeof(*noise)))
1839 return 0;
1841 else if(meas_req->type == 5) {
1842 struct element_meas_beacon *beacon;
1844 beacon = (struct element_meas_beacon *)
1845 pkt_pull(pkt, sizeof(*beacon));
1846 if (beacon == NULL)
1847 return 0;
1849 if ((ssize_t)(meas_req->len - 3 - sizeof(*beacon)) < 0) {
1850 tprintf("Length of Req matchs not Type %u",
1851 meas_req->type);
1852 return 0;
1855 tprintf("OP Class: %u, ", beacon->op_class);
1856 tprintf("Ch Nr: %u, ", beacon->ch_nr);
1857 tprintf("Rand Intv: %fs, ",
1858 le16_to_cpu(beacon->rand_intv) * TU);
1859 tprintf("Meas Duration: %fs",
1860 le16_to_cpu(beacon->dur) * TU);
1861 tprintf("Mode: %u, ", beacon->mode);
1862 tprintf("BSSID: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1863 beacon->bssid[0], beacon->bssid[1],
1864 beacon->bssid[2], beacon->bssid[3],
1865 beacon->bssid[4], beacon->bssid[5]);
1867 if(!subelements(pkt,
1868 meas_req->len - 3 - sizeof(*beacon)))
1869 return 0;
1871 else if(meas_req->type == 6) {
1872 struct element_meas_frame *frame;
1874 frame = (struct element_meas_frame *)
1875 pkt_pull(pkt, sizeof(*frame));
1876 if (frame == NULL)
1877 return 0;
1879 if ((ssize_t)(meas_req->len - 3 - sizeof(*frame)) < 0) {
1880 tprintf("Length of Req matchs not Type %u",
1881 meas_req->type);
1882 return 0;
1885 tprintf("OP Class: %u, ", frame->op_class);
1886 tprintf("Ch Nr: %u, ", frame->ch_nr);
1887 tprintf("Rand Intv: %fs, ",
1888 le16_to_cpu(frame->rand_intv) * TU);
1889 tprintf("Meas Duration: %fs",
1890 le16_to_cpu(frame->dur) * TU);
1891 tprintf("Request Type: %u, ", frame->frame);
1892 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1893 frame->mac[0], frame->mac[1],
1894 frame->mac[2], frame->mac[3],
1895 frame->mac[4], frame->mac[5]);
1897 if(!subelements(pkt,
1898 meas_req->len - 3 - sizeof(*frame)))
1899 return 0;
1901 else if(meas_req->type == 7) {
1902 struct element_meas_sta *sta;
1904 sta = (struct element_meas_sta *)
1905 pkt_pull(pkt, sizeof(*sta));
1906 if (sta == NULL)
1907 return 0;
1909 if ((ssize_t)(meas_req->len - 3 - sizeof(*sta)) < 0) {
1910 tprintf("Length of Req matchs not Type %u",
1911 meas_req->type);
1912 return 0;
1915 tprintf("Peer MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1916 sta->peer_mac[0], sta->peer_mac[1],
1917 sta->peer_mac[2], sta->peer_mac[3],
1918 sta->peer_mac[4], sta->peer_mac[5]);
1919 tprintf("Rand Intv: %fs, ",
1920 le16_to_cpu(sta->rand_intv) * TU);
1921 tprintf("Meas Duration: %fs",
1922 le16_to_cpu(sta->dur) * TU);
1923 tprintf("Group ID: %u, ", sta->group_id);
1925 if(!subelements(pkt,
1926 meas_req->len - 3 - sizeof(*sta)))
1927 return 0;
1929 else if(meas_req->type == 8) {
1930 struct element_meas_lci *lci;
1932 lci = (struct element_meas_lci *)
1933 pkt_pull(pkt, sizeof(*lci));
1934 if (lci == NULL)
1935 return 0;
1937 if ((ssize_t)(meas_req->len - 3 - sizeof(*lci)) < 0) {
1938 tprintf("Length of Req matchs not Type %u",
1939 meas_req->type);
1940 return 0;
1943 tprintf("Location Subj: %u, ", lci->loc_subj);
1944 tprintf("Latitude Req Res: %udeg",
1945 lci->latitude_req_res);
1946 tprintf("Longitude Req Res: %udeg",
1947 lci->longitude_req_res);
1948 tprintf("Altitude Req Res: %udeg",
1949 lci->altitude_req_res);
1951 if(!subelements(pkt,
1952 meas_req->len - 3 - sizeof(*lci)))
1953 return 0;
1955 else if(meas_req->type == 9) {
1956 struct element_meas_trans_str_cat *trans;
1958 trans = (struct element_meas_trans_str_cat *)
1959 pkt_pull(pkt, sizeof(*trans));
1960 if (trans == NULL)
1961 return 0;
1963 if ((ssize_t)(meas_req->len - 3 - sizeof(*trans)) < 0) {
1964 tprintf("Length of Req matchs not Type %u",
1965 meas_req->type);
1966 return 0;
1969 tprintf("Rand Intv: %fs, ",
1970 le16_to_cpu(trans->rand_intv) * TU);
1971 tprintf("Meas Duration: %fs",
1972 le16_to_cpu(trans->dur) * TU);
1973 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1974 trans->peer_sta_addr[0], trans->peer_sta_addr[1],
1975 trans->peer_sta_addr[2], trans->peer_sta_addr[3],
1976 trans->peer_sta_addr[4], trans->peer_sta_addr[5]);
1977 tprintf("Traffic ID: %u, ", trans->traffic_id);
1978 tprintf("Bin 0 Range: %u, ", trans->bin_0_range);
1980 if(!subelements(pkt,
1981 meas_req->len - 3 - sizeof(*trans)))
1982 return 0;
1984 else if(meas_req->type == 10) {
1985 struct element_meas_mcast_diag *mcast;
1987 mcast = (struct element_meas_mcast_diag *)
1988 pkt_pull(pkt, sizeof(*mcast));
1989 if (mcast == NULL)
1990 return 0;
1992 if ((ssize_t)(meas_req->len - 3 - sizeof(*mcast)) < 0) {
1993 tprintf("Length of Req matchs not Type %u",
1994 meas_req->type);
1995 return 0;
1998 tprintf("Rand Intv: %fs, ",
1999 le16_to_cpu(mcast->rand_intv) * TU);
2000 tprintf("Meas Duration: %fs",
2001 le16_to_cpu(mcast->dur) * TU);
2002 tprintf("Group MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2003 mcast->group_mac[0], mcast->group_mac[1],
2004 mcast->group_mac[2], mcast->group_mac[3],
2005 mcast->group_mac[4], mcast->group_mac[5]);
2007 if(!subelements(pkt,
2008 meas_req->len - 3 - sizeof(*mcast)))
2009 return 0;
2011 else if(meas_req->type == 11) {
2012 struct element_meas_loc_civic *civic;
2014 civic = (struct element_meas_loc_civic *)
2015 pkt_pull(pkt, sizeof(*civic));
2016 if (civic == NULL)
2017 return 0;
2019 if ((ssize_t)(meas_req->len - 3 - sizeof(*civic)) < 0) {
2020 tprintf("Length of Req matchs not Type %u",
2021 meas_req->type);
2022 return 0;
2025 tprintf("Location Subj: %u, ", civic->loc_subj);
2026 tprintf("Type: %u, ", civic->civic_loc);
2027 tprintf("Srv Intv Units: %u, ",
2028 le16_to_cpu(civic->loc_srv_intv_unit));
2029 tprintf("Srv Intv: %u, ", civic->loc_srv_intv);
2031 if(!subelements(pkt,
2032 meas_req->len - 3 - sizeof(*civic)))
2033 return 0;
2035 else if(meas_req->type == 12) {
2036 struct element_meas_loc_id *id;
2038 id = (struct element_meas_loc_id *)
2039 pkt_pull(pkt, sizeof(*id));
2040 if (id == NULL)
2041 return 0;
2043 if ((ssize_t)(meas_req->len - 3 - sizeof(*id)) < 0) {
2044 tprintf("Length of Req matchs not Type %u",
2045 meas_req->type);
2046 return 0;
2049 tprintf("Location Subj: %u, ", id->loc_subj);
2050 tprintf("Srv Intv Units: %u, ",
2051 le16_to_cpu(id->loc_srv_intv_unit));
2052 tprintf("Srv Intv: %u", id->loc_srv_intv);
2054 if(!subelements(pkt,
2055 meas_req->len - 3 - sizeof(*id)))
2056 return 0;
2058 else if(meas_req->type == 255) {
2059 struct element_meas_pause *pause;
2061 pause = (struct element_meas_pause *)
2062 pkt_pull(pkt, sizeof(*pause));
2063 if (pause == NULL)
2064 return 0;
2066 if ((ssize_t)(meas_req->len - 3 - sizeof(*pause)) < 0) {
2067 tprintf("Length of Req matchs not Type %u",
2068 meas_req->type);
2069 return 0;
2072 tprintf("Pause Time: %fs, ", pause->time * 10 * TU);
2074 if(!subelements(pkt,
2075 meas_req->len - 3 - sizeof(*pause)))
2076 return 0;
2078 else {
2079 tprintf("Length field indicates data,"
2080 " but could not interpreted");
2081 return 0;
2085 return 1;
2088 static int8_t inf_meas_rep(struct pkt_buff *pkt, u8 *id)
2090 struct element_meas_rep *meas_rep;
2092 meas_rep = (struct element_meas_rep *) pkt_pull(pkt, sizeof(*meas_rep));
2093 if (meas_rep == NULL)
2094 return 0;
2096 tprintf(" Measurement Rep (%u, Len(%u)): ", *id, meas_rep->len);
2097 if (len_lt_error(meas_rep->len, 3))
2098 return 0;
2100 tprintf("Token: %u, ", meas_rep->token);
2101 tprintf("Rep Mode: 0x%x (Late (%u), Incapable(%u), Refused(%u), ",
2102 meas_rep->rep_mode, meas_rep->rep_mode >> 7,
2103 (meas_rep->rep_mode >> 6) & 0x1,
2104 (meas_rep->rep_mode >> 5) & 0x1);
2105 tprintf("Type: %s (%u), ", meas_type(meas_rep->type), meas_rep->type);
2107 if(meas_rep->len > 3) {
2108 if(meas_rep->type == 0) {
2109 struct element_meas_basic *basic;
2111 basic = (struct element_meas_basic *)
2112 pkt_pull(pkt, sizeof(*basic));
2113 if (basic == NULL)
2114 return 0;
2116 if ((meas_rep->len - 3 - sizeof(*basic)) != 0) {
2117 tprintf("Length of Req matchs not Type %u",
2118 meas_rep->type);
2119 return 0;
2122 tprintf("Ch Nr: %uus, ", basic->ch_nr);
2123 tprintf("Meas Start Time: %lu, ",
2124 le64_to_cpu(basic->start));
2125 tprintf("Meas Duration: %fs",
2126 le16_to_cpu(basic->dur) * TU);
2129 else if(meas_rep->type == 1) {
2130 struct element_meas_cca *cca;
2132 cca = (struct element_meas_cca *)
2133 pkt_pull(pkt, sizeof(*cca));
2134 if (cca == NULL)
2135 return 0;
2137 if ((meas_rep->len - 3 - sizeof(*cca)) != 0) {
2138 tprintf("Length of Req matchs not Type %u",
2139 meas_rep->type);
2140 return 0;
2143 tprintf("Ch Nr: %uus, ", cca->ch_nr);
2144 tprintf("Meas Start Time: %lu, ",
2145 le64_to_cpu(cca->start));
2146 tprintf("Meas Duration: %fs",
2147 le16_to_cpu(cca->dur) * TU);
2149 else if(meas_rep->type == 2) {
2150 struct element_meas_rpi *rpi;
2152 rpi = (struct element_meas_rpi *)
2153 pkt_pull(pkt, sizeof(*rpi));
2154 if (rpi == NULL)
2155 return 0;
2157 if ((meas_rep->len - 3 - sizeof(*rpi)) != 0) {
2158 tprintf("Length of Req matchs not Type %u",
2159 meas_rep->type);
2160 return 0;
2163 tprintf("Ch Nr: %uus, ", rpi->ch_nr);
2164 tprintf("Meas Start Time: %lu, ",
2165 le64_to_cpu(rpi->start));
2166 tprintf("Meas Duration: %fs",
2167 le16_to_cpu(rpi->dur) * TU);
2169 else if(meas_rep->type == 3) {
2170 struct element_meas_ch_load *ch_load;
2172 ch_load = (struct element_meas_ch_load *)
2173 pkt_pull(pkt, sizeof(*ch_load));
2174 if (ch_load == NULL)
2175 return 0;
2177 if ((ssize_t)(meas_rep->len - 3 - sizeof(*ch_load)) < 0) {
2178 tprintf("Length of Req matchs not Type %u",
2179 meas_rep->type);
2180 return 0;
2183 tprintf("OP Class: %u, ", ch_load->op_class);
2184 tprintf("Ch Nr: %u, ", ch_load->ch_nr);
2185 tprintf("Rand Intv: %fs, ",
2186 le16_to_cpu(ch_load->rand_intv) * TU);
2187 tprintf("Meas Duration: %fs",
2188 le16_to_cpu(ch_load->dur) * TU);
2190 if(!subelements(pkt,
2191 meas_rep->len - 3 - sizeof(*ch_load)))
2192 return 0;
2194 else if(meas_rep->type == 4) {
2195 struct element_meas_noise *noise;
2197 noise = (struct element_meas_noise *)
2198 pkt_pull(pkt, sizeof(*noise));
2199 if (noise == NULL)
2200 return 0;
2202 if ((ssize_t)(meas_rep->len - 3 - sizeof(*noise)) < 0) {
2203 tprintf("Length of Req matchs not Type %u",
2204 meas_rep->type);
2205 return 0;
2208 tprintf("OP Class: %u, ", noise->op_class);
2209 tprintf("Ch Nr: %u, ", noise->ch_nr);
2210 tprintf("Rand Intv: %fs, ",
2211 le16_to_cpu(noise->rand_intv) * TU);
2212 tprintf("Meas Duration: %fs",
2213 le16_to_cpu(noise->dur) * TU);
2215 if(!subelements(pkt,
2216 meas_rep->len - 3 - sizeof(*noise)))
2217 return 0;
2219 else if(meas_rep->type == 5) {
2220 struct element_meas_beacon *beacon;
2222 beacon = (struct element_meas_beacon *)
2223 pkt_pull(pkt, sizeof(*beacon));
2224 if (beacon == NULL)
2225 return 0;
2227 if ((ssize_t)(meas_rep->len - 3 - sizeof(*beacon)) < 0) {
2228 tprintf("Length of Req matchs not Type %u",
2229 meas_rep->type);
2230 return 0;
2233 tprintf("OP Class: %u, ", beacon->op_class);
2234 tprintf("Ch Nr: %u, ", beacon->ch_nr);
2235 tprintf("Rand Intv: %fs, ",
2236 le16_to_cpu(beacon->rand_intv) * TU);
2237 tprintf("Meas Duration: %fs",
2238 le16_to_cpu(beacon->dur) * TU);
2239 tprintf("Mode: %u, ", beacon->mode);
2240 tprintf("BSSID: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2241 beacon->bssid[0], beacon->bssid[1],
2242 beacon->bssid[2], beacon->bssid[3],
2243 beacon->bssid[4], beacon->bssid[5]);
2245 if(!subelements(pkt,
2246 meas_rep->len - 3 - sizeof(*beacon)))
2247 return 0;
2249 else if(meas_rep->type == 6) {
2250 struct element_meas_frame *frame;
2252 frame = (struct element_meas_frame *)
2253 pkt_pull(pkt, sizeof(*frame));
2254 if (frame == NULL)
2255 return 0;
2257 if ((ssize_t)(meas_rep->len - 3 - sizeof(*frame)) < 0) {
2258 tprintf("Length of Req matchs not Type %u",
2259 meas_rep->type);
2260 return 0;
2263 tprintf("OP Class: %u, ", frame->op_class);
2264 tprintf("Ch Nr: %u, ", frame->ch_nr);
2265 tprintf("Rand Intv: %fs, ",
2266 le16_to_cpu(frame->rand_intv) * TU);
2267 tprintf("Meas Duration: %fs",
2268 le16_to_cpu(frame->dur) * TU);
2269 tprintf("Request Type: %u, ", frame->frame);
2270 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2271 frame->mac[0], frame->mac[1],
2272 frame->mac[2], frame->mac[3],
2273 frame->mac[4], frame->mac[5]);
2275 if(!subelements(pkt,
2276 meas_rep->len - 3 - sizeof(*frame)))
2277 return 0;
2279 else if(meas_rep->type == 7) {
2280 struct element_meas_sta *sta;
2282 sta = (struct element_meas_sta *)
2283 pkt_pull(pkt, sizeof(*sta));
2284 if (sta == NULL)
2285 return 0;
2287 if ((ssize_t)(meas_rep->len - 3 - sizeof(*sta)) < 0) {
2288 tprintf("Length of Req matchs not Type %u",
2289 meas_rep->type);
2290 return 0;
2293 tprintf("Peer MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2294 sta->peer_mac[0], sta->peer_mac[1],
2295 sta->peer_mac[2], sta->peer_mac[3],
2296 sta->peer_mac[4], sta->peer_mac[5]);
2297 tprintf("Rand Intv: %fs, ",
2298 le16_to_cpu(sta->rand_intv) * TU);
2299 tprintf("Meas Duration: %fs",
2300 le16_to_cpu(sta->dur) * TU);
2301 tprintf("Group ID: %u, ", sta->group_id);
2303 if(!subelements(pkt,
2304 meas_rep->len - 3 - sizeof(*sta)))
2305 return 0;
2307 else if(meas_rep->type == 8) {
2308 struct element_meas_lci *lci;
2310 lci = (struct element_meas_lci *)
2311 pkt_pull(pkt, sizeof(*lci));
2312 if (lci == NULL)
2313 return 0;
2315 if ((ssize_t)(meas_rep->len - 3 - sizeof(*lci)) < 0) {
2316 tprintf("Length of Req matchs not Type %u",
2317 meas_rep->type);
2318 return 0;
2321 tprintf("Location Subj: %u, ", lci->loc_subj);
2322 tprintf("Latitude Req Res: %udeg",
2323 lci->latitude_req_res);
2324 tprintf("Longitude Req Res: %udeg",
2325 lci->longitude_req_res);
2326 tprintf("Altitude Req Res: %udeg",
2327 lci->altitude_req_res);
2329 if(!subelements(pkt,
2330 meas_rep->len - 3 - sizeof(*lci)))
2331 return 0;
2333 else if(meas_rep->type == 9) {
2334 struct element_meas_trans_str_cat *trans;
2336 trans = (struct element_meas_trans_str_cat *)
2337 pkt_pull(pkt, sizeof(*trans));
2338 if (trans == NULL)
2339 return 0;
2341 if ((ssize_t)(meas_rep->len - 3 - sizeof(*trans)) < 0) {
2342 tprintf("Length of Req matchs not Type %u",
2343 meas_rep->type);
2344 return 0;
2347 tprintf("Rand Intv: %fs, ",
2348 le16_to_cpu(trans->rand_intv) * TU);
2349 tprintf("Meas Duration: %fs",
2350 le16_to_cpu(trans->dur) * TU);
2351 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2352 trans->peer_sta_addr[0], trans->peer_sta_addr[1],
2353 trans->peer_sta_addr[2], trans->peer_sta_addr[3],
2354 trans->peer_sta_addr[4], trans->peer_sta_addr[5]);
2355 tprintf("Traffic ID: %u, ", trans->traffic_id);
2356 tprintf("Bin 0 Range: %u, ", trans->bin_0_range);
2358 if(!subelements(pkt,
2359 meas_rep->len - 3 - sizeof(*trans)))
2360 return 0;
2362 else if(meas_rep->type == 10) {
2363 struct element_meas_mcast_diag *mcast;
2365 mcast = (struct element_meas_mcast_diag *)
2366 pkt_pull(pkt, sizeof(*mcast));
2367 if (mcast == NULL)
2368 return 0;
2370 if ((ssize_t)(meas_rep->len - 3 - sizeof(*mcast)) < 0) {
2371 tprintf("Length of Req matchs not Type %u",
2372 meas_rep->type);
2373 return 0;
2376 tprintf("Rand Intv: %fs, ",
2377 le16_to_cpu(mcast->rand_intv) * TU);
2378 tprintf("Meas Duration: %fs",
2379 le16_to_cpu(mcast->dur) * TU);
2380 tprintf("Group MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2381 mcast->group_mac[0], mcast->group_mac[1],
2382 mcast->group_mac[2], mcast->group_mac[3],
2383 mcast->group_mac[4], mcast->group_mac[5]);
2385 if(!subelements(pkt,
2386 meas_rep->len - 3 - sizeof(*mcast)))
2387 return 0;
2389 else if(meas_rep->type == 11) {
2390 struct element_meas_loc_civic *civic;
2392 civic = (struct element_meas_loc_civic *)
2393 pkt_pull(pkt, sizeof(*civic));
2394 if (civic == NULL)
2395 return 0;
2397 if ((ssize_t)(meas_rep->len - 3 - sizeof(*civic)) < 0) {
2398 tprintf("Length of Req matchs not Type %u",
2399 meas_rep->type);
2400 return 0;
2403 tprintf("Location Subj: %u, ", civic->loc_subj);
2404 tprintf("Type: %u, ", civic->civic_loc);
2405 tprintf("Srv Intv Units: %u, ",
2406 le16_to_cpu(civic->loc_srv_intv_unit));
2407 tprintf("Srv Intv: %u, ", civic->loc_srv_intv);
2409 if(!subelements(pkt,
2410 meas_rep->len - 3 - sizeof(*civic)))
2411 return 0;
2413 else if(meas_rep->type == 12) {
2414 struct element_meas_loc_id *id;
2416 id = (struct element_meas_loc_id *)
2417 pkt_pull(pkt, sizeof(*id));
2418 if (id == NULL)
2419 return 0;
2421 if ((ssize_t)(meas_rep->len - 3 - sizeof(*id)) < 0) {
2422 tprintf("Length of Req matchs not Type %u",
2423 meas_rep->type);
2424 return 0;
2427 tprintf("Location Subj: %u, ", id->loc_subj);
2428 tprintf("Srv Intv Units: %u, ",
2429 le16_to_cpu(id->loc_srv_intv_unit));
2430 tprintf("Srv Intv: %u", id->loc_srv_intv);
2432 if(!subelements(pkt,
2433 meas_rep->len - 3 - sizeof(*id)))
2434 return 0;
2436 else {
2437 tprintf("Length field indicates data,"
2438 " but could not interpreted");
2439 return 0;
2443 return 1;
2446 static int8_t inf_quiet(struct pkt_buff *pkt, u8 *id)
2448 struct element_quiet *quiet;
2450 quiet = (struct element_quiet *) pkt_pull(pkt, sizeof(*quiet));
2451 if (quiet == NULL)
2452 return 0;
2454 tprintf(" Quit (%u, Len(%u)): ", *id, quiet->len);
2455 if (len_neq_error(quiet->len, 6))
2456 return 0;
2458 tprintf("Count: %ud, ", quiet->cnt);
2459 tprintf("Period: %u, ", quiet->period);
2460 tprintf("Duration: %fs, ", le16_to_cpu(quiet->dur) * TU);
2461 tprintf("Offs: %fs", le16_to_cpu(quiet->offs) * TU);
2464 return 1;
2467 static int8_t inf_ibss_dfs(struct pkt_buff *pkt, u8 *id)
2469 struct element_ibss_dfs *ibss_dfs;
2470 u8 i;
2472 ibss_dfs = (struct element_ibss_dfs *) pkt_pull(pkt, sizeof(*ibss_dfs));
2473 if (ibss_dfs == NULL)
2474 return 0;
2476 tprintf(" IBSS DFS (%u, Len(%u)): ", *id, ibss_dfs->len);
2477 if (len_lt_error(ibss_dfs->len, 7))
2478 return 0;
2480 tprintf("Owner: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2481 ibss_dfs->owner[0], ibss_dfs->owner[1],
2482 ibss_dfs->owner[2], ibss_dfs->owner[3],
2483 ibss_dfs->owner[4], ibss_dfs->owner[5]);
2484 tprintf("Recovery Intv: %u, ", ibss_dfs->rec_intv);
2486 if((ibss_dfs->len - sizeof(*ibss_dfs) + 1) & 1) {
2487 tprintf("Length of Channel Map should be modulo 2");
2488 return 0;
2491 for (i = 0; i < ibss_dfs->len; i += 2) {
2492 struct element_ibss_dfs_tuple *ibss_dfs_tuple;
2494 ibss_dfs_tuple = (struct element_ibss_dfs_tuple *)
2495 pkt_pull(pkt, sizeof(*ibss_dfs_tuple));
2496 if (ibss_dfs_tuple == NULL)
2497 return 0;
2499 tprintf("Channel Nr: %u, ", ibss_dfs_tuple->ch_nr);
2500 tprintf("Map: %u, ", ibss_dfs_tuple->map);
2503 return 1;
2506 static int8_t inf_erp(struct pkt_buff *pkt, u8 *id)
2508 struct element_erp *erp;
2510 erp = (struct element_erp *) pkt_pull(pkt, sizeof(*erp));
2511 if (erp == NULL)
2512 return 0;
2514 tprintf(" ERP (%u, Len(%u)): ", *id, erp->len);
2515 if (len_neq_error(erp->len, 1))
2516 return 0;
2517 tprintf("Non ERP Present (%u), ", erp->param & 0x1);
2518 tprintf("Use Protection (%u), ", (erp->param >> 1) & 0x1);
2519 tprintf("Barker Preamble Mode (%u), ", (erp->param >> 2) & 0x1);
2520 tprintf("Reserved (0x%.5x)", erp->param >> 3);
2522 return 1;
2525 static int8_t inf_ts_del(struct pkt_buff *pkt, u8 *id)
2527 struct element_ts_del *ts_del;
2529 ts_del = (struct element_ts_del *) pkt_pull(pkt, sizeof(*ts_del));
2530 if (ts_del == NULL)
2531 return 0;
2533 tprintf(" TS Delay (%u, Len(%u)): ", *id, ts_del->len);
2534 if (len_neq_error(ts_del->len, 4))
2535 return 0;
2536 tprintf("Delay (%fs)", le32_to_cpu(ts_del->delay) * TU);
2538 return 1;
2541 static int8_t inf_tclas_proc(struct pkt_buff *pkt, u8 *id)
2543 struct element_tclas_proc *tclas_proc;
2545 tclas_proc = (struct element_tclas_proc *)
2546 pkt_pull(pkt, sizeof(*tclas_proc));
2547 if (tclas_proc == NULL)
2548 return 0;
2550 tprintf(" TCLAS Procesing (%u, Len(%u)): ", *id, tclas_proc->len);
2551 if (len_neq_error(tclas_proc->len, 1))
2552 return 0;
2553 tprintf("Processing (%u)", tclas_proc->proc);
2555 return 1;
2558 static int8_t inf_ht_cap(struct pkt_buff *pkt, u8 *id)
2560 struct element_ht_cap *ht_cap;
2561 u32 tx_param_res, beam_cap;
2562 u16 ext_cap;
2564 ht_cap = (struct element_ht_cap *)
2565 pkt_pull(pkt, sizeof(*ht_cap));
2566 if (ht_cap == NULL)
2567 return 0;
2569 tx_param_res = le32_to_cpu(ht_cap->tx_param_res);
2570 beam_cap = le32_to_cpu(ht_cap->beam_cap);
2571 ext_cap = le16_to_cpu(ht_cap->ext_cap);
2573 tprintf(" HT Capabilities (%u, Len(%u)): ", *id, ht_cap->len);
2574 if (len_neq_error(ht_cap->len, 26))
2575 return 0;
2576 tprintf("Info (LDCP Cod Cap (%u), Supp Ch Width Set (%u),"
2577 " SM Pwr Save(%u), HT-Greenfield (%u), Short GI for 20/40 MHz"
2578 " (%u/%u), Tx/Rx STBC (%u/%u), HT-Delayed Block Ack (%u),"
2579 " Max A-MSDU Len (%u), DSSS/CCK Mode in 40 MHz (%u),"
2580 " Res (0x%x), Forty MHz Intol (%u), L-SIG TXOP Protection Supp"
2581 " (%u)), ", ht_cap->ldpc, ht_cap->supp_width,
2582 ht_cap->sm_pwr, ht_cap->ht_green, ht_cap->gi_20mhz,
2583 ht_cap->gi_40mhz, ht_cap->tx_stbc, ht_cap->rx_stbc,
2584 ht_cap->ht_ack, ht_cap->max_msdu_length, ht_cap->dsss_ck_mode,
2585 ht_cap->res, ht_cap->forty_int, ht_cap->prot_supp);
2586 tprintf("A-MPDU Params (Max Len Exp (%u), Min Start Spacing (%u),"
2587 " Res (0x%x)), ", ht_cap->param >> 6, (ht_cap->param >> 3) & 0x7,
2588 ht_cap->param & 0x07);
2589 tprintf("Supp MCS Set (Rx MCS Bitmask (0x%x%x%x%x%x%x%x%x%x%x),"
2590 " Res (0x%x), Rx High Supp Data Rate (%u), Res (0x%x),"
2591 " Tx MCS Set Def (%u), Tx Rx MCS Set Not Eq (%u),"
2592 " Tx Max Number Spat Str Supp (%u),"
2593 " Tx Uneq Mod Supp (%u), Res (0x%x)), ",
2594 ht_cap->bitmask1, ht_cap->bitmask2, ht_cap->bitmask3,
2595 ht_cap->bitmask4, ht_cap->bitmask5, ht_cap->bitmask6,
2596 ht_cap->bitmask7, ht_cap->bitmask8, ht_cap->bitmask9,
2597 ht_cap->bitmask10_res >> 3, ht_cap->bitmask10_res & 0x7,
2598 le16_to_cpu(ht_cap->supp_rate_res) >> 6,
2599 le16_to_cpu(ht_cap->supp_rate_res) & 0x3F,
2600 tx_param_res >> 31, (tx_param_res >> 30) & 1,
2601 (tx_param_res >> 28) & 3, (tx_param_res >> 27) & 1,
2602 tx_param_res & 0x7FFFFFF);
2603 tprintf("Ext Cap (PCO (%u), PCO Trans Time (%u), Res (0x%x),"
2604 " MCS Feedb (%u), +HTC Supp (%u), RD Resp (%u), Res (0x%x)), ",
2605 ext_cap >> 15, (ext_cap >> 13) & 3, (ext_cap >> 8) & 0x1F,
2606 (ext_cap >> 6) & 3, (ext_cap >> 5) & 1, (ext_cap >> 4) & 1,
2607 ext_cap & 0xF);
2608 tprintf("Transm Beamf (Impl Transm Beamf Rec Cap (%u),"
2609 " Rec/Transm Stagg Sound Cap (%u/%u),"
2610 " Rec/Trans NDP Cap (%u/%u), Impl Transm Beamf Cap (%u),"
2611 " Cal (%u), Expl CSI Transm Beamf Cap (%u),"
2612 " Expl Noncmpr/Compr Steering Cap (%u/%u),"
2613 " Expl Trans Beamf CSI Feedb (%u),"
2614 " Expl Noncmpr/Cmpr Feedb Cap (%u/%u),"
2615 " Min Grpg (%u), CSI Num Beamf Ant Supp (%u),"
2616 " Noncmpr/Cmpr Steering Nr Beamf Ant Supp (%u/%u),"
2617 " CSI Max Nr Rows Beamf Supp (%u),"
2618 " Ch Estim Cap (%u), Res (0x%x)), ",
2619 beam_cap >> 31, (beam_cap >> 30) & 1, (beam_cap >> 29) & 1,
2620 (beam_cap >> 28) & 1, (beam_cap >> 27) & 1, (beam_cap >> 26) & 1,
2621 (beam_cap >> 24) & 3, (beam_cap >> 23) & 1, (beam_cap >> 22) & 1,
2622 (beam_cap >> 21) & 1, (beam_cap >> 19) & 3, (beam_cap >> 17) & 3,
2623 (beam_cap >> 15) & 3, (beam_cap >> 13) & 3, (beam_cap >> 11) & 3,
2624 (beam_cap >> 9) & 3, (beam_cap >> 7) & 3, (beam_cap >> 5) & 3,
2625 (beam_cap >> 3) & 3, beam_cap & 7);
2626 tprintf("ASEL (Ant Select Cap (%u),"
2627 " Expl CSI Feedb Based Transm ASEL Cap (%u),"
2628 " Ant Indic Feedb Based Transm ASEL Cap (%u),"
2629 " Expl CSI Feedb Cap (%u), Ant Indic Feedb Cap (%u),"
2630 " Rec ASEL Cap (%u), Transm Sound PPDUs Cap (%u), Res (0x%x))",
2631 ht_cap->asel_cap >> 7, (ht_cap->asel_cap >> 6) & 1,
2632 (ht_cap->asel_cap >> 5) & 1, (ht_cap->asel_cap >> 4) & 1,
2633 (ht_cap->asel_cap >> 3) & 1, (ht_cap->asel_cap >> 2) & 1,
2634 (ht_cap->asel_cap >> 1) & 1, ht_cap->asel_cap & 1);
2636 return 1;
2639 static int8_t inf_qos_cap(struct pkt_buff *pkt, u8 *id)
2641 struct element_qos_cap *qos_cap;
2643 qos_cap = (struct element_qos_cap *)
2644 pkt_pull(pkt, sizeof(*qos_cap));
2645 if (qos_cap == NULL)
2646 return 0;
2648 tprintf(" QoS Capabilities (%u, Len(%u)): ", *id, qos_cap->len);
2649 if (len_neq_error(qos_cap->len, 1))
2650 return 0;
2652 tprintf("Info (0x%x)", qos_cap->info);
2654 return 1;
2657 static int8_t inf_rsn(struct pkt_buff *pkt, u8 *id)
2659 return 0;
2662 static int8_t inf_ext_supp_rates(struct pkt_buff *pkt, u8 *id)
2664 u8 i;
2665 u8 *rates;
2666 struct element_ext_supp_rates *ext_supp_rates;
2668 ext_supp_rates = (struct element_ext_supp_rates *)
2669 pkt_pull(pkt, sizeof(*ext_supp_rates));
2670 if (ext_supp_rates == NULL)
2671 return 0;
2673 tprintf(" Ext Support Rates (%u, Len(%u)): ", *id, ext_supp_rates->len);
2675 if ((ext_supp_rates->len - sizeof(*ext_supp_rates) + 1) > 0) {
2676 rates = pkt_pull(pkt, ext_supp_rates->len);
2677 if (rates == NULL)
2678 return 0;
2680 for (i = 0; i < ext_supp_rates->len; i++)
2681 tprintf("%g ", (rates[i] & 0x80) ?
2682 ((rates[i] & 0x3f) * 0.5) :
2683 data_rates(rates[i]));
2684 return 1;
2687 return 0;
2690 static int8_t inf_ap_ch_exp(struct pkt_buff *pkt, u8 *id) {
2691 return 0;
2694 static int8_t inf_neighb_rep(struct pkt_buff *pkt, u8 *id) {
2695 return 0;
2698 static int8_t inf_rcpi(struct pkt_buff *pkt, u8 *id) {
2699 return 0;
2702 static int8_t inf_mde(struct pkt_buff *pkt, u8 *id) {
2703 return 0;
2706 static int8_t inf_fte(struct pkt_buff *pkt, u8 *id) {
2707 return 0;
2710 static int8_t inf_time_out_int(struct pkt_buff *pkt, u8 *id) {
2711 return 0;
2714 static int8_t inf_rde(struct pkt_buff *pkt, u8 *id) {
2715 return 0;
2718 static int8_t inf_dse_reg_loc(struct pkt_buff *pkt, u8 *id) {
2719 return 0;
2722 static int8_t inf_supp_op_class(struct pkt_buff *pkt, u8 *id) {
2723 return 0;
2726 static int8_t inf_ext_ch_sw_ann(struct pkt_buff *pkt, u8 *id) {
2727 return 0;
2730 static int8_t inf_ht_op(struct pkt_buff *pkt, u8 *id) {
2731 return 0;
2734 static int8_t inf_sec_ch_offs(struct pkt_buff *pkt, u8 *id) {
2735 return 0;
2738 static int8_t inf_bss_avg_acc_del(struct pkt_buff *pkt, u8 *id) {
2739 return 0;
2742 static int8_t inf_ant(struct pkt_buff *pkt, u8 *id) {
2743 return 0;
2746 static int8_t inf_rsni(struct pkt_buff *pkt, u8 *id) {
2747 return 0;
2750 static int8_t inf_meas_pilot_trans(struct pkt_buff *pkt, u8 *id) {
2751 return 0;
2754 static int8_t inf_bss_avl_adm_cap(struct pkt_buff *pkt, u8 *id) {
2755 return 0;
2758 static int8_t inf_bss_ac_acc_del(struct pkt_buff *pkt, u8 *id) {
2759 return 0;
2762 static int8_t inf_time_adv(struct pkt_buff *pkt, u8 *id) {
2763 return 0;
2766 static int8_t inf_rm_ena_cap(struct pkt_buff *pkt, u8 *id) {
2767 return 0;
2770 static int8_t inf_mult_bssid(struct pkt_buff *pkt, u8 *id) {
2771 return 0;
2774 static int8_t inf_20_40_bss_coex(struct pkt_buff *pkt, u8 *id) {
2775 return 0;
2778 static int8_t inf_20_40_bss_int_ch_rep(struct pkt_buff *pkt, u8 *id) {
2779 return 0;
2782 static int8_t inf_overl_bss_scan_para(struct pkt_buff *pkt, u8 *id) {
2783 return 0;
2786 static int8_t inf_ric_desc(struct pkt_buff *pkt, u8 *id) {
2787 return 0;
2790 static int8_t inf_mgmt_mic(struct pkt_buff *pkt, u8 *id) {
2791 return 0;
2794 static int8_t inf_ev_req(struct pkt_buff *pkt, u8 *id) {
2795 return 0;
2798 static int8_t inf_ev_rep(struct pkt_buff *pkt, u8 *id) {
2799 return 0;
2802 static int8_t inf_diagn_req(struct pkt_buff *pkt, u8 *id) {
2803 return 0;
2806 static int8_t inf_diagn_rep(struct pkt_buff *pkt, u8 *id) {
2807 return 0;
2810 static int8_t inf_loc_para(struct pkt_buff *pkt, u8 *id) {
2811 return 0;
2814 static int8_t inf_nontr_bssid_cap(struct pkt_buff *pkt, u8 *id) {
2815 return 0;
2818 static int8_t inf_ssid_list(struct pkt_buff *pkt, u8 *id) {
2819 return 0;
2822 static int8_t inf_mult_bssid_index(struct pkt_buff *pkt, u8 *id) {
2823 return 0;
2826 static int8_t inf_fms_desc(struct pkt_buff *pkt, u8 *id) {
2827 return 0;
2830 static int8_t inf_fms_req(struct pkt_buff *pkt, u8 *id) {
2831 return 0;
2834 static int8_t inf_fms_resp(struct pkt_buff *pkt, u8 *id) {
2835 return 0;
2838 static int8_t inf_qos_tfc_cap(struct pkt_buff *pkt, u8 *id) {
2839 return 0;
2842 static int8_t inf_bss_max_idle_per(struct pkt_buff *pkt, u8 *id) {
2843 return 0;
2846 static int8_t inf_tfs_req(struct pkt_buff *pkt, u8 *id) {
2847 return 0;
2850 static int8_t inf_tfs_resp(struct pkt_buff *pkt, u8 *id) {
2851 return 0;
2854 static int8_t inf_wnm_sleep_mod(struct pkt_buff *pkt, u8 *id) {
2855 return 0;
2858 static int8_t inf_tim_bcst_req(struct pkt_buff *pkt, u8 *id) {
2859 return 0;
2862 static int8_t inf_tim_bcst_resp(struct pkt_buff *pkt, u8 *id) {
2863 return 0;
2866 static int8_t inf_coll_interf_rep(struct pkt_buff *pkt, u8 *id) {
2867 return 0;
2870 static int8_t inf_ch_usage(struct pkt_buff *pkt, u8 *id) {
2871 return 0;
2874 static int8_t inf_time_zone(struct pkt_buff *pkt, u8 *id) {
2875 return 0;
2878 static int8_t inf_dms_req(struct pkt_buff *pkt, u8 *id) {
2879 return 0;
2882 static int8_t inf_dms_resp(struct pkt_buff *pkt, u8 *id) {
2883 return 0;
2886 static int8_t inf_link_id(struct pkt_buff *pkt, u8 *id) {
2887 return 0;
2890 static int8_t inf_wakeup_sched(struct pkt_buff *pkt, u8 *id) {
2891 return 0;
2894 static int8_t inf_ch_sw_timing(struct pkt_buff *pkt, u8 *id) {
2895 return 0;
2898 static int8_t inf_pti_ctrl(struct pkt_buff *pkt, u8 *id) {
2899 return 0;
2902 static int8_t inf_tpu_buff_status(struct pkt_buff *pkt, u8 *id) {
2903 return 0;
2906 static int8_t inf_interw(struct pkt_buff *pkt, u8 *id) {
2907 return 0;
2910 static int8_t inf_adv_proto(struct pkt_buff *pkt, u8 *id) {
2911 return 0;
2914 static int8_t inf_exp_bandw_req(struct pkt_buff *pkt, u8 *id) {
2915 return 0;
2918 static int8_t inf_qos_map_set(struct pkt_buff *pkt, u8 *id) {
2919 return 0;
2922 static int8_t inf_roam_cons(struct pkt_buff *pkt, u8 *id) {
2923 return 0;
2926 static int8_t inf_emer_alert_id(struct pkt_buff *pkt, u8 *id) {
2927 return 0;
2930 static int8_t inf_mesh_conf(struct pkt_buff *pkt, u8 *id) {
2931 return 0;
2934 static int8_t inf_mesh_id(struct pkt_buff *pkt, u8 *id) {
2935 return 0;
2938 static int8_t inf_mesh_link_metr_rep(struct pkt_buff *pkt, u8 *id) {
2939 return 0;
2942 static int8_t inf_cong_notif(struct pkt_buff *pkt, u8 *id) {
2943 return 0;
2946 static int8_t inf_mesh_peer_mgmt(struct pkt_buff *pkt, u8 *id) {
2947 return 0;
2950 static int8_t inf_mesh_ch_sw_para(struct pkt_buff *pkt, u8 *id) {
2951 return 0;
2954 static int8_t inf_mesh_awake_win(struct pkt_buff *pkt, u8 *id) {
2955 return 0;
2958 static int8_t inf_beacon_timing(struct pkt_buff *pkt, u8 *id) {
2959 return 0;
2962 static int8_t inf_mccaop_setup_req(struct pkt_buff *pkt, u8 *id) {
2963 return 0;
2966 static int8_t inf_mccaop_setup_rep(struct pkt_buff *pkt, u8 *id) {
2967 return 0;
2970 static int8_t inf_mccaop_adv(struct pkt_buff *pkt, u8 *id) {
2971 return 0;
2974 static int8_t inf_mccaop_teardwn(struct pkt_buff *pkt, u8 *id) {
2975 return 0;
2978 static int8_t inf_gann(struct pkt_buff *pkt, u8 *id) {
2979 return 0;
2982 static int8_t inf_rann(struct pkt_buff *pkt, u8 *id) {
2983 return 0;
2986 static int8_t inf_ext_cap(struct pkt_buff *pkt, u8 *id) {
2987 return 0;
2990 static int8_t inf_preq(struct pkt_buff *pkt, u8 *id) {
2991 return 0;
2994 static int8_t inf_prep(struct pkt_buff *pkt, u8 *id) {
2995 return 0;
2998 static int8_t inf_perr(struct pkt_buff *pkt, u8 *id) {
2999 return 0;
3002 static int8_t inf_pxu(struct pkt_buff *pkt, u8 *id) {
3003 return 0;
3006 static int8_t inf_pxuc(struct pkt_buff *pkt, u8 *id) {
3007 return 0;
3010 static int8_t inf_auth_mesh_peer_exch(struct pkt_buff *pkt, u8 *id) {
3011 return 0;
3014 static int8_t inf_mic(struct pkt_buff *pkt, u8 *id) {
3015 return 0;
3018 static int8_t inf_dest_uri(struct pkt_buff *pkt, u8 *id) {
3019 return 0;
3022 static int8_t inf_u_apsd_coex(struct pkt_buff *pkt, u8 *id) {
3023 return 0;
3026 static int8_t inf_mccaop_adv_overv(struct pkt_buff *pkt, u8 *id) {
3027 return 0;
3030 static int8_t inf_vend_spec(struct pkt_buff *pkt, u8 *id)
3032 u8 i;
3033 u8 *data;
3034 struct element_vend_spec *vend_spec;
3036 vend_spec = (struct element_vend_spec *)
3037 pkt_pull(pkt, sizeof(*vend_spec));
3038 if (vend_spec == NULL)
3039 return 0;
3041 tprintf(" Vendor Specific (%u, Len (%u)): ", *id, vend_spec->len);
3043 data = pkt_pull(pkt, vend_spec->len);
3044 if (data == NULL)
3045 return 0;
3047 tprintf("Data 0x");
3048 for (i = 0; i < vend_spec->len; i++)
3049 tprintf("%.2x", data[i]);
3051 return 1;
3054 static int8_t inf_elements(struct pkt_buff *pkt)
3056 u8 *id = pkt_pull(pkt, 1);
3057 if (id == NULL)
3058 return 0;
3060 switch (*id) {
3061 case 0: return inf_ssid(pkt, id);
3062 case 1: return inf_supp_rates(pkt, id);
3063 case 2: return inf_fh_ps(pkt, id);
3064 case 3: return inf_dsss_ps(pkt, id);
3065 case 4: return inf_cf_ps(pkt, id);
3066 case 5: return inf_tim(pkt, id);
3067 case 6: return inf_ibss_ps(pkt, id);
3068 case 7: return inf_country(pkt, id);
3069 case 8: return inf_hop_pp(pkt, id);
3070 case 9: return inf_hop_pt(pkt, id);
3071 case 10: return inf_req(pkt, id);
3072 case 11: return inf_bss_load(pkt, id);
3073 case 12: return inf_edca_ps(pkt, id);
3074 case 13: return inf_tspec(pkt, id);
3075 case 14: return inf_tclas(pkt, id);
3076 case 15: return inf_sched(pkt, id);
3077 case 16: return inf_chall_txt(pkt, id);
3078 case 17 ... 31: return inf_reserved(pkt, id);
3079 case 32: return inf_pwr_constr(pkt, id);
3080 case 33: return inf_pwr_cap(pkt, id);
3081 case 34: return inf_tpc_req(pkt, id);
3082 case 35: return inf_tpc_rep(pkt, id);
3083 case 36: return inf_supp_ch(pkt, id);
3084 case 37: return inf_ch_sw_ann(pkt, id);
3085 case 38: return inf_meas_req(pkt, id);
3086 case 39: return inf_meas_rep(pkt, id);
3087 case 40: return inf_quiet(pkt, id);
3088 case 41: return inf_ibss_dfs(pkt, id);
3089 case 42: return inf_erp(pkt, id);
3090 case 43: return inf_ts_del(pkt, id);
3091 case 44: return inf_tclas_proc(pkt, id);
3092 case 45: return inf_ht_cap(pkt, id);
3093 case 46: return inf_qos_cap(pkt, id);
3094 case 47: return inf_reserved(pkt, id);
3095 case 48: return inf_rsn(pkt, id);
3096 case 49: return inf_rsn(pkt, id);
3097 case 50: return inf_ext_supp_rates(pkt, id);
3098 case 51: return inf_ap_ch_exp(pkt, id);
3099 case 52: return inf_neighb_rep(pkt, id);
3100 case 53: return inf_rcpi(pkt, id);
3101 case 54: return inf_mde(pkt, id);
3102 case 55: return inf_fte(pkt, id);
3103 case 56: return inf_time_out_int(pkt, id);
3104 case 57: return inf_rde(pkt, id);
3105 case 58: return inf_dse_reg_loc(pkt, id);
3106 case 59: return inf_supp_op_class(pkt, id);
3107 case 60: return inf_ext_ch_sw_ann(pkt, id);
3108 case 61: return inf_ht_op(pkt, id);
3109 case 62: return inf_sec_ch_offs(pkt, id);
3110 case 63: return inf_bss_avg_acc_del(pkt, id);
3111 case 64: return inf_ant(pkt, id);
3112 case 65: return inf_rsni(pkt, id);
3113 case 66: return inf_meas_pilot_trans(pkt, id);
3114 case 67: return inf_bss_avl_adm_cap(pkt, id);
3115 case 68: return inf_bss_ac_acc_del(pkt, id);
3116 case 69: return inf_time_adv(pkt, id);
3117 case 70: return inf_rm_ena_cap(pkt, id);
3118 case 71: return inf_mult_bssid(pkt, id);
3119 case 72: return inf_20_40_bss_coex(pkt, id);
3120 case 73: return inf_20_40_bss_int_ch_rep(pkt, id);
3121 case 74: return inf_overl_bss_scan_para(pkt, id);
3122 case 75: return inf_ric_desc(pkt, id);
3123 case 76: return inf_mgmt_mic(pkt, id);
3124 case 78: return inf_ev_req(pkt, id);
3125 case 79: return inf_ev_rep(pkt, id);
3126 case 80: return inf_diagn_req(pkt, id);
3127 case 81: return inf_diagn_rep(pkt, id);
3128 case 82: return inf_loc_para(pkt, id);
3129 case 83: return inf_nontr_bssid_cap(pkt, id);
3130 case 84: return inf_ssid_list(pkt, id);
3131 case 85: return inf_mult_bssid_index(pkt, id);
3132 case 86: return inf_fms_desc(pkt, id);
3133 case 87: return inf_fms_req(pkt, id);
3134 case 88: return inf_fms_resp(pkt, id);
3135 case 89: return inf_qos_tfc_cap(pkt, id);
3136 case 90: return inf_bss_max_idle_per(pkt, id);
3137 case 91: return inf_tfs_req(pkt, id);
3138 case 92: return inf_tfs_resp(pkt, id);
3139 case 93: return inf_wnm_sleep_mod(pkt, id);
3140 case 94: return inf_tim_bcst_req(pkt, id);
3141 case 95: return inf_tim_bcst_resp(pkt, id);
3142 case 96: return inf_coll_interf_rep(pkt, id);
3143 case 97: return inf_ch_usage(pkt, id);
3144 case 98: return inf_time_zone(pkt, id);
3145 case 99: return inf_dms_req(pkt, id);
3146 case 100: return inf_dms_resp(pkt, id);
3147 case 101: return inf_link_id(pkt, id);
3148 case 102: return inf_wakeup_sched(pkt, id);
3149 case 104: return inf_ch_sw_timing(pkt, id);
3150 case 105: return inf_pti_ctrl(pkt, id);
3151 case 106: return inf_tpu_buff_status(pkt, id);
3152 case 107: return inf_interw(pkt, id);
3153 case 108: return inf_adv_proto(pkt, id);
3154 case 109: return inf_exp_bandw_req(pkt, id);
3155 case 110: return inf_qos_map_set(pkt, id);
3156 case 111: return inf_roam_cons(pkt, id);
3157 case 112: return inf_emer_alert_id(pkt, id);
3158 case 113: return inf_mesh_conf(pkt, id);
3159 case 114: return inf_mesh_id(pkt, id);
3160 case 115: return inf_mesh_link_metr_rep(pkt, id);
3161 case 116: return inf_cong_notif(pkt, id);
3162 case 117: return inf_mesh_peer_mgmt(pkt, id);
3163 case 118: return inf_mesh_ch_sw_para(pkt, id);
3164 case 119: return inf_mesh_awake_win(pkt, id);
3165 case 120: return inf_beacon_timing(pkt, id);
3166 case 121: return inf_mccaop_setup_req(pkt, id);
3167 case 122: return inf_mccaop_setup_rep(pkt, id);
3168 case 123: return inf_mccaop_adv(pkt, id);
3169 case 124: return inf_mccaop_teardwn(pkt, id);
3170 case 125: return inf_gann(pkt, id);
3171 case 126: return inf_rann(pkt, id);
3172 case 127: return inf_ext_cap(pkt, id);
3173 case 128: return inf_reserved(pkt, id);
3174 case 129: return inf_reserved(pkt, id);
3175 case 130: return inf_preq(pkt, id);
3176 case 131: return inf_prep(pkt, id);
3177 case 132: return inf_perr(pkt, id);
3178 case 133: return inf_reserved(pkt, id);
3179 case 134: return inf_reserved(pkt, id);
3180 case 135: return inf_reserved(pkt, id);
3181 case 136: return inf_reserved(pkt, id);
3182 case 137: return inf_pxu(pkt, id);
3183 case 138: return inf_pxuc(pkt, id);
3184 case 139: return inf_auth_mesh_peer_exch(pkt, id);
3185 case 140: return inf_mic(pkt, id);
3186 case 141: return inf_dest_uri(pkt, id);
3187 case 142: return inf_u_apsd_coex(pkt, id);
3188 case 143 ... 173: return inf_reserved(pkt, id);
3189 case 174: return inf_mccaop_adv_overv(pkt, id);
3190 case 221: return inf_vend_spec(pkt, id);
3193 return 0;
3196 #define ESS 0b0000000000000001
3197 #define IBSS 0b0000000000000010
3198 #define CF_Pollable 0b0000000000000100
3199 #define CF_Poll_Req 0b0000000000001000
3200 #define Privacy 0b0000000000010000
3201 #define Short_Pre 0b0000000000100000
3202 #define PBCC 0b0000000001000000
3203 #define Ch_Agility 0b0000000010000000
3204 #define Spec_Mgmt 0b0000000100000000
3205 #define QoS 0b0000001000000000
3206 #define Short_Slot_t 0b0000010000000000
3207 #define APSD 0b0000100000000000
3208 #define Radio_Meas 0b0001000000000000
3209 #define DSSS_OFDM 0b0010000000000000
3210 #define Del_Block_ACK 0b0100000000000000
3211 #define Imm_Block_ACK 0b1000000000000000
3213 static int8_t cap_field(u16 cap_inf)
3215 if (ESS & cap_inf)
3216 tprintf(" ESS;");
3217 if (IBSS & cap_inf)
3218 tprintf(" IBSS;");
3219 if (CF_Pollable & cap_inf)
3220 tprintf(" CF Pollable;");
3221 if (CF_Poll_Req & cap_inf)
3222 tprintf(" CF-Poll Request;");
3223 if (Privacy & cap_inf)
3224 tprintf(" Privacy;");
3225 if (Short_Pre & cap_inf)
3226 tprintf(" Short Preamble;");
3227 if (PBCC & cap_inf)
3228 tprintf(" PBCC;");
3229 if (Ch_Agility & cap_inf)
3230 tprintf(" Channel Agility;");
3231 if (Spec_Mgmt & cap_inf)
3232 tprintf(" Spectrum Management;");
3233 if (QoS & cap_inf)
3234 tprintf(" QoS;");
3235 if (Short_Slot_t & cap_inf)
3236 tprintf(" Short Slot Time;");
3237 if (APSD & cap_inf)
3238 tprintf(" APSD;");
3239 if (Radio_Meas & cap_inf)
3240 tprintf(" Radio Measurement;");
3241 if (DSSS_OFDM & cap_inf)
3242 tprintf(" DSSS-OFDM;");
3243 if (Del_Block_ACK & cap_inf)
3244 tprintf(" Delayed Block Ack;");
3245 if (Imm_Block_ACK & cap_inf)
3246 tprintf(" Immediate Block Ack;");
3248 return 1;
3251 /* Management Dissectors */
3252 static int8_t assoc_req(struct pkt_buff *pkt) {
3253 return 0;
3256 static int8_t assoc_resp(struct pkt_buff *pkt) {
3257 return 0;
3260 static int8_t reassoc_req(struct pkt_buff *pkt) {
3261 return 0;
3264 static int8_t reassoc_resp(struct pkt_buff *pkt) {
3265 return 0;
3268 static int8_t probe_req(struct pkt_buff *pkt) {
3269 return 0;
3272 static int8_t probe_resp(struct pkt_buff *pkt) {
3273 return 0;
3276 static int8_t beacon(struct pkt_buff *pkt)
3278 struct ieee80211_mgmt_beacon *beacon;
3280 beacon = (struct ieee80211_mgmt_beacon *)
3281 pkt_pull(pkt, sizeof(*beacon));
3282 if (beacon == NULL)
3283 return 0;
3285 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon->timestamp));
3286 tprintf("Beacon Interval (%fs), ", le16_to_cpu(beacon->beacon_int)*TU);
3287 tprintf("Capabilities (0x%x <->", le16_to_cpu(beacon->capab_info));
3288 cap_field(le16_to_cpu(beacon->capab_info));
3289 tprintf(")");
3291 if(pkt_len(pkt)) {
3292 tprintf("\n\tParameters:");
3293 while (inf_elements(pkt)) {
3294 tprintf("\n\t");
3298 if(pkt_len(pkt))
3299 return 0;
3300 return 1;
3303 static int8_t atim(struct pkt_buff *pkt) {
3304 return 0;
3307 static int8_t disassoc(struct pkt_buff *pkt) {
3308 return 0;
3311 static int8_t auth(struct pkt_buff *pkt) {
3312 return 0;
3315 static int8_t deauth(struct pkt_buff *pkt) {
3316 return 0;
3318 /* End Management Dissectors */
3320 /* Control Dissectors */
3321 static int8_t ps_poll(struct pkt_buff *pkt) {
3322 return 0;
3325 static int8_t rts(struct pkt_buff *pkt) {
3326 return 0;
3329 static int8_t cts(struct pkt_buff *pkt) {
3330 return 0;
3333 static int8_t ack(struct pkt_buff *pkt) {
3334 return 0;
3337 static int8_t cf_end(struct pkt_buff *pkt) {
3338 return 0;
3341 static int8_t cf_end_ack(struct pkt_buff *pkt) {
3342 return 0;
3344 /* End Control Dissectors */
3346 /* Data Dissectors */
3347 static int8_t data(struct pkt_buff *pkt) {
3348 return 0;
3351 static int8_t data_cf_ack(struct pkt_buff *pkt) {
3352 return 0;
3355 static int8_t data_cf_poll(struct pkt_buff *pkt) {
3356 return 0;
3359 static int8_t data_cf_ack_poll(struct pkt_buff *pkt) {
3360 return 0;
3363 static int8_t null(struct pkt_buff *pkt) {
3364 return 0;
3367 static int8_t cf_ack(struct pkt_buff *pkt) {
3368 return 0;
3371 static int8_t cf_poll(struct pkt_buff *pkt) {
3372 return 0;
3375 static int8_t cf_ack_poll(struct pkt_buff *pkt) {
3376 return 0;
3378 /* End Data Dissectors */
3380 static const char *mgt_sub(u8 subtype, struct pkt_buff *pkt,
3381 int8_t (**get_content)(struct pkt_buff *pkt))
3383 u16 seq_ctrl;
3384 struct ieee80211_mgmt *mgmt;
3385 const char *dst, *src, *bssid;
3387 mgmt = (struct ieee80211_mgmt *) pkt_pull(pkt, sizeof(*mgmt));
3388 if (mgmt == NULL)
3389 return 0;
3391 dst = lookup_vendor((mgmt->da[0] << 16) |
3392 (mgmt->da[1] << 8) |
3393 mgmt->da[2]);
3394 src = lookup_vendor((mgmt->sa[0] << 16) |
3395 (mgmt->sa[1] << 8) |
3396 mgmt->sa[2]);
3398 bssid = lookup_vendor((mgmt->bssid[0] << 16) |
3399 (mgmt->bssid[1] << 8) |
3400 mgmt->bssid[2]);
3401 seq_ctrl = le16_to_cpu(mgmt->seq_ctrl);
3403 tprintf("Duration (%u),", le16_to_cpu(mgmt->duration));
3404 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3405 mgmt->da[0], mgmt->da[1], mgmt->da[2],
3406 mgmt->da[3], mgmt->da[4], mgmt->da[5]);
3407 if (dst) {
3408 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst,
3409 mgmt->da[3], mgmt->da[4], mgmt->da[5]);
3412 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3413 mgmt->sa[0], mgmt->sa[1], mgmt->sa[2],
3414 mgmt->sa[3], mgmt->sa[4], mgmt->sa[5]);
3415 if (src) {
3416 tprintf("=> (%s:%.2x:%.2x:%.2x)", src,
3417 mgmt->sa[3], mgmt->sa[4], mgmt->sa[5]);
3420 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3421 mgmt->bssid[0], mgmt->bssid[1], mgmt->bssid[2],
3422 mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5]);
3423 if(bssid) {
3424 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid,
3425 mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5]);
3428 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ",
3429 seq_ctrl & 0xf, seq_ctrl >> 4);
3431 switch (subtype) {
3432 case 0b0000:
3433 *get_content = assoc_req;
3434 return "Association Request";
3435 case 0b0001:
3436 *get_content = assoc_resp;
3437 return "Association Response";
3438 case 0b0010:
3439 *get_content = reassoc_req;
3440 return "Reassociation Request";
3441 case 0b0011:
3442 *get_content = reassoc_resp;
3443 return "Reassociation Response";
3444 case 0b0100:
3445 *get_content = probe_req;
3446 return "Probe Request";
3447 case 0b0101:
3448 *get_content = probe_resp;
3449 return "Probe Response";
3450 case 0b1000:
3451 *get_content = beacon;
3452 return "Beacon";
3453 case 0b1001:
3454 *get_content = atim;
3455 return "ATIM";
3456 case 0b1010:
3457 *get_content = disassoc;
3458 return "Disassociation";
3459 case 0b1011:
3460 *get_content = auth;
3461 return "Authentication";
3462 case 0b1100:
3463 *get_content = deauth;
3464 return "Deauthentication";
3465 case 0b0110 ... 0b0111:
3466 case 0b1101 ... 0b1111:
3467 *get_content = NULL;
3468 return "Reserved";
3469 default:
3470 *get_content = NULL;
3471 return "Management SubType unknown";
3475 static const char *ctrl_sub(u8 subtype, struct pkt_buff *pkt,
3476 int8_t (**get_content)(struct pkt_buff *pkt))
3478 switch (subtype) {
3479 case 0b1010:
3480 *get_content = ps_poll;
3481 return "PS-Poll";
3482 case 0b1011:
3483 *get_content = rts;
3484 return "RTS";
3485 case 0b1100:
3486 *get_content = cts;
3487 return "CTS";
3488 case 0b1101:
3489 *get_content = ack;
3490 return "ACK";
3491 case 0b1110:
3492 *get_content = cf_end;
3493 return "CF End";
3494 case 0b1111:
3495 *get_content = cf_end_ack;
3496 return "CF End + CF-ACK";
3497 case 0b0000 ... 0b1001:
3498 *get_content = NULL;
3499 return "Reserved";
3500 default:
3501 return "Control SubType unkown";
3505 static const char *data_sub(u8 subtype, struct pkt_buff *pkt,
3506 int8_t (**get_content)(struct pkt_buff *pkt))
3508 switch (subtype) {
3509 case 0b0000:
3510 *get_content = data;
3511 return "Data";
3512 case 0b0001:
3513 *get_content = data_cf_ack;
3514 return "Data + CF-ACK";
3515 case 0b0010:
3516 *get_content = data_cf_poll;
3517 return "Data + CF-Poll";
3518 case 0b0011:
3519 *get_content = data_cf_ack_poll;
3520 return "Data + CF-ACK + CF-Poll";
3521 case 0b0100:
3522 *get_content = null;
3523 return "Null";
3524 case 0b0101:
3525 *get_content = cf_ack;
3526 return "CF-ACK";
3527 case 0b0110:
3528 *get_content = cf_poll;
3529 return "CF-Poll";
3530 case 0b0111:
3531 *get_content = cf_ack_poll;
3532 return "CF-ACK + CF-Poll";
3533 case 0b1000 ... 0b1111:
3534 *get_content = NULL;
3535 return "Reserved";
3536 default:
3537 *get_content = NULL;
3538 return "Data SubType unkown";
3542 static const char *
3543 frame_control_type(u8 type, const char *(**get_subtype)(u8 subtype,
3544 struct pkt_buff *pkt, int8_t (**get_content)(struct pkt_buff *pkt)))
3546 switch (type) {
3547 case 0b00:
3548 *get_subtype = mgt_sub;
3549 return "Management";
3550 case 0b01:
3551 *get_subtype = ctrl_sub;
3552 return "Control";
3553 case 0b10:
3554 *get_subtype = data_sub;
3555 return "Data";
3556 case 0b11:
3557 *get_subtype = NULL;
3558 return "Reserved";
3559 default:
3560 *get_subtype = NULL;
3561 return "Control Type unkown";
3565 static void ieee80211(struct pkt_buff *pkt)
3567 int8_t (*get_content)(struct pkt_buff *pkt) = NULL;
3568 const char *(*get_subtype)(u8 subtype, struct pkt_buff *pkt,
3569 int8_t (**get_content)(struct pkt_buff *pkt)) = NULL;
3570 const char *subtype = NULL;
3571 struct ieee80211_frm_ctrl *frm_ctrl;
3573 frm_ctrl = (struct ieee80211_frm_ctrl *)
3574 pkt_pull(pkt, sizeof(*frm_ctrl));
3575 if (frm_ctrl == NULL)
3576 return;
3578 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
3579 le16_to_cpu(frm_ctrl->frame_control));
3581 tprintf(" [ Proto Version (%u), ", frm_ctrl->proto_version);
3582 tprintf("Type (%u, %s), ", frm_ctrl->type,
3583 frame_control_type(frm_ctrl->type, &get_subtype));
3584 if (get_subtype) {
3585 subtype = (*get_subtype)(frm_ctrl->subtype, pkt, &get_content);
3586 tprintf("Subtype (%u, %s)", frm_ctrl->subtype, subtype);
3587 } else {
3588 tprintf("%s%s%s", colorize_start_full(black, red),
3589 "No SubType Data available", colorize_end());
3592 tprintf("%s%s", frm_ctrl->to_ds ? ", Frame goes to DS" : "",
3593 frm_ctrl->from_ds ? ", Frame comes from DS" : "");
3594 tprintf("%s", frm_ctrl->more_frags ? ", More Fragments" : "");
3595 tprintf("%s", frm_ctrl->retry ? ", Frame is retransmitted" : "");
3596 tprintf("%s", frm_ctrl->power_mgmt ? ", In Power Saving Mode" : "");
3597 tprintf("%s", frm_ctrl->more_data ? ", More Data" : "");
3598 tprintf("%s", frm_ctrl->wep ? ", Needs WEP" : "");
3599 tprintf("%s", frm_ctrl->order ? ", Order" : "");
3600 tprintf(" ]\n");
3602 if (get_content) {
3603 tprintf(" [ Subtype %s: ", subtype);
3604 if (!((*get_content) (pkt)))
3605 tprintf("%s%s%s", colorize_start_full(black, red),
3606 "Failed to dissect Subtype", colorize_end());
3607 tprintf(" ]");
3608 } else {
3609 tprintf("%s%s%s", colorize_start_full(black, red),
3610 "No SubType Data available", colorize_end());
3613 tprintf("\n");
3615 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
3618 static void ieee80211_less(struct pkt_buff *pkt)
3620 tprintf("802.11 frame (more on todo)");
3623 struct protocol ieee80211_ops = {
3624 .key = 0,
3625 .print_full = ieee80211,
3626 .print_less = ieee80211_less,