2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>
4 * Copyright 2012 Daniel Borkmann <daniel@netsniff-ng.org>
5 * Subject to the GPL, version 2.
9 * check all possible frame combinations for their behavior
10 * with respect to endianess (little / big)
15 #include <netinet/in.h> /* for ntohs() */
16 #include <asm/byteorder.h>
17 #include <arpa/inet.h> /* for inet_ntop() */
21 #include "dissector_80211.h"
28 /* Note: Fields are encoded in little-endian! */
29 struct ieee80211_frm_ctrl
{
33 #if defined(__LITTLE_ENDIAN_BITFIELD)
34 /* Correct order here ... */
35 __extension__ u16 proto_version
:2,
46 #elif defined(__BIG_ENDIAN_BITFIELD)
47 __extension__ u16 subtype
:4,
59 # error "Adjust your <asm/byteorder.h> defines"
65 /* Management Frame start */
66 /* Note: Fields are encoded in little-endian! */
67 struct ieee80211_mgmt
{
75 struct ieee80211_mgmt_auth
{
79 /* possibly followed by Challenge text */
83 struct ieee80211_mgmt_deauth
{
87 struct ieee80211_mgmt_assoc_req
{
90 /* followed by SSID and Supported rates */
94 struct ieee80211_mgmt_assoc_resp
{
98 /* followed by Supported rates */
102 struct ieee80211_mgmt_reassoc_resp
{
106 /* followed by Supported rates */
110 struct ieee80211_mgmt_reassoc_req
{
114 /* followed by SSID and Supported rates */
118 struct ieee80211_mgmt_disassoc
{
122 struct ieee80211_mgmt_probe_req
{
125 struct ieee80211_mgmt_beacon
{
129 /* followed by some of SSID, Supported rates,
130 * FH Params, DS Params, CF Params, IBSS Params, TIM */
134 struct ieee80211_mgmt_probe_resp
{
138 /* followed by some of SSID, Supported rates,
139 * FH Params, DS Params, CF Params, IBSS Params, TIM */
142 /* Management Frame end */
144 /* Control Frame start */
145 /* Note: Fields are encoded in little-endian! */
146 struct ieee80211_ctrl
{
149 struct ieee80211_ctrl_rts
{
155 struct ieee80211_ctrl_cts
{
160 struct ieee80211_ctrl_ack
{
165 struct ieee80211_ctrl_ps_poll
{
171 struct ieee80211_ctrl_cf_end
{
177 struct ieee80211_ctrl_cf_end_ack
{
182 /* Control Frame end */
184 /* Data Frame start */
185 /* Note: Fields are encoded in little-endian! */
186 struct ieee80211_data
{
192 struct element_reserved
{
196 struct element_ssid
{
201 struct element_supp_rates
{
206 struct element_fh_ps
{
214 struct element_dsss_ps
{
219 struct element_cf_ps
{
235 struct element_ibss_ps
{
240 struct element_country_tripled
{
246 struct element_country
{
248 #if defined(__LITTLE_ENDIAN_BITFIELD)
249 /* Correct order here ... */
253 #elif defined(__BIG_ENDIAN_BITFIELD)
258 # error "Adjust your <asm/byteorder.h> defines"
260 /* triplet may repeat */
261 struct element_country_tripled tripled
[0];
266 struct element_hop_pp
{
272 struct element_hop_pt
{
286 struct element_bss_load
{
293 struct element_edca_ps
{
303 struct element_tspec
{
307 #if defined(__LITTLE_ENDIAN_BITFIELD)
308 /* Correct order here ... */
309 __extension__ u32 len
:8,
320 #elif defined(__BIG_ENDIAN_BITFIELD)
321 __extension__ u32 len
:8,
333 # error "Adjust your <asm/byteorder.h> defines"
350 u16 surplus_bandw_allow
;
354 struct element_tclas
{
360 struct element_tclas_frm_class
{
366 struct element_tclas_type0
{
372 struct element_tclas_type1
{
377 struct element_tclas_type1_ip4
{
387 struct element_tclas_type1_ip6
{
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;
404 # error "Adjust your <asm/byteorder.h> defines"
410 struct element_tclas_type2
{
414 struct element_tclas_type3
{
420 struct element_tclas_type4
{
425 struct element_tclas_type4_ip4
{
435 struct element_tclas_type4_ip6
{
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;
454 # error "Adjust your <asm/byteorder.h> defines"
460 struct element_tclas_type5
{
466 struct element_schedule
{
474 struct element_chall_txt
{
479 struct element_pwr_constr
{
484 struct element_pwr_cap
{
490 struct element_tpc_req
{
494 struct element_tpc_rep
{
500 struct element_supp_ch
{
506 struct element_supp_ch_tuple
{
511 struct element_ch_sw_ann
{
518 struct element_meas_basic
{
524 struct element_meas_cca
{
530 struct element_meas_rpi
{
536 struct element_meas_ch_load
{
544 struct element_meas_noise
{
552 struct element_meas_beacon
{
562 struct element_meas_frame
{
572 struct element_meas_sta
{
580 struct element_meas_lci
{
583 u8 longitude_req_res
;
588 struct element_meas_trans_str_cat
{
597 struct element_meas_mcast_diag
{
601 u8 mcast_triggered
[0];
605 struct element_meas_loc_civic
{
608 u8 loc_srv_intv_unit
;
613 struct element_meas_loc_id
{
615 u8 loc_srv_intv_unit
;
620 struct element_meas_pause
{
625 struct element_meas_req
{
633 struct element_meas_rep
{
641 struct element_quiet
{
649 struct element_ibss_dfs
{
656 struct element_ibss_dfs_tuple
{
666 struct element_ts_del
{
671 struct element_tclas_proc
{
676 struct element_ht_cap
{
681 #if defined(__LITTLE_ENDIAN_BITFIELD)
682 /* Correct order here ... */
683 __extension__ u16 ldpc
:1,
697 #elif defined(__BIG_ENDIAN_BITFIELD)
698 __extension__ u16 rx_stbc
:2,
713 # error "Adjust your <asm/byteorder.h> defines"
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;
750 # error "Adjust your <asm/byteorder.h> defines"
759 struct element_qos_cap
{
764 struct element_ext_supp_rates
{
769 struct element_vend_spec
{
775 static int8_t len_neq_error(u8 len
, u8 intended
)
777 if(intended
!= len
) {
778 tprintf("Length should be %u Bytes", intended
);
785 static int8_t len_lt_error(u8 len
, u8 intended
)
788 tprintf("Length should be greater %u Bytes", intended
);
795 static float data_rates(u8 id
)
797 /* XXX Why not (id / 2.f)? */
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
;
831 static int8_t subelements(struct pkt_buff
*pkt
, u8 len
)
837 struct subelement
*sub
;
839 sub
= (struct subelement
*) pkt_pull(pkt
, sizeof(*sub
));
843 tprintf(", Subelement ID %u, ", sub
->id
);
844 tprintf("Length %u, ", sub
->len
);
846 data
= pkt_pull(pkt
, sub
->len
);
851 for(j
=0; j
< sub
->len
; j
++)
852 tprintf("%.2x ", data
[j
]);
858 tprintf("Length error");
865 static int8_t inf_reserved(struct pkt_buff
*pkt
, u8
*id
)
869 struct element_reserved
*reserved
;
871 reserved
= (struct element_reserved
*) pkt_pull(pkt
, sizeof(*reserved
));
872 if (reserved
== NULL
)
875 tprintf("Reserved (%u, Len (%u)): ", *id
, reserved
->len
);
877 data
= pkt_pull(pkt
, reserved
->len
);
882 for (i
= 0; i
< reserved
->len
; i
++)
883 tprintf("%.2x", data
[i
]);
888 static int8_t inf_ssid(struct pkt_buff
*pkt
, u8
*id
)
891 struct element_ssid
*ssid
;
894 ssid
= (struct element_ssid
*) pkt_pull(pkt
, sizeof(*ssid
));
898 tprintf(" SSID (%u, Len (%u)): ", *id
, ssid
->len
);
900 if ((ssid
->len
- sizeof(*ssid
) + 1) > 0) {
901 ssid_name
= (char *) pkt_pull(pkt
, ssid
->len
);
902 if (ssid_name
== NULL
)
905 for (i
= 0; i
< ssid
->len
; i
++)
906 tprintf("%c",ssid_name
[i
]);
908 tprintf("Wildcard SSID");
914 static int8_t inf_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
918 struct element_supp_rates
*supp_rates
;
920 supp_rates
= (struct element_supp_rates
*)
921 pkt_pull(pkt
, sizeof(*supp_rates
));
922 if (supp_rates
== NULL
)
925 tprintf("Rates (%u, Len (%u)): ", *id
, supp_rates
->len
);
926 if (len_lt_error(supp_rates
->len
, 1))
929 if ((supp_rates
->len
- sizeof(*supp_rates
) + 1) > 0) {
930 rates
= pkt_pull(pkt
, supp_rates
->len
);
934 for (i
= 0; i
< supp_rates
->len
; i
++)
935 tprintf("%g ", (rates
[i
] & 0x80) ?
936 ((rates
[i
] & 0x3f) * 0.5) :
937 data_rates(rates
[i
]));
944 static int8_t inf_fh_ps(struct pkt_buff
*pkt
, u8
*id
)
946 struct element_fh_ps
*fh_ps
;
948 fh_ps
= (struct element_fh_ps
*) pkt_pull(pkt
, sizeof(*fh_ps
));
952 tprintf("FH Param Set (%u, Len(%u)): ", *id
, fh_ps
->len
);
953 if (len_neq_error(fh_ps
->len
, 5))
955 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps
->dwell_time
) * TU
);
956 tprintf("HopSet: %u, ", fh_ps
->hop_set
);
957 tprintf("HopPattern: %u, ", fh_ps
->hop_pattern
);
958 tprintf("HopIndex: %u", fh_ps
->hop_index
);
963 static int8_t inf_dsss_ps(struct pkt_buff
*pkt
, u8
*id
)
965 struct element_dsss_ps
*dsss_ps
;
967 dsss_ps
= (struct element_dsss_ps
*) pkt_pull(pkt
, sizeof(*dsss_ps
));
971 tprintf("DSSS Param Set (%u, Len(%u)): ", *id
, dsss_ps
->len
);
972 if (len_neq_error(dsss_ps
->len
, 1))
974 tprintf("Current Channel: %u", dsss_ps
->curr_ch
);
979 static int8_t inf_cf_ps(struct pkt_buff
*pkt
, u8
*id
)
981 struct element_cf_ps
*cf_ps
;
983 cf_ps
= (struct element_cf_ps
*) pkt_pull(pkt
, sizeof(*cf_ps
));
987 tprintf("CF Param Set (%u, Len(%u)): ", *id
, cf_ps
->len
);
988 if (len_neq_error(cf_ps
->len
, 6))
990 tprintf("CFP Count: %u, ", cf_ps
->cfp_cnt
);
991 tprintf("CFP Period: %u, ", cf_ps
->cfp_period
);
992 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps
->cfp_max_dur
) * TU
);
993 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps
->cfp_dur_rem
) * TU
);
998 static int8_t inf_tim(struct pkt_buff
*pkt
, u8
*id
)
1000 struct element_tim
*tim
;
1002 tim
= (struct element_tim
*) pkt_pull(pkt
, sizeof(*tim
));
1006 tprintf("TIM (%u, Len(%u)): ", *id
, tim
->len
);
1007 if (len_lt_error(tim
->len
, 3))
1009 tprintf("DTIM Count: %u, ", tim
->dtim_cnt
);
1010 tprintf("DTIM Period: %u, ", tim
->dtim_period
);
1011 tprintf("Bitmap Control: %u, ", tim
->bmp_cntrl
);
1012 if ((tim
->len
- sizeof(*tim
) + 1) > 0) {
1013 u8
*bmp
= pkt_pull(pkt
, (tim
->len
- sizeof(*tim
) + 1));
1017 tprintf("Partial Virtual Bitmap: 0x");
1018 for(u8 i
=0; i
< (tim
->len
- sizeof(*tim
) + 1); i
++)
1019 tprintf("%.2x ", bmp
[i
]);
1025 static int8_t inf_ibss_ps(struct pkt_buff
*pkt
, u8
*id
)
1027 struct element_ibss_ps
*ibss_ps
;
1029 ibss_ps
= (struct element_ibss_ps
*) pkt_pull(pkt
, sizeof(*ibss_ps
));
1030 if (ibss_ps
== NULL
)
1033 tprintf("IBSS Param Set (%u, Len(%u)): ", *id
, ibss_ps
->len
);
1034 if (len_neq_error(ibss_ps
->len
, 2))
1036 tprintf("ATIM Window: %fs", le16_to_cpu(ibss_ps
->atim_win
) * TU
);
1041 static int8_t inf_country(struct pkt_buff
*pkt
, u8
*id
)
1045 struct element_country
*country
;
1047 country
= (struct element_country
*) pkt_pull(pkt
, sizeof(*country
));
1048 if (country
== NULL
)
1051 tprintf("Country (%u, Len(%u)): ", *id
, country
->len
);
1052 if (len_lt_error(country
->len
, 6))
1054 tprintf("Country String: %c%c%c", country
->country_first
,
1055 country
->country_sec
, country
->country_third
);
1057 for (i
= 0; i
< (country
->len
- 3); i
+= 3) {
1058 struct element_country_tripled
*country_tripled
;
1060 country_tripled
= (struct element_country_tripled
*)
1061 pkt_pull(pkt
, sizeof(*country_tripled
));
1062 if (country_tripled
== NULL
)
1065 if(country_tripled
->frst_ch
>= 201) {
1066 tprintf("Oper Ext ID: %u, ", country_tripled
->frst_ch
);
1067 tprintf("Operating Class: %u, ", country_tripled
->nr_ch
);
1068 tprintf("Coverage Class: %u", country_tripled
->max_trans
);
1070 tprintf("First Ch Nr: %u, ", country_tripled
->frst_ch
);
1071 tprintf("Nr of Ch: %u, ", country_tripled
->nr_ch
);
1072 tprintf("Max Transmit Pwr Lvl: %u", country_tripled
->max_trans
);
1076 if(country
->len
% 2) {
1077 pad
= pkt_pull(pkt
, 1);
1081 tprintf(", Pad: 0x%x", *pad
);
1087 static int8_t inf_hop_pp(struct pkt_buff
*pkt
, u8
*id
)
1089 struct element_hop_pp
*hop_pp
;
1091 hop_pp
= (struct element_hop_pp
*) pkt_pull(pkt
, sizeof(*hop_pp
));
1095 tprintf("Hopping Pattern Param (%u, Len(%u)): ", *id
, hop_pp
->len
);
1096 if (len_neq_error(hop_pp
->len
, 2))
1098 tprintf("Nr of Ch: %u", hop_pp
->nr_ch
);
1103 static int8_t inf_hop_pt(struct pkt_buff
*pkt
, u8
*id
)
1107 struct element_hop_pt
*hop_pt
;
1109 hop_pt
= (struct element_hop_pt
*) pkt_pull(pkt
, sizeof(*hop_pt
));
1113 tprintf("Hopping Pattern Table (%u, Len(%u)): ", *id
, hop_pt
->len
);
1114 if (len_lt_error(hop_pt
->len
, 4))
1116 tprintf("Flag: %u, ", hop_pt
->flag
);
1117 tprintf("Nr of Sets: %u, ", hop_pt
->nr_sets
);
1118 tprintf("Modules: %u, ", hop_pt
->modules
);
1119 tprintf("Offs: %u", hop_pt
->offs
);
1121 if ((hop_pt
->len
- sizeof(*hop_pt
) + 1) > 0) {
1122 rand_tabl
= pkt_pull(pkt
, (hop_pt
->len
- sizeof(*hop_pt
) + 1));
1123 if (rand_tabl
== NULL
)
1126 tprintf(", Rand table: 0x");
1127 for (i
= 0; i
< (hop_pt
->len
- sizeof(*hop_pt
) + 1); i
++)
1128 tprintf("%.2x ", rand_tabl
[i
]);
1134 static int8_t inf_req(struct pkt_buff
*pkt
, u8
*id
)
1137 struct element_req
*req
;
1140 req
= (struct element_req
*) pkt_pull(pkt
, sizeof(*req
));
1144 tprintf("Request Element (%u, Len(%u)): ", *id
, req
->len
);
1145 if ((req
->len
- sizeof(*req
) + 1) > 0) {
1146 req_ids
= pkt_pull(pkt
, (req
->len
- sizeof(*req
) + 1));
1147 if (req_ids
== NULL
)
1150 tprintf(", Requested Element IDs: ");
1151 for (i
= 0; i
< (req
->len
- sizeof(*req
) + 1); i
++)
1152 tprintf("%u ", req_ids
[i
]);
1158 static int8_t inf_bss_load(struct pkt_buff
*pkt
, u8
*id
)
1160 struct element_bss_load
*bss_load
;
1162 bss_load
= (struct element_bss_load
*) pkt_pull(pkt
, sizeof(*bss_load
));
1163 if (bss_load
== NULL
)
1166 tprintf("BSS Load element (%u, Len(%u)): ", *id
, bss_load
->len
);
1167 if (len_neq_error(bss_load
->len
, 5))
1169 tprintf("Station Count: %u, ", le16_to_cpu(bss_load
->station_cnt
));
1170 tprintf("Channel Utilization: %u, ", bss_load
->ch_util
);
1171 tprintf("Available Admission Capacity: %uus",
1172 bss_load
->avlb_adm_cap
* 32);
1177 static int8_t inf_edca_ps(struct pkt_buff
*pkt
, u8
*id
)
1179 u32 ac_be
, ac_bk
, ac_vi
, ac_vo
;
1180 struct element_edca_ps
*edca_ps
;
1182 edca_ps
= (struct element_edca_ps
*) pkt_pull(pkt
, sizeof(*edca_ps
));
1183 if (edca_ps
== NULL
)
1186 ac_be
= le32_to_cpu(edca_ps
->ac_be
);
1187 ac_bk
= le32_to_cpu(edca_ps
->ac_bk
);
1188 ac_vi
= le32_to_cpu(edca_ps
->ac_vi
);
1189 ac_vo
= le32_to_cpu(edca_ps
->ac_vo
);
1191 tprintf("EDCA Param Set (%u, Len(%u)): ", *id
, edca_ps
->len
);
1192 if (len_neq_error(edca_ps
->len
, 18))
1194 tprintf("QoS Info: 0x%x (-> EDCA Param Set Update Count (%u),"
1195 "Q-Ack (%u), Queue Re (%u), TXOP Req(%u), Res(%u)), ",
1196 edca_ps
->qos_inf
, edca_ps
->qos_inf
>> 4,
1197 (edca_ps
->qos_inf
>> 3) & 1, (edca_ps
->qos_inf
>> 2) & 1,
1198 (edca_ps
->qos_inf
>> 1) & 1, edca_ps
->qos_inf
& 1);
1199 tprintf("Reserved: 0x%x, ", edca_ps
->res
);
1200 tprintf("AC_BE Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1201 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_be
,
1202 ac_be
>> 28, (ac_be
>> 27) & 1, (ac_be
>> 25) & 3,
1203 (ac_be
>> 24) & 1, (ac_be
>> 20) & 15, (ac_be
>> 16) & 15,
1204 bswap_16(ac_be
& 0xFFFF) * 32);
1205 tprintf("AC_BK Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1206 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_bk
,
1207 ac_bk
>> 28, (ac_bk
>> 27) & 1, (ac_bk
>> 25) & 3,
1208 (ac_bk
>> 24) & 1, (ac_bk
>> 20) & 15, (ac_bk
>> 16) & 15,
1209 bswap_16(ac_bk
& 0xFFFF) * 32);
1210 tprintf("AC_VI Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1211 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_vi
,
1212 ac_vi
>> 28, (ac_vi
>> 27) & 1, (ac_vi
>> 25) & 3,
1213 (ac_vi
>> 24) & 1, (ac_vi
>> 20) & 15, (ac_vi
>> 16) & 15,
1214 bswap_16(ac_vi
& 0xFFFF) * 32);
1215 tprintf("AC_VO Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1216 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)", ac_vo
,
1217 ac_vo
>> 28, (ac_vo
>> 27) & 1, (ac_vo
>> 25) & 3,
1218 (ac_vo
>> 24) & 1, (ac_vo
>> 20) & 15, (ac_vo
>> 16) & 15,
1219 bswap_16(ac_vo
& 0xFFFF) * 32);
1224 static int8_t inf_tspec(struct pkt_buff
*pkt
, u8
*id
)
1226 u16 nom_msdu_size
, surplus_bandw_allow
;
1227 struct element_tspec
*tspec
;
1229 tspec
= (struct element_tspec
*) pkt_pull(pkt
, sizeof(*tspec
));
1233 nom_msdu_size
= le16_to_cpu(tspec
->nom_msdu_size
);
1234 surplus_bandw_allow
= le16_to_cpu(tspec
->surplus_bandw_allow
);
1236 tprintf("TSPEC (%u, Len(%u)): ", *id
, tspec
->len
);
1237 if (len_neq_error(tspec
->len
, 55))
1239 tprintf("Traffic Type: %u, ", tspec
->traffic_type
);
1240 tprintf("TSID: %u, ", tspec
->tsid
);
1241 tprintf("Direction: %u, ", tspec
->direction
);
1242 tprintf("Access Policy: %u, ", tspec
->access_policy
);
1243 tprintf("Aggregation: %u, ", tspec
->aggr
);
1244 tprintf("User Priority: %u, ", tspec
->user_prior
);
1245 tprintf("TSinfo Ack Policy: %u, ", tspec
->tsinfo_ack_pol
);
1246 tprintf("Schedule: %u, ", tspec
->schedule
);
1247 tprintf("Reserved: 0x%x, ", tspec
->res
);
1248 tprintf("Nominal MSDU Size: %uB (Fixed (%u)), ",
1249 nom_msdu_size
>> 1, nom_msdu_size
& 1);
1250 tprintf("Maximum MSDU Size: %uB, ", le16_to_cpu(tspec
->max_msdu_size
));
1251 tprintf("Minimum Service Interval: %uus, ",
1252 le32_to_cpu(tspec
->min_srv_intv
));
1253 tprintf("Maximum Service Interval: %uus, ",
1254 le32_to_cpu(tspec
->max_srv_intv
));
1255 tprintf("Inactivity Interval: %uus, ",
1256 le32_to_cpu(tspec
->inactive_intv
));
1257 tprintf("Suspension Interval: %uus, ", le32_to_cpu(tspec
->susp_intv
));
1258 tprintf("Service Start Time: %uus, ",
1259 le32_to_cpu(tspec
->srv_start_time
));
1260 tprintf("Minimum Data Rate: %ub/s, ",le32_to_cpu(tspec
->min_data_rate
));
1261 tprintf("Mean Data Rate: %ub/s, ", le32_to_cpu(tspec
->mean_data_rate
));
1262 tprintf("Peak Data Rate: %ub/s, ",le32_to_cpu(tspec
->peak_data_rate
));
1263 tprintf("Burst Size: %uB, ", le32_to_cpu(tspec
->burst_size
));
1264 tprintf("Delay Bound: %uus, ", le32_to_cpu(tspec
->delay_bound
));
1265 tprintf("Minimum PHY Rate: %ub/s, ", le32_to_cpu(tspec
->min_phy_rate
));
1266 tprintf("Surplus Bandwidth: %u.%u, ", surplus_bandw_allow
>> 13,
1267 surplus_bandw_allow
& 0x1FFF);
1268 tprintf("Medium Time: %uus", le16_to_cpu(tspec
->med_time
) * 32);
1273 static const char *class_type(u8 type
)
1276 case 0: return "Ethernet parameters";
1277 case 1: return "TCP/UDP IP parameters";
1278 case 2: return "IEEE 802.1Q parameters";
1279 case 3: return "Filter Offset parameters";
1280 case 4: return "IP and higher layer parameters";
1281 case 5: return "IEEE 802.1D/Q parameters";
1282 default: return "Reserved";
1286 static int8_t inf_tclas(struct pkt_buff
*pkt
, u8
*id
)
1288 struct element_tclas
*tclas
;
1289 struct element_tclas_frm_class
*frm_class
;
1291 tclas
= (struct element_tclas
*) pkt_pull(pkt
, sizeof(*tclas
));
1295 frm_class
= (struct element_tclas_frm_class
*)
1296 pkt_pull(pkt
, sizeof(*frm_class
));
1297 if (frm_class
== NULL
)
1300 tprintf("TCLAS (%u, Len(%u)): ", *id
, tclas
->len
);
1301 if (len_lt_error(tclas
->len
, 3))
1303 tprintf("User Priority: %u, ", tclas
->user_priority
);
1304 tprintf("Classifier Type: %s (%u), ", class_type(frm_class
->type
),
1306 tprintf("Classifier Mask: 0x%x, ", frm_class
->mask
);
1308 if(frm_class
->type
== 0) {
1309 struct element_tclas_type0
*type0
;
1311 type0
= (struct element_tclas_type0
*)
1312 pkt_pull(pkt
, sizeof(*type0
));
1316 /* I think little endian, like the rest */
1317 tprintf("Src Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1318 type0
->sa
[5], type0
->sa
[4], type0
->sa
[3],
1319 type0
->sa
[2], type0
->sa
[1], type0
->sa
[0]);
1320 tprintf("Dst Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1321 type0
->da
[5], type0
->da
[4], type0
->da
[3],
1322 type0
->da
[2], type0
->da
[1], type0
->da
[0]);
1323 tprintf("Type: 0x%x", le16_to_cpu(type0
->type
));
1325 else if(frm_class
->type
== 1) {
1326 struct element_tclas_type1
*type1
;
1328 type1
= (struct element_tclas_type1
*)
1329 pkt_pull(pkt
, sizeof(*type1
));
1333 tprintf("Version: %u, ", type1
->version
);
1334 /* big endian format follows */
1335 if(type1
->version
== 4) {
1336 struct element_tclas_type1_ip4
*type1_ip4
;
1337 char src_ip
[INET_ADDRSTRLEN
];
1338 char dst_ip
[INET_ADDRSTRLEN
];
1340 type1_ip4
= (struct element_tclas_type1_ip4
*)
1341 pkt_pull(pkt
, sizeof(*type1_ip4
));
1342 if (type1_ip4
== NULL
)
1345 inet_ntop(AF_INET
, &type1_ip4
->sa
, src_ip
, sizeof(src_ip
));
1346 inet_ntop(AF_INET
, &type1_ip4
->da
, dst_ip
, sizeof(dst_ip
));
1348 tprintf("Src IP: %s, ", src_ip
);
1349 tprintf("Dst IP: %s, ", dst_ip
);
1350 tprintf("Src Port: %u, ", ntohs(type1_ip4
->sp
));
1351 tprintf("Dst Port: %u, ", ntohs(type1_ip4
->dp
));
1352 tprintf("DSCP: 0x%x, ", type1_ip4
->dscp
);
1353 tprintf("Proto: %u, ", type1_ip4
->proto
);
1354 tprintf("Res: 0x%x", type1_ip4
->reserved
);
1356 else if(type1
->version
== 6) {
1357 struct element_tclas_type1_ip6
*type1_ip6
;
1358 char src_ip
[INET6_ADDRSTRLEN
];
1359 char dst_ip
[INET6_ADDRSTRLEN
];
1361 type1_ip6
= (struct element_tclas_type1_ip6
*)
1362 pkt_pull(pkt
, sizeof(*type1_ip6
));
1363 if (type1_ip6
== NULL
)
1366 inet_ntop(AF_INET6
, &type1_ip6
->sa
,
1367 src_ip
, sizeof(src_ip
));
1368 inet_ntop(AF_INET6
, &type1_ip6
->da
,
1369 dst_ip
, sizeof(dst_ip
));
1371 tprintf("Src IP: %s, ", src_ip
);
1372 tprintf("Dst IP: %s, ", dst_ip
);
1373 tprintf("Src Port: %u, ", ntohs(type1_ip6
->sp
));
1374 tprintf("Dst Port: %u, ", ntohs(type1_ip6
->dp
));
1375 tprintf("Flow Label: 0x%x%x%x", type1_ip6
->flow_label1
,
1376 type1_ip6
->flow_label2
, type1_ip6
->flow_label3
);
1379 tprintf("Version (%u) not supported", type1
->version
);
1384 else if(frm_class
->type
== 2) {
1385 struct element_tclas_type2
*type2
;
1387 type2
= (struct element_tclas_type2
*)
1388 pkt_pull(pkt
, sizeof(*type2
));
1392 tprintf("802.1Q VLAN TCI: 0x%x", ntohs(type2
->vlan_tci
));
1394 else if(frm_class
->type
== 3) {
1395 struct element_tclas_type3
*type3
;
1399 type3
= (struct element_tclas_type3
*)
1400 pkt_pull(pkt
, sizeof(*type3
));
1404 len
= (tclas
->len
- 5) / 2;
1406 tprintf("Filter Offset: %u, ", type3
->offs
);
1408 if((len
& 1) || (len_lt_error(tclas
->len
, 5))) {
1409 tprintf("Length of TCLAS (%u) not correct", tclas
->len
);
1413 val
= pkt_pull(pkt
, len
);
1417 tprintf("Filter Value: 0x");
1418 for (i
= 0; i
< len
/ 2; i
++)
1419 tprintf("%x ", val
[i
]);
1421 tprintf("Filter Mask: 0x");
1422 for (i
= len
/ 2; i
< len
; i
++)
1423 tprintf("%x ", val
[i
]);
1427 else if(frm_class
->type
== 4) {
1428 struct element_tclas_type4
*type4
;
1430 type4
= (struct element_tclas_type4
*)
1431 pkt_pull(pkt
, sizeof(*type4
));
1435 tprintf("Version: %u, ", type4
->version
);
1436 /* big endian format follows */
1437 if(type4
->version
== 4) {
1438 struct element_tclas_type4_ip4
*type4_ip4
;
1439 char src_ip
[INET_ADDRSTRLEN
];
1440 char dst_ip
[INET_ADDRSTRLEN
];
1442 type4_ip4
= (struct element_tclas_type4_ip4
*)
1443 pkt_pull(pkt
, sizeof(*type4_ip4
));
1444 if (type4_ip4
== NULL
)
1447 inet_ntop(AF_INET
, &type4_ip4
->sa
, src_ip
, sizeof(src_ip
));
1448 inet_ntop(AF_INET
, &type4_ip4
->da
, dst_ip
, sizeof(dst_ip
));
1450 tprintf("Src IP: %s, ", src_ip
);
1451 tprintf("Dst IP: %s, ", dst_ip
);
1452 tprintf("Src Port: %u, ", ntohs(type4_ip4
->sp
));
1453 tprintf("Dst Port: %u, ", ntohs(type4_ip4
->dp
));
1454 tprintf("DSCP: 0x%x, ", type4_ip4
->dscp
);
1455 tprintf("Proto: %u, ", type4_ip4
->proto
);
1456 tprintf("Res: 0x%x", type4_ip4
->reserved
);
1458 else if(type4
->version
== 6) {
1459 struct element_tclas_type4_ip6
*type4_ip6
;
1460 char src_ip
[INET6_ADDRSTRLEN
];
1461 char dst_ip
[INET6_ADDRSTRLEN
];
1463 type4_ip6
= (struct element_tclas_type4_ip6
*)
1464 pkt_pull(pkt
, sizeof(*type4_ip6
));
1465 if (type4_ip6
== NULL
)
1468 inet_ntop(AF_INET6
, &type4_ip6
->sa
,
1469 src_ip
, sizeof(src_ip
));
1470 inet_ntop(AF_INET6
, &type4_ip6
->da
,
1471 dst_ip
, sizeof(dst_ip
));
1473 tprintf("Src IP: %s, ", src_ip
);
1474 tprintf("Dst IP: %s, ", dst_ip
);
1475 tprintf("Src Port: %u, ", ntohs(type4_ip6
->sp
));
1476 tprintf("Dst Port: %u, ", ntohs(type4_ip6
->dp
));
1477 tprintf("DSCP: 0x%x, ", type4_ip6
->dscp
);
1478 tprintf("Nxt Hdr: %u, ", type4_ip6
->nxt_hdr
);
1479 tprintf("Flow Label: 0x%x%x%x", type4_ip6
->flow_label1
,
1480 type4_ip6
->flow_label2
, type4_ip6
->flow_label3
);
1483 tprintf("Version (%u) not supported", type4
->version
);
1487 else if(frm_class
->type
== 5) {
1488 struct element_tclas_type5
*type5
;
1490 type5
= (struct element_tclas_type5
*)
1491 pkt_pull(pkt
, sizeof(*type5
));
1495 tprintf("802.1Q PCP: 0x%x, ", type5
->pcp
);
1496 tprintf("802.1Q CFI: 0x%x, ", type5
->cfi
);
1497 tprintf("802.1Q VID: 0x%x", type5
->vid
);
1500 tprintf("Classifier Type (%u) not supported", frm_class
->type
);
1507 static int8_t inf_sched(struct pkt_buff
*pkt
, u8
*id
)
1509 struct element_schedule
*schedule
;
1512 schedule
= (struct element_schedule
*) pkt_pull(pkt
, sizeof(*schedule
));
1513 if (schedule
== NULL
)
1516 info
= le16_to_cpu(schedule
->inf
);
1518 tprintf("Schedule (%u, Len(%u)): ", *id
, schedule
->len
);
1519 if (len_neq_error(schedule
->len
, 12))
1522 tprintf("Aggregation: %u, ", info
>> 15);
1523 tprintf("TSID: %u, ", (info
>> 11) & 0xF);
1524 tprintf("Direction: %u, ", (info
>> 9) & 0x3);
1525 tprintf("Res: %u, ", info
& 0x1FF);
1526 tprintf("Serv Start Time: %uus, ", le32_to_cpu(schedule
->start
));
1527 tprintf("Serv Interval: %uus, ", le32_to_cpu(schedule
->serv_intv
));
1528 tprintf("Spec Interval: %fs", le32_to_cpu(schedule
->spec_intv
) * TU
);
1533 static int8_t inf_chall_txt(struct pkt_buff
*pkt
, u8
*id
)
1535 struct element_chall_txt
*chall_txt
;
1539 chall_txt
= (struct element_chall_txt
*)
1540 pkt_pull(pkt
, sizeof(*chall_txt
));
1541 if (chall_txt
== NULL
)
1544 tprintf("Challenge Text (%u, Len(%u)): ", *id
, chall_txt
->len
);
1545 if ((chall_txt
->len
- sizeof(*chall_txt
) + 1) > 0) {
1546 txt
= pkt_pull(pkt
, (chall_txt
->len
- sizeof(*chall_txt
) + 1));
1551 for (i
= 0; i
< (chall_txt
->len
- sizeof(*chall_txt
) + 1); i
++)
1552 tprintf("%x ", txt
[i
]);
1558 static int8_t inf_pwr_constr(struct pkt_buff
*pkt
, u8
*id
)
1560 struct element_pwr_constr
*pwr_constr
;
1562 pwr_constr
= (struct element_pwr_constr
*) pkt_pull(pkt
, sizeof(*pwr_constr
));
1563 if (pwr_constr
== NULL
)
1566 tprintf("Power Constraint (%u, Len(%u)): ", *id
, pwr_constr
->len
);
1567 if (len_neq_error(pwr_constr
->len
, 1))
1570 tprintf("Local Power Constraint: %udB", pwr_constr
->local_pwr_constr
);
1575 static int8_t inf_pwr_cap(struct pkt_buff
*pkt
, u8
*id
)
1577 struct element_pwr_cap
*pwr_cap
;
1579 pwr_cap
= (struct element_pwr_cap
*) pkt_pull(pkt
, sizeof(*pwr_cap
));
1580 if (pwr_cap
== NULL
)
1583 tprintf("Power Capability (%u, Len(%u)): ", *id
, pwr_cap
->len
);
1584 if (len_neq_error(pwr_cap
->len
, 2))
1587 tprintf("Min. Transm. Pwr Cap.: %ddBm, ", (int8_t)pwr_cap
->min_pwr_cap
);
1588 tprintf("Max. Transm. Pwr Cap.: %ddBm", (int8_t)pwr_cap
->max_pwr_cap
);
1593 static int8_t inf_tpc_req(struct pkt_buff
*pkt
, u8
*id
)
1595 struct element_tpc_req
*tpc_req
;
1597 tpc_req
= (struct element_tpc_req
*) pkt_pull(pkt
, sizeof(*tpc_req
));
1598 if (tpc_req
== NULL
)
1601 tprintf("TPC Request (%u, Len(%u))", *id
, tpc_req
->len
);
1602 if (len_neq_error(tpc_req
->len
, 0))
1608 static int8_t inf_tpc_rep(struct pkt_buff
*pkt
, u8
*id
)
1610 struct element_tpc_rep
*tpc_rep
;
1612 tpc_rep
= (struct element_tpc_rep
*) pkt_pull(pkt
, sizeof(*tpc_rep
));
1613 if (tpc_rep
== NULL
)
1616 tprintf("TPC Report (%u, Len(%u)): ", *id
, tpc_rep
->len
);
1617 if (len_neq_error(tpc_rep
->len
, 2))
1620 tprintf("Transmit Power: %udBm, ", (int8_t)tpc_rep
->trans_pwr
);
1621 tprintf("Link Margin: %udB", (int8_t)tpc_rep
->trans_pwr
);
1626 static int8_t inf_supp_ch(struct pkt_buff
*pkt
, u8
*id
)
1628 struct element_supp_ch
*supp_ch
;
1631 supp_ch
= (struct element_supp_ch
*) pkt_pull(pkt
, sizeof(*supp_ch
));
1632 if (supp_ch
== NULL
)
1635 tprintf("Supp Channels (%u, Len(%u)): ", *id
, supp_ch
->len
);
1636 if (len_lt_error(supp_ch
->len
, 2))
1639 if(supp_ch
->len
& 1) {
1640 tprintf("Length should be modulo 2");
1644 for (i
= 0; i
< supp_ch
->len
; i
+= 2) {
1645 struct element_supp_ch_tuple
*supp_ch_tuple
;
1647 supp_ch_tuple
= (struct element_supp_ch_tuple
*)
1648 pkt_pull(pkt
, sizeof(*supp_ch_tuple
));
1649 if (supp_ch_tuple
== NULL
)
1652 tprintf("First Channel Nr: %u, ", supp_ch_tuple
->first_ch_nr
);
1653 tprintf("Nr of Channels: %u, ", supp_ch_tuple
->nr_ch
);
1659 static int8_t inf_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
)
1661 struct element_ch_sw_ann
*ch_sw_ann
;
1663 ch_sw_ann
= (struct element_ch_sw_ann
*)
1664 pkt_pull(pkt
, sizeof(*ch_sw_ann
));
1665 if (ch_sw_ann
== NULL
)
1668 tprintf("Channel Switch Announc (%u, Len(%u)): ", *id
, ch_sw_ann
->len
);
1669 if (len_neq_error(ch_sw_ann
->len
, 3))
1672 tprintf("Switch Mode: %u, ", ch_sw_ann
->switch_mode
);
1673 tprintf("New Nr: %u, ", ch_sw_ann
->new_nr
);
1674 tprintf("Switch Count: %u", ch_sw_ann
->switch_cnt
);
1679 static const char *meas_type(u8 type
)
1682 case 0: return "Basic";
1683 case 1: return "Clear Channel assesment (CCA)";
1684 case 2: return "Receive power indication (RPI) histogram";
1685 case 3: return "Channel load";
1686 case 4: return "Noise histogram";
1687 case 5: return "Beacon";
1688 case 6: return "Frame";
1689 case 7: return "STA statistics";
1690 case 8: return "LCI";
1691 case 9: return "Transmit stream/category measurement";
1692 case 10: return "Multicast diagnostics";
1693 case 11: return "Location Civic";
1694 case 12: return "Location Identifier";
1695 case 13 ... 255: return "Reserved";
1699 static int8_t inf_meas_req(struct pkt_buff
*pkt
, u8
*id
)
1701 struct element_meas_req
*meas_req
;
1703 meas_req
= (struct element_meas_req
*) pkt_pull(pkt
, sizeof(*meas_req
));
1704 if (meas_req
== NULL
)
1707 tprintf("Measurement Req (%u, Len(%u)): ", *id
, meas_req
->len
);
1708 if (len_lt_error(meas_req
->len
, 3))
1711 tprintf("Token: %u, ", meas_req
->token
);
1712 tprintf("Req Mode: 0x%x (Parallel (%u), Enable(%u), Request(%u), "
1713 "Report(%u), Dur Mand(%u)), ", meas_req
->req_mode
,
1714 meas_req
->req_mode
>> 7, (meas_req
->req_mode
>> 6) & 0x1,
1715 (meas_req
->req_mode
>> 5) & 0x1, (meas_req
->req_mode
>> 4) & 0x1,
1716 (meas_req
->req_mode
>> 3) & 0x1);
1717 tprintf("Type: %s (%u), ", meas_type(meas_req
->type
), meas_req
->type
);
1719 if(meas_req
->len
> 3) {
1720 if(meas_req
->type
== 0) {
1721 struct element_meas_basic
*basic
;
1723 basic
= (struct element_meas_basic
*)
1724 pkt_pull(pkt
, sizeof(*basic
));
1728 if (!(meas_req
->len
- 3 - sizeof(*basic
))) {
1729 tprintf("Length of Req matchs not Type %u",
1734 tprintf("Ch Nr: %uus, ", basic
->ch_nr
);
1735 tprintf("Meas Start Time: %lu, ",
1736 le64_to_cpu(basic
->start
));
1737 tprintf("Meas Duration: %fs",
1738 le16_to_cpu(basic
->dur
) * TU
);
1741 else if(meas_req
->type
== 1) {
1742 struct element_meas_cca
*cca
;
1744 cca
= (struct element_meas_cca
*)
1745 pkt_pull(pkt
, sizeof(*cca
));
1749 if (!(meas_req
->len
- 3 - sizeof(*cca
))) {
1750 tprintf("Length of Req matchs not Type %u",
1755 tprintf("Ch Nr: %uus, ", cca
->ch_nr
);
1756 tprintf("Meas Start Time: %lu, ",
1757 le64_to_cpu(cca
->start
));
1758 tprintf("Meas Duration: %fs",
1759 le16_to_cpu(cca
->dur
) * TU
);
1761 else if(meas_req
->type
== 2) {
1762 struct element_meas_rpi
*rpi
;
1764 rpi
= (struct element_meas_rpi
*)
1765 pkt_pull(pkt
, sizeof(*rpi
));
1769 if (!(meas_req
->len
- 3 - sizeof(*rpi
))) {
1770 tprintf("Length of Req matchs not Type %u",
1775 tprintf("Ch Nr: %uus, ", rpi
->ch_nr
);
1776 tprintf("Meas Start Time: %lu, ",
1777 le64_to_cpu(rpi
->start
));
1778 tprintf("Meas Duration: %fs",
1779 le16_to_cpu(rpi
->dur
) * TU
);
1781 else if(meas_req
->type
== 3) {
1782 struct element_meas_ch_load
*ch_load
;
1784 ch_load
= (struct element_meas_ch_load
*)
1785 pkt_pull(pkt
, sizeof(*ch_load
));
1786 if (ch_load
== NULL
)
1789 if ((meas_req
->len
- 3 - sizeof(*ch_load
)) >= 0) {
1790 tprintf("Length of Req matchs not Type %u",
1795 tprintf("OP Class: %u, ", ch_load
->op_class
);
1796 tprintf("Ch Nr: %u, ", ch_load
->ch_nr
);
1797 tprintf("Rand Intv: %fs, ",
1798 le16_to_cpu(ch_load
->rand_intv
) * TU
);
1799 tprintf("Meas Duration: %fs",
1800 le16_to_cpu(ch_load
->dur
) * TU
);
1802 if(!subelements(pkt
,
1803 meas_req
->len
- 3 - sizeof(*ch_load
)))
1806 else if(meas_req
->type
== 4) {
1807 struct element_meas_noise
*noise
;
1809 noise
= (struct element_meas_noise
*)
1810 pkt_pull(pkt
, sizeof(*noise
));
1814 if ((meas_req
->len
- 3 - sizeof(*noise
)) >= 0) {
1815 tprintf("Length of Req matchs not Type %u",
1820 tprintf("OP Class: %u, ", noise
->op_class
);
1821 tprintf("Ch Nr: %u, ", noise
->ch_nr
);
1822 tprintf("Rand Intv: %fs, ",
1823 le16_to_cpu(noise
->rand_intv
) * TU
);
1824 tprintf("Meas Duration: %fs",
1825 le16_to_cpu(noise
->dur
) * TU
);
1827 if(!subelements(pkt
,
1828 meas_req
->len
- 3 - sizeof(*noise
)))
1831 else if(meas_req
->type
== 5) {
1832 struct element_meas_beacon
*beacon
;
1834 beacon
= (struct element_meas_beacon
*)
1835 pkt_pull(pkt
, sizeof(*beacon
));
1839 if ((meas_req
->len
- 3 - sizeof(*beacon
)) >= 0) {
1840 tprintf("Length of Req matchs not Type %u",
1845 tprintf("OP Class: %u, ", beacon
->op_class
);
1846 tprintf("Ch Nr: %u, ", beacon
->ch_nr
);
1847 tprintf("Rand Intv: %fs, ",
1848 le16_to_cpu(beacon
->rand_intv
) * TU
);
1849 tprintf("Meas Duration: %fs",
1850 le16_to_cpu(beacon
->dur
) * TU
);
1851 tprintf("Mode: %u, ", beacon
->mode
);
1852 tprintf("BSSID: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1853 beacon
->bssid
[0], beacon
->bssid
[1],
1854 beacon
->bssid
[2], beacon
->bssid
[3],
1855 beacon
->bssid
[4], beacon
->bssid
[5]);
1857 if(!subelements(pkt
,
1858 meas_req
->len
- 3 - sizeof(*beacon
)))
1861 else if(meas_req
->type
== 6) {
1862 struct element_meas_frame
*frame
;
1864 frame
= (struct element_meas_frame
*)
1865 pkt_pull(pkt
, sizeof(*frame
));
1869 if ((meas_req
->len
- 3 - sizeof(*frame
)) >= 0) {
1870 tprintf("Length of Req matchs not Type %u",
1875 tprintf("OP Class: %u, ", frame
->op_class
);
1876 tprintf("Ch Nr: %u, ", frame
->ch_nr
);
1877 tprintf("Rand Intv: %fs, ",
1878 le16_to_cpu(frame
->rand_intv
) * TU
);
1879 tprintf("Meas Duration: %fs",
1880 le16_to_cpu(frame
->dur
) * TU
);
1881 tprintf("Request Type: %u, ", frame
->frame
);
1882 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1883 frame
->mac
[0], frame
->mac
[1],
1884 frame
->mac
[2], frame
->mac
[3],
1885 frame
->mac
[4], frame
->mac
[5]);
1887 if(!subelements(pkt
,
1888 meas_req
->len
- 3 - sizeof(*frame
)))
1891 else if(meas_req
->type
== 7) {
1892 struct element_meas_sta
*sta
;
1894 sta
= (struct element_meas_sta
*)
1895 pkt_pull(pkt
, sizeof(*sta
));
1899 if ((meas_req
->len
- 3 - sizeof(*sta
)) >= 0) {
1900 tprintf("Length of Req matchs not Type %u",
1905 tprintf("Peer MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1906 sta
->peer_mac
[0], sta
->peer_mac
[1],
1907 sta
->peer_mac
[2], sta
->peer_mac
[3],
1908 sta
->peer_mac
[4], sta
->peer_mac
[5]);
1909 tprintf("Rand Intv: %fs, ",
1910 le16_to_cpu(sta
->rand_intv
) * TU
);
1911 tprintf("Meas Duration: %fs",
1912 le16_to_cpu(sta
->dur
) * TU
);
1913 tprintf("Group ID: %u, ", sta
->group_id
);
1915 if(!subelements(pkt
,
1916 meas_req
->len
- 3 - sizeof(*sta
)))
1919 else if(meas_req
->type
== 8) {
1920 struct element_meas_lci
*lci
;
1922 lci
= (struct element_meas_lci
*)
1923 pkt_pull(pkt
, sizeof(*lci
));
1927 if ((meas_req
->len
- 3 - sizeof(*lci
)) >= 0) {
1928 tprintf("Length of Req matchs not Type %u",
1933 tprintf("Location Subj: %u, ", lci
->loc_subj
);
1934 tprintf("Latitude Req Res: %udeg",
1935 lci
->latitude_req_res
);
1936 tprintf("Longitude Req Res: %udeg",
1937 lci
->longitude_req_res
);
1938 tprintf("Altitude Req Res: %udeg",
1939 lci
->altitude_req_res
);
1941 if(!subelements(pkt
,
1942 meas_req
->len
- 3 - sizeof(*lci
)))
1945 else if(meas_req
->type
== 9) {
1946 struct element_meas_trans_str_cat
*trans
;
1948 trans
= (struct element_meas_trans_str_cat
*)
1949 pkt_pull(pkt
, sizeof(*trans
));
1953 if ((meas_req
->len
- 3 - sizeof(*trans
)) >= 0) {
1954 tprintf("Length of Req matchs not Type %u",
1959 tprintf("Rand Intv: %fs, ",
1960 le16_to_cpu(trans
->rand_intv
) * TU
);
1961 tprintf("Meas Duration: %fs",
1962 le16_to_cpu(trans
->dur
) * TU
);
1963 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1964 trans
->peer_sta_addr
[0], trans
->peer_sta_addr
[1],
1965 trans
->peer_sta_addr
[2], trans
->peer_sta_addr
[3],
1966 trans
->peer_sta_addr
[4], trans
->peer_sta_addr
[5]);
1967 tprintf("Traffic ID: %u, ", trans
->traffic_id
);
1968 tprintf("Bin 0 Range: %u, ", trans
->bin_0_range
);
1970 if(!subelements(pkt
,
1971 meas_req
->len
- 3 - sizeof(*trans
)))
1974 else if(meas_req
->type
== 10) {
1975 struct element_meas_mcast_diag
*mcast
;
1977 mcast
= (struct element_meas_mcast_diag
*)
1978 pkt_pull(pkt
, sizeof(*mcast
));
1982 if ((meas_req
->len
- 3 - sizeof(*mcast
)) >= 0) {
1983 tprintf("Length of Req matchs not Type %u",
1988 tprintf("Rand Intv: %fs, ",
1989 le16_to_cpu(mcast
->rand_intv
) * TU
);
1990 tprintf("Meas Duration: %fs",
1991 le16_to_cpu(mcast
->dur
) * TU
);
1992 tprintf("Group MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1993 mcast
->group_mac
[0], mcast
->group_mac
[1],
1994 mcast
->group_mac
[2], mcast
->group_mac
[3],
1995 mcast
->group_mac
[4], mcast
->group_mac
[5]);
1997 if(!subelements(pkt
,
1998 meas_req
->len
- 3 - sizeof(*mcast
)))
2001 else if(meas_req
->type
== 11) {
2002 struct element_meas_loc_civic
*civic
;
2004 civic
= (struct element_meas_loc_civic
*)
2005 pkt_pull(pkt
, sizeof(*civic
));
2009 if ((meas_req
->len
- 3 - sizeof(*civic
)) >= 0) {
2010 tprintf("Length of Req matchs not Type %u",
2015 tprintf("Location Subj: %u, ", civic
->loc_subj
);
2016 tprintf("Type: %u, ", civic
->civic_loc
);
2017 tprintf("Srv Intv Units: %u, ",
2018 le16_to_cpu(civic
->loc_srv_intv_unit
));
2019 tprintf("Srv Intv: %u, ", civic
->loc_srv_intv
);
2021 if(!subelements(pkt
,
2022 meas_req
->len
- 3 - sizeof(*civic
)))
2025 else if(meas_req
->type
== 12) {
2026 struct element_meas_loc_id
*id
;
2028 id
= (struct element_meas_loc_id
*)
2029 pkt_pull(pkt
, sizeof(*id
));
2033 if ((meas_req
->len
- 3 - sizeof(*id
)) >= 0) {
2034 tprintf("Length of Req matchs not Type %u",
2039 tprintf("Location Subj: %u, ", id
->loc_subj
);
2040 tprintf("Srv Intv Units: %u, ",
2041 le16_to_cpu(id
->loc_srv_intv_unit
));
2042 tprintf("Srv Intv: %u", id
->loc_srv_intv
);
2044 if(!subelements(pkt
,
2045 meas_req
->len
- 3 - sizeof(*id
)))
2048 else if(meas_req
->type
== 255) {
2049 struct element_meas_pause
*pause
;
2051 pause
= (struct element_meas_pause
*)
2052 pkt_pull(pkt
, sizeof(*pause
));
2056 if ((meas_req
->len
- 3 - sizeof(*pause
)) >= 0) {
2057 tprintf("Length of Req matchs not Type %u",
2062 tprintf("Pause Time: %fs, ", pause
->time
* 10 * TU
);
2064 if(!subelements(pkt
,
2065 meas_req
->len
- 3 - sizeof(*pause
)))
2069 tprintf("Length field indicates data,"
2070 " but could not interpreted");
2078 static int8_t inf_meas_rep(struct pkt_buff
*pkt
, u8
*id
)
2080 struct element_meas_rep
*meas_rep
;
2082 meas_rep
= (struct element_meas_rep
*) pkt_pull(pkt
, sizeof(*meas_rep
));
2083 if (meas_rep
== NULL
)
2086 tprintf("Measurement Rep (%u, Len(%u)): ", *id
, meas_rep
->len
);
2087 if (len_lt_error(meas_rep
->len
, 3))
2090 tprintf("Token: %u, ", meas_rep
->token
);
2091 tprintf("Rep Mode: 0x%x (Late (%u), Incapable(%u), Refused(%u), ",
2092 meas_rep
->rep_mode
, meas_rep
->rep_mode
>> 7,
2093 (meas_rep
->rep_mode
>> 6) & 0x1,
2094 (meas_rep
->rep_mode
>> 5) & 0x1);
2095 tprintf("Type: %s (%u), ", meas_type(meas_rep
->type
), meas_rep
->type
);
2097 if(meas_rep
->len
> 3) {
2098 if(meas_rep
->type
== 0) {
2099 struct element_meas_basic
*basic
;
2101 basic
= (struct element_meas_basic
*)
2102 pkt_pull(pkt
, sizeof(*basic
));
2106 if (!(meas_rep
->len
- 3 - sizeof(*basic
))) {
2107 tprintf("Length of Req matchs not Type %u",
2112 tprintf("Ch Nr: %uus, ", basic
->ch_nr
);
2113 tprintf("Meas Start Time: %lu, ",
2114 le64_to_cpu(basic
->start
));
2115 tprintf("Meas Duration: %fs",
2116 le16_to_cpu(basic
->dur
) * TU
);
2119 else if(meas_rep
->type
== 1) {
2120 struct element_meas_cca
*cca
;
2122 cca
= (struct element_meas_cca
*)
2123 pkt_pull(pkt
, sizeof(*cca
));
2127 if (!(meas_rep
->len
- 3 - sizeof(*cca
))) {
2128 tprintf("Length of Req matchs not Type %u",
2133 tprintf("Ch Nr: %uus, ", cca
->ch_nr
);
2134 tprintf("Meas Start Time: %lu, ",
2135 le64_to_cpu(cca
->start
));
2136 tprintf("Meas Duration: %fs",
2137 le16_to_cpu(cca
->dur
) * TU
);
2139 else if(meas_rep
->type
== 2) {
2140 struct element_meas_rpi
*rpi
;
2142 rpi
= (struct element_meas_rpi
*)
2143 pkt_pull(pkt
, sizeof(*rpi
));
2147 if (!(meas_rep
->len
- 3 - sizeof(*rpi
))) {
2148 tprintf("Length of Req matchs not Type %u",
2153 tprintf("Ch Nr: %uus, ", rpi
->ch_nr
);
2154 tprintf("Meas Start Time: %lu, ",
2155 le64_to_cpu(rpi
->start
));
2156 tprintf("Meas Duration: %fs",
2157 le16_to_cpu(rpi
->dur
) * TU
);
2159 else if(meas_rep
->type
== 3) {
2160 struct element_meas_ch_load
*ch_load
;
2162 ch_load
= (struct element_meas_ch_load
*)
2163 pkt_pull(pkt
, sizeof(*ch_load
));
2164 if (ch_load
== NULL
)
2167 if ((meas_rep
->len
- 3 - sizeof(*ch_load
)) >= 0) {
2168 tprintf("Length of Req matchs not Type %u",
2173 tprintf("OP Class: %u, ", ch_load
->op_class
);
2174 tprintf("Ch Nr: %u, ", ch_load
->ch_nr
);
2175 tprintf("Rand Intv: %fs, ",
2176 le16_to_cpu(ch_load
->rand_intv
) * TU
);
2177 tprintf("Meas Duration: %fs",
2178 le16_to_cpu(ch_load
->dur
) * TU
);
2180 if(!subelements(pkt
,
2181 meas_rep
->len
- 3 - sizeof(*ch_load
)))
2184 else if(meas_rep
->type
== 4) {
2185 struct element_meas_noise
*noise
;
2187 noise
= (struct element_meas_noise
*)
2188 pkt_pull(pkt
, sizeof(*noise
));
2192 if ((meas_rep
->len
- 3 - sizeof(*noise
)) >= 0) {
2193 tprintf("Length of Req matchs not Type %u",
2198 tprintf("OP Class: %u, ", noise
->op_class
);
2199 tprintf("Ch Nr: %u, ", noise
->ch_nr
);
2200 tprintf("Rand Intv: %fs, ",
2201 le16_to_cpu(noise
->rand_intv
) * TU
);
2202 tprintf("Meas Duration: %fs",
2203 le16_to_cpu(noise
->dur
) * TU
);
2205 if(!subelements(pkt
,
2206 meas_rep
->len
- 3 - sizeof(*noise
)))
2209 else if(meas_rep
->type
== 5) {
2210 struct element_meas_beacon
*beacon
;
2212 beacon
= (struct element_meas_beacon
*)
2213 pkt_pull(pkt
, sizeof(*beacon
));
2217 if ((meas_rep
->len
- 3 - sizeof(*beacon
)) >= 0) {
2218 tprintf("Length of Req matchs not Type %u",
2223 tprintf("OP Class: %u, ", beacon
->op_class
);
2224 tprintf("Ch Nr: %u, ", beacon
->ch_nr
);
2225 tprintf("Rand Intv: %fs, ",
2226 le16_to_cpu(beacon
->rand_intv
) * TU
);
2227 tprintf("Meas Duration: %fs",
2228 le16_to_cpu(beacon
->dur
) * TU
);
2229 tprintf("Mode: %u, ", beacon
->mode
);
2230 tprintf("BSSID: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2231 beacon
->bssid
[0], beacon
->bssid
[1],
2232 beacon
->bssid
[2], beacon
->bssid
[3],
2233 beacon
->bssid
[4], beacon
->bssid
[5]);
2235 if(!subelements(pkt
,
2236 meas_rep
->len
- 3 - sizeof(*beacon
)))
2239 else if(meas_rep
->type
== 6) {
2240 struct element_meas_frame
*frame
;
2242 frame
= (struct element_meas_frame
*)
2243 pkt_pull(pkt
, sizeof(*frame
));
2247 if ((meas_rep
->len
- 3 - sizeof(*frame
)) >= 0) {
2248 tprintf("Length of Req matchs not Type %u",
2253 tprintf("OP Class: %u, ", frame
->op_class
);
2254 tprintf("Ch Nr: %u, ", frame
->ch_nr
);
2255 tprintf("Rand Intv: %fs, ",
2256 le16_to_cpu(frame
->rand_intv
) * TU
);
2257 tprintf("Meas Duration: %fs",
2258 le16_to_cpu(frame
->dur
) * TU
);
2259 tprintf("Request Type: %u, ", frame
->frame
);
2260 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2261 frame
->mac
[0], frame
->mac
[1],
2262 frame
->mac
[2], frame
->mac
[3],
2263 frame
->mac
[4], frame
->mac
[5]);
2265 if(!subelements(pkt
,
2266 meas_rep
->len
- 3 - sizeof(*frame
)))
2269 else if(meas_rep
->type
== 7) {
2270 struct element_meas_sta
*sta
;
2272 sta
= (struct element_meas_sta
*)
2273 pkt_pull(pkt
, sizeof(*sta
));
2277 if ((meas_rep
->len
- 3 - sizeof(*sta
)) >= 0) {
2278 tprintf("Length of Req matchs not Type %u",
2283 tprintf("Peer MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2284 sta
->peer_mac
[0], sta
->peer_mac
[1],
2285 sta
->peer_mac
[2], sta
->peer_mac
[3],
2286 sta
->peer_mac
[4], sta
->peer_mac
[5]);
2287 tprintf("Rand Intv: %fs, ",
2288 le16_to_cpu(sta
->rand_intv
) * TU
);
2289 tprintf("Meas Duration: %fs",
2290 le16_to_cpu(sta
->dur
) * TU
);
2291 tprintf("Group ID: %u, ", sta
->group_id
);
2293 if(!subelements(pkt
,
2294 meas_rep
->len
- 3 - sizeof(*sta
)))
2297 else if(meas_rep
->type
== 8) {
2298 struct element_meas_lci
*lci
;
2300 lci
= (struct element_meas_lci
*)
2301 pkt_pull(pkt
, sizeof(*lci
));
2305 if ((meas_rep
->len
- 3 - sizeof(*lci
)) >= 0) {
2306 tprintf("Length of Req matchs not Type %u",
2311 tprintf("Location Subj: %u, ", lci
->loc_subj
);
2312 tprintf("Latitude Req Res: %udeg",
2313 lci
->latitude_req_res
);
2314 tprintf("Longitude Req Res: %udeg",
2315 lci
->longitude_req_res
);
2316 tprintf("Altitude Req Res: %udeg",
2317 lci
->altitude_req_res
);
2319 if(!subelements(pkt
,
2320 meas_rep
->len
- 3 - sizeof(*lci
)))
2323 else if(meas_rep
->type
== 9) {
2324 struct element_meas_trans_str_cat
*trans
;
2326 trans
= (struct element_meas_trans_str_cat
*)
2327 pkt_pull(pkt
, sizeof(*trans
));
2331 if ((meas_rep
->len
- 3 - sizeof(*trans
)) >= 0) {
2332 tprintf("Length of Req matchs not Type %u",
2337 tprintf("Rand Intv: %fs, ",
2338 le16_to_cpu(trans
->rand_intv
) * TU
);
2339 tprintf("Meas Duration: %fs",
2340 le16_to_cpu(trans
->dur
) * TU
);
2341 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2342 trans
->peer_sta_addr
[0], trans
->peer_sta_addr
[1],
2343 trans
->peer_sta_addr
[2], trans
->peer_sta_addr
[3],
2344 trans
->peer_sta_addr
[4], trans
->peer_sta_addr
[5]);
2345 tprintf("Traffic ID: %u, ", trans
->traffic_id
);
2346 tprintf("Bin 0 Range: %u, ", trans
->bin_0_range
);
2348 if(!subelements(pkt
,
2349 meas_rep
->len
- 3 - sizeof(*trans
)))
2352 else if(meas_rep
->type
== 10) {
2353 struct element_meas_mcast_diag
*mcast
;
2355 mcast
= (struct element_meas_mcast_diag
*)
2356 pkt_pull(pkt
, sizeof(*mcast
));
2360 if ((meas_rep
->len
- 3 - sizeof(*mcast
)) >= 0) {
2361 tprintf("Length of Req matchs not Type %u",
2366 tprintf("Rand Intv: %fs, ",
2367 le16_to_cpu(mcast
->rand_intv
) * TU
);
2368 tprintf("Meas Duration: %fs",
2369 le16_to_cpu(mcast
->dur
) * TU
);
2370 tprintf("Group MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2371 mcast
->group_mac
[0], mcast
->group_mac
[1],
2372 mcast
->group_mac
[2], mcast
->group_mac
[3],
2373 mcast
->group_mac
[4], mcast
->group_mac
[5]);
2375 if(!subelements(pkt
,
2376 meas_rep
->len
- 3 - sizeof(*mcast
)))
2379 else if(meas_rep
->type
== 11) {
2380 struct element_meas_loc_civic
*civic
;
2382 civic
= (struct element_meas_loc_civic
*)
2383 pkt_pull(pkt
, sizeof(*civic
));
2387 if ((meas_rep
->len
- 3 - sizeof(*civic
)) >= 0) {
2388 tprintf("Length of Req matchs not Type %u",
2393 tprintf("Location Subj: %u, ", civic
->loc_subj
);
2394 tprintf("Type: %u, ", civic
->civic_loc
);
2395 tprintf("Srv Intv Units: %u, ",
2396 le16_to_cpu(civic
->loc_srv_intv_unit
));
2397 tprintf("Srv Intv: %u, ", civic
->loc_srv_intv
);
2399 if(!subelements(pkt
,
2400 meas_rep
->len
- 3 - sizeof(*civic
)))
2403 else if(meas_rep
->type
== 12) {
2404 struct element_meas_loc_id
*id
;
2406 id
= (struct element_meas_loc_id
*)
2407 pkt_pull(pkt
, sizeof(*id
));
2411 if ((meas_rep
->len
- 3 - sizeof(*id
)) >= 0) {
2412 tprintf("Length of Req matchs not Type %u",
2417 tprintf("Location Subj: %u, ", id
->loc_subj
);
2418 tprintf("Srv Intv Units: %u, ",
2419 le16_to_cpu(id
->loc_srv_intv_unit
));
2420 tprintf("Srv Intv: %u", id
->loc_srv_intv
);
2422 if(!subelements(pkt
,
2423 meas_rep
->len
- 3 - sizeof(*id
)))
2427 tprintf("Length field indicates data,"
2428 " but could not interpreted");
2436 static int8_t inf_quiet(struct pkt_buff
*pkt
, u8
*id
)
2438 struct element_quiet
*quiet
;
2440 quiet
= (struct element_quiet
*) pkt_pull(pkt
, sizeof(*quiet
));
2444 tprintf("Quit (%u, Len(%u)): ", *id
, quiet
->len
);
2445 if (len_neq_error(quiet
->len
, 6))
2448 tprintf("Count: %ud, ", quiet
->cnt
);
2449 tprintf("Period: %u, ", quiet
->period
);
2450 tprintf("Duration: %fs, ", le16_to_cpu(quiet
->dur
) * TU
);
2451 tprintf("Offs: %fs", le16_to_cpu(quiet
->offs
) * TU
);
2457 static int8_t inf_ibss_dfs(struct pkt_buff
*pkt
, u8
*id
)
2459 struct element_ibss_dfs
*ibss_dfs
;
2462 ibss_dfs
= (struct element_ibss_dfs
*) pkt_pull(pkt
, sizeof(*ibss_dfs
));
2463 if (ibss_dfs
== NULL
)
2466 tprintf("IBSS DFS (%u, Len(%u)): ", *id
, ibss_dfs
->len
);
2467 if (len_lt_error(ibss_dfs
->len
, 7))
2470 tprintf("Owner: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2471 ibss_dfs
->owner
[0], ibss_dfs
->owner
[1],
2472 ibss_dfs
->owner
[2], ibss_dfs
->owner
[3],
2473 ibss_dfs
->owner
[4], ibss_dfs
->owner
[5]);
2474 tprintf("Recovery Intv: %u, ", ibss_dfs
->rec_intv
);
2476 if((ibss_dfs
->len
- sizeof(*ibss_dfs
) + 1) & 1) {
2477 tprintf("Length of Channel Map should be modulo 2");
2481 for (i
= 0; i
< ibss_dfs
->len
; i
+= 2) {
2482 struct element_ibss_dfs_tuple
*ibss_dfs_tuple
;
2484 ibss_dfs_tuple
= (struct element_ibss_dfs_tuple
*)
2485 pkt_pull(pkt
, sizeof(*ibss_dfs_tuple
));
2486 if (ibss_dfs_tuple
== NULL
)
2489 tprintf("Channel Nr: %u, ", ibss_dfs_tuple
->ch_nr
);
2490 tprintf("Map: %u, ", ibss_dfs_tuple
->map
);
2496 static int8_t inf_erp(struct pkt_buff
*pkt
, u8
*id
)
2498 struct element_erp
*erp
;
2500 erp
= (struct element_erp
*) pkt_pull(pkt
, sizeof(*erp
));
2504 tprintf("ERP (%u, Len(%u)): ", *id
, erp
->len
);
2505 if (len_neq_error(erp
->len
, 1))
2507 tprintf("Non ERP Present (%u), ", erp
->param
& 0x1);
2508 tprintf("Use Protection (%u), ", (erp
->param
>> 1) & 0x1);
2509 tprintf("Barker Preamble Mode (%u), ", (erp
->param
>> 2) & 0x1);
2510 tprintf("Reserved (0x%.5x)", erp
->param
>> 3);
2515 static int8_t inf_ts_del(struct pkt_buff
*pkt
, u8
*id
)
2517 struct element_ts_del
*ts_del
;
2519 ts_del
= (struct element_ts_del
*) pkt_pull(pkt
, sizeof(*ts_del
));
2523 tprintf("TS Delay (%u, Len(%u)): ", *id
, ts_del
->len
);
2524 if (len_neq_error(ts_del
->len
, 4))
2526 tprintf("Delay (%fs)", le32_to_cpu(ts_del
->delay
) * TU
);
2531 static int8_t inf_tclas_proc(struct pkt_buff
*pkt
, u8
*id
)
2533 struct element_tclas_proc
*tclas_proc
;
2535 tclas_proc
= (struct element_tclas_proc
*)
2536 pkt_pull(pkt
, sizeof(*tclas_proc
));
2537 if (tclas_proc
== NULL
)
2540 tprintf("TCLAS Procesing (%u, Len(%u)): ", *id
, tclas_proc
->len
);
2541 if (len_neq_error(tclas_proc
->len
, 1))
2543 tprintf("Processing (%u)", tclas_proc
->proc
);
2548 static int8_t inf_ht_cap(struct pkt_buff
*pkt
, u8
*id
)
2550 struct element_ht_cap
*ht_cap
;
2551 u32 tx_param_res
, beam_cap
;
2554 ht_cap
= (struct element_ht_cap
*)
2555 pkt_pull(pkt
, sizeof(*ht_cap
));
2559 tx_param_res
= le32_to_cpu(ht_cap
->tx_param_res
);
2560 beam_cap
= le32_to_cpu(ht_cap
->beam_cap
);
2561 ext_cap
= le16_to_cpu(ht_cap
->ext_cap
);
2563 tprintf("HT Capabilities (%u, Len(%u)): ", *id
, ht_cap
->len
);
2564 if (len_neq_error(ht_cap
->len
, 26))
2566 tprintf("Info (LDCP Cod Cap (%u), Supp Ch Width Set (%u),"
2567 " SM Pwr Save(%u), HT-Greenfield (%u), Short GI for 20/40 MHz"
2568 " (%u/%u), Tx/Rx STBC (%u/%u), HT-Delayed Block Ack (%u),"
2569 " Max A-MSDU Len (%u), DSSS/CCK Mode in 40 MHz (%u),"
2570 " Res (0x%x), Forty MHz Intol (%u), L-SIG TXOP Protection Supp"
2571 " (%u)), ", ht_cap
->ldpc
, ht_cap
->supp_width
,
2572 ht_cap
->sm_pwr
, ht_cap
->ht_green
, ht_cap
->gi_20mhz
,
2573 ht_cap
->gi_40mhz
, ht_cap
->tx_stbc
, ht_cap
->rx_stbc
,
2574 ht_cap
->ht_ack
, ht_cap
->max_msdu_length
, ht_cap
->dsss_ck_mode
,
2575 ht_cap
->res
, ht_cap
->forty_int
, ht_cap
->prot_supp
);
2576 tprintf("A-MPDU Params (Max Len Exp (%u), Min Start Spacing (%u),"
2577 " Res (0x%x)), ", ht_cap
->param
>> 6, (ht_cap
->param
>> 3) & 0x7,
2578 ht_cap
->param
& 0x07);
2579 tprintf("Supp MCS Set (Rx MCS Bitmask (0x%x%x%x%x%x%x%x%x%x%x),"
2580 " Res (0x%x), Rx High Supp Data Rate (%u), Res (0x%x),"
2581 " Tx MCS Set Def (%u), Tx Rx MCS Set Not Eq (%u),"
2582 " Tx Max Number Spat Str Supp (%u),"
2583 " Tx Uneq Mod Supp (%u), Res (0x%x)), ",
2584 ht_cap
->bitmask1
, ht_cap
->bitmask2
, ht_cap
->bitmask3
,
2585 ht_cap
->bitmask4
, ht_cap
->bitmask5
, ht_cap
->bitmask6
,
2586 ht_cap
->bitmask7
, ht_cap
->bitmask8
, ht_cap
->bitmask9
,
2587 ht_cap
->bitmask10_res
>> 3, ht_cap
->bitmask10_res
& 0x7,
2588 le16_to_cpu(ht_cap
->supp_rate_res
) >> 6,
2589 le16_to_cpu(ht_cap
->supp_rate_res
) & 0x3F,
2590 tx_param_res
>> 31, (tx_param_res
>> 30) & 1,
2591 (tx_param_res
>> 28) & 3, (tx_param_res
>> 27) & 1,
2592 tx_param_res
& 0x7FFFFFF);
2593 tprintf("Ext Cap (PCO (%u), PCO Trans Time (%u), Res (0x%x),"
2594 " MCS Feedb (%u), +HTC Supp (%u), RD Resp (%u), Res (0x%x)), ",
2595 ext_cap
>> 15, (ext_cap
>> 13) & 3, (ext_cap
>> 8) & 0x1F,
2596 (ext_cap
>> 6) & 3, (ext_cap
>> 5) & 1, (ext_cap
>> 4) & 1,
2598 tprintf("Transm Beamf (Impl Transm Beamf Rec Cap (%u),"
2599 " Rec/Transm Stagg Sound Cap (%u/%u),"
2600 " Rec/Trans NDP Cap (%u/%u), Impl Transm Beamf Cap (%u),"
2601 " Cal (%u), Expl CSI Transm Beamf Cap (%u),"
2602 " Expl Noncmpr/Compr Steering Cap (%u/%u),"
2603 " Expl Trans Beamf CSI Feedb (%u),"
2604 " Expl Noncmpr/Cmpr Feedb Cap (%u/%u),"
2605 " Min Grpg (%u), CSI Num Beamf Ant Supp (%u),"
2606 " Noncmpr/Cmpr Steering Nr Beamf Ant Supp (%u/%u),"
2607 " CSI Max Nr Rows Beamf Supp (%u),"
2608 " Ch Estim Cap (%u), Res (0x%x)), ",
2609 beam_cap
>> 31, (beam_cap
>> 30) & 1, (beam_cap
>> 29) & 1,
2610 (beam_cap
>> 28) & 1, (beam_cap
>> 27) & 1, (beam_cap
>> 26) & 1,
2611 (beam_cap
>> 24) & 3, (beam_cap
>> 23) & 1, (beam_cap
>> 22) & 1,
2612 (beam_cap
>> 21) & 1, (beam_cap
>> 19) & 3, (beam_cap
>> 17) & 3,
2613 (beam_cap
>> 15) & 3, (beam_cap
>> 13) & 3, (beam_cap
>> 11) & 3,
2614 (beam_cap
>> 9) & 3, (beam_cap
>> 7) & 3, (beam_cap
>> 5) & 3,
2615 (beam_cap
>> 3) & 3, beam_cap
& 7);
2616 tprintf("ASEL (Ant Select Cap (%u),"
2617 " Expl CSI Feedb Based Transm ASEL Cap (%u),"
2618 " Ant Indic Feedb Based Transm ASEL Cap (%u),"
2619 " Expl CSI Feedb Cap (%u), Ant Indic Feedb Cap (%u),"
2620 " Rec ASEL Cap (%u), Transm Sound PPDUs Cap (%u), Res (0x%x))",
2621 ht_cap
->asel_cap
>> 7, (ht_cap
->asel_cap
>> 6) & 1,
2622 (ht_cap
->asel_cap
>> 5) & 1, (ht_cap
->asel_cap
>> 4) & 1,
2623 (ht_cap
->asel_cap
>> 3) & 1, (ht_cap
->asel_cap
>> 2) & 1,
2624 (ht_cap
->asel_cap
>> 1) & 1, ht_cap
->asel_cap
& 1);
2629 static int8_t inf_qos_cap(struct pkt_buff
*pkt
, u8
*id
)
2631 struct element_qos_cap
*qos_cap
;
2633 qos_cap
= (struct element_qos_cap
*)
2634 pkt_pull(pkt
, sizeof(*qos_cap
));
2635 if (qos_cap
== NULL
)
2638 tprintf("QoS Capabilities (%u, Len(%u)): ", *id
, qos_cap
->len
);
2639 if (len_neq_error(qos_cap
->len
, 1))
2642 tprintf("Info (0x%x)", qos_cap
->info
);
2647 static int8_t inf_rsn(struct pkt_buff
*pkt
, u8
*id
)
2652 static int8_t inf_ext_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
2656 struct element_ext_supp_rates
*ext_supp_rates
;
2658 ext_supp_rates
= (struct element_ext_supp_rates
*)
2659 pkt_pull(pkt
, sizeof(*ext_supp_rates
));
2660 if (ext_supp_rates
== NULL
)
2663 tprintf("Ext Support Rates (%u, Len(%u)): ", *id
, ext_supp_rates
->len
);
2665 if ((ext_supp_rates
->len
- sizeof(*ext_supp_rates
) + 1) > 0) {
2666 rates
= pkt_pull(pkt
, ext_supp_rates
->len
);
2670 for (i
= 0; i
< ext_supp_rates
->len
; i
++)
2671 tprintf("%g ", (rates
[i
] & 0x80) ?
2672 ((rates
[i
] & 0x3f) * 0.5) :
2673 data_rates(rates
[i
]));
2680 static int8_t inf_ap_ch_exp(struct pkt_buff
*pkt
, u8
*id
) {
2684 static int8_t inf_neighb_rep(struct pkt_buff
*pkt
, u8
*id
) {
2688 static int8_t inf_rcpi(struct pkt_buff
*pkt
, u8
*id
) {
2692 static int8_t inf_mde(struct pkt_buff
*pkt
, u8
*id
) {
2696 static int8_t inf_fte(struct pkt_buff
*pkt
, u8
*id
) {
2700 static int8_t inf_time_out_int(struct pkt_buff
*pkt
, u8
*id
) {
2704 static int8_t inf_rde(struct pkt_buff
*pkt
, u8
*id
) {
2708 static int8_t inf_dse_reg_loc(struct pkt_buff
*pkt
, u8
*id
) {
2712 static int8_t inf_supp_op_class(struct pkt_buff
*pkt
, u8
*id
) {
2716 static int8_t inf_ext_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
) {
2720 static int8_t inf_ht_op(struct pkt_buff
*pkt
, u8
*id
) {
2724 static int8_t inf_sec_ch_offs(struct pkt_buff
*pkt
, u8
*id
) {
2728 static int8_t inf_bss_avg_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
2732 static int8_t inf_ant(struct pkt_buff
*pkt
, u8
*id
) {
2736 static int8_t inf_rsni(struct pkt_buff
*pkt
, u8
*id
) {
2740 static int8_t inf_meas_pilot_trans(struct pkt_buff
*pkt
, u8
*id
) {
2744 static int8_t inf_bss_avl_adm_cap(struct pkt_buff
*pkt
, u8
*id
) {
2748 static int8_t inf_bss_ac_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
2752 static int8_t inf_time_adv(struct pkt_buff
*pkt
, u8
*id
) {
2756 static int8_t inf_rm_ena_cap(struct pkt_buff
*pkt
, u8
*id
) {
2760 static int8_t inf_mult_bssid(struct pkt_buff
*pkt
, u8
*id
) {
2764 static int8_t inf_20_40_bss_coex(struct pkt_buff
*pkt
, u8
*id
) {
2768 static int8_t inf_20_40_bss_int_ch_rep(struct pkt_buff
*pkt
, u8
*id
) {
2772 static int8_t inf_overl_bss_scan_para(struct pkt_buff
*pkt
, u8
*id
) {
2776 static int8_t inf_ric_desc(struct pkt_buff
*pkt
, u8
*id
) {
2780 static int8_t inf_mgmt_mic(struct pkt_buff
*pkt
, u8
*id
) {
2784 static int8_t inf_ev_req(struct pkt_buff
*pkt
, u8
*id
) {
2788 static int8_t inf_ev_rep(struct pkt_buff
*pkt
, u8
*id
) {
2792 static int8_t inf_diagn_req(struct pkt_buff
*pkt
, u8
*id
) {
2796 static int8_t inf_diagn_rep(struct pkt_buff
*pkt
, u8
*id
) {
2800 static int8_t inf_loc_para(struct pkt_buff
*pkt
, u8
*id
) {
2804 static int8_t inf_nontr_bssid_cap(struct pkt_buff
*pkt
, u8
*id
) {
2808 static int8_t inf_ssid_list(struct pkt_buff
*pkt
, u8
*id
) {
2812 static int8_t inf_mult_bssid_index(struct pkt_buff
*pkt
, u8
*id
) {
2816 static int8_t inf_fms_desc(struct pkt_buff
*pkt
, u8
*id
) {
2820 static int8_t inf_fms_req(struct pkt_buff
*pkt
, u8
*id
) {
2824 static int8_t inf_fms_resp(struct pkt_buff
*pkt
, u8
*id
) {
2828 static int8_t inf_qos_tfc_cap(struct pkt_buff
*pkt
, u8
*id
) {
2832 static int8_t inf_bss_max_idle_per(struct pkt_buff
*pkt
, u8
*id
) {
2836 static int8_t inf_tfs_req(struct pkt_buff
*pkt
, u8
*id
) {
2840 static int8_t inf_tfs_resp(struct pkt_buff
*pkt
, u8
*id
) {
2844 static int8_t inf_wnm_sleep_mod(struct pkt_buff
*pkt
, u8
*id
) {
2848 static int8_t inf_tim_bcst_req(struct pkt_buff
*pkt
, u8
*id
) {
2852 static int8_t inf_tim_bcst_resp(struct pkt_buff
*pkt
, u8
*id
) {
2856 static int8_t inf_coll_interf_rep(struct pkt_buff
*pkt
, u8
*id
) {
2860 static int8_t inf_ch_usage(struct pkt_buff
*pkt
, u8
*id
) {
2864 static int8_t inf_time_zone(struct pkt_buff
*pkt
, u8
*id
) {
2868 static int8_t inf_dms_req(struct pkt_buff
*pkt
, u8
*id
) {
2872 static int8_t inf_dms_resp(struct pkt_buff
*pkt
, u8
*id
) {
2876 static int8_t inf_link_id(struct pkt_buff
*pkt
, u8
*id
) {
2880 static int8_t inf_wakeup_sched(struct pkt_buff
*pkt
, u8
*id
) {
2884 static int8_t inf_ch_sw_timing(struct pkt_buff
*pkt
, u8
*id
) {
2888 static int8_t inf_pti_ctrl(struct pkt_buff
*pkt
, u8
*id
) {
2892 static int8_t inf_tpu_buff_status(struct pkt_buff
*pkt
, u8
*id
) {
2896 static int8_t inf_interw(struct pkt_buff
*pkt
, u8
*id
) {
2900 static int8_t inf_adv_proto(struct pkt_buff
*pkt
, u8
*id
) {
2904 static int8_t inf_exp_bandw_req(struct pkt_buff
*pkt
, u8
*id
) {
2908 static int8_t inf_qos_map_set(struct pkt_buff
*pkt
, u8
*id
) {
2912 static int8_t inf_roam_cons(struct pkt_buff
*pkt
, u8
*id
) {
2916 static int8_t inf_emer_alert_id(struct pkt_buff
*pkt
, u8
*id
) {
2920 static int8_t inf_mesh_conf(struct pkt_buff
*pkt
, u8
*id
) {
2924 static int8_t inf_mesh_id(struct pkt_buff
*pkt
, u8
*id
) {
2928 static int8_t inf_mesh_link_metr_rep(struct pkt_buff
*pkt
, u8
*id
) {
2932 static int8_t inf_cong_notif(struct pkt_buff
*pkt
, u8
*id
) {
2936 static int8_t inf_mesh_peer_mgmt(struct pkt_buff
*pkt
, u8
*id
) {
2940 static int8_t inf_mesh_ch_sw_para(struct pkt_buff
*pkt
, u8
*id
) {
2944 static int8_t inf_mesh_awake_win(struct pkt_buff
*pkt
, u8
*id
) {
2948 static int8_t inf_beacon_timing(struct pkt_buff
*pkt
, u8
*id
) {
2952 static int8_t inf_mccaop_setup_req(struct pkt_buff
*pkt
, u8
*id
) {
2956 static int8_t inf_mccaop_setup_rep(struct pkt_buff
*pkt
, u8
*id
) {
2960 static int8_t inf_mccaop_adv(struct pkt_buff
*pkt
, u8
*id
) {
2964 static int8_t inf_mccaop_teardwn(struct pkt_buff
*pkt
, u8
*id
) {
2968 static int8_t inf_gann(struct pkt_buff
*pkt
, u8
*id
) {
2972 static int8_t inf_rann(struct pkt_buff
*pkt
, u8
*id
) {
2976 static int8_t inf_ext_cap(struct pkt_buff
*pkt
, u8
*id
) {
2980 static int8_t inf_preq(struct pkt_buff
*pkt
, u8
*id
) {
2984 static int8_t inf_prep(struct pkt_buff
*pkt
, u8
*id
) {
2988 static int8_t inf_perr(struct pkt_buff
*pkt
, u8
*id
) {
2992 static int8_t inf_pxu(struct pkt_buff
*pkt
, u8
*id
) {
2996 static int8_t inf_pxuc(struct pkt_buff
*pkt
, u8
*id
) {
3000 static int8_t inf_auth_mesh_peer_exch(struct pkt_buff
*pkt
, u8
*id
) {
3004 static int8_t inf_mic(struct pkt_buff
*pkt
, u8
*id
) {
3008 static int8_t inf_dest_uri(struct pkt_buff
*pkt
, u8
*id
) {
3012 static int8_t inf_u_apsd_coex(struct pkt_buff
*pkt
, u8
*id
) {
3016 static int8_t inf_mccaop_adv_overv(struct pkt_buff
*pkt
, u8
*id
) {
3020 static int8_t inf_vend_spec(struct pkt_buff
*pkt
, u8
*id
)
3024 struct element_vend_spec
*vend_spec
;
3026 vend_spec
= (struct element_vend_spec
*)
3027 pkt_pull(pkt
, sizeof(*vend_spec
));
3028 if (vend_spec
== NULL
)
3031 tprintf("Vendor Specific (%u, Len (%u)): ", *id
, vend_spec
->len
);
3033 data
= pkt_pull(pkt
, vend_spec
->len
);
3038 for (i
= 0; i
< vend_spec
->len
; i
++)
3039 tprintf("%.2x", data
[i
]);
3044 static int8_t inf_elements(struct pkt_buff
*pkt
)
3046 u8
*id
= pkt_pull(pkt
, 1);
3051 case 0: return inf_ssid(pkt
, id
);
3052 case 1: return inf_supp_rates(pkt
, id
);
3053 case 2: return inf_fh_ps(pkt
, id
);
3054 case 3: return inf_dsss_ps(pkt
, id
);
3055 case 4: return inf_cf_ps(pkt
, id
);
3056 case 5: return inf_tim(pkt
, id
);
3057 case 6: return inf_ibss_ps(pkt
, id
);
3058 case 7: return inf_country(pkt
, id
);
3059 case 8: return inf_hop_pp(pkt
, id
);
3060 case 9: return inf_hop_pt(pkt
, id
);
3061 case 10: return inf_req(pkt
, id
);
3062 case 11: return inf_bss_load(pkt
, id
);
3063 case 12: return inf_edca_ps(pkt
, id
);
3064 case 13: return inf_tspec(pkt
, id
);
3065 case 14: return inf_tclas(pkt
, id
);
3066 case 15: return inf_sched(pkt
, id
);
3067 case 16: return inf_chall_txt(pkt
, id
);
3068 case 17 ... 31: return inf_reserved(pkt
, id
);
3069 case 32: return inf_pwr_constr(pkt
, id
);
3070 case 33: return inf_pwr_cap(pkt
, id
);
3071 case 34: return inf_tpc_req(pkt
, id
);
3072 case 35: return inf_tpc_rep(pkt
, id
);
3073 case 36: return inf_supp_ch(pkt
, id
);
3074 case 37: return inf_ch_sw_ann(pkt
, id
);
3075 case 38: return inf_meas_req(pkt
, id
);
3076 case 39: return inf_meas_rep(pkt
, id
);
3077 case 40: return inf_quiet(pkt
, id
);
3078 case 41: return inf_ibss_dfs(pkt
, id
);
3079 case 42: return inf_erp(pkt
, id
);
3080 case 43: return inf_ts_del(pkt
, id
);
3081 case 44: return inf_tclas_proc(pkt
, id
);
3082 case 45: return inf_ht_cap(pkt
, id
);
3083 case 46: return inf_qos_cap(pkt
, id
);
3084 case 47: return inf_reserved(pkt
, id
);
3085 case 48: return inf_rsn(pkt
, id
);
3086 case 49: return inf_rsn(pkt
, id
);
3087 case 50: return inf_ext_supp_rates(pkt
, id
);
3088 case 51: return inf_ap_ch_exp(pkt
, id
);
3089 case 52: return inf_neighb_rep(pkt
, id
);
3090 case 53: return inf_rcpi(pkt
, id
);
3091 case 54: return inf_mde(pkt
, id
);
3092 case 55: return inf_fte(pkt
, id
);
3093 case 56: return inf_time_out_int(pkt
, id
);
3094 case 57: return inf_rde(pkt
, id
);
3095 case 58: return inf_dse_reg_loc(pkt
, id
);
3096 case 59: return inf_supp_op_class(pkt
, id
);
3097 case 60: return inf_ext_ch_sw_ann(pkt
, id
);
3098 case 61: return inf_ht_op(pkt
, id
);
3099 case 62: return inf_sec_ch_offs(pkt
, id
);
3100 case 63: return inf_bss_avg_acc_del(pkt
, id
);
3101 case 64: return inf_ant(pkt
, id
);
3102 case 65: return inf_rsni(pkt
, id
);
3103 case 66: return inf_meas_pilot_trans(pkt
, id
);
3104 case 67: return inf_bss_avl_adm_cap(pkt
, id
);
3105 case 68: return inf_bss_ac_acc_del(pkt
, id
);
3106 case 69: return inf_time_adv(pkt
, id
);
3107 case 70: return inf_rm_ena_cap(pkt
, id
);
3108 case 71: return inf_mult_bssid(pkt
, id
);
3109 case 72: return inf_20_40_bss_coex(pkt
, id
);
3110 case 73: return inf_20_40_bss_int_ch_rep(pkt
, id
);
3111 case 74: return inf_overl_bss_scan_para(pkt
, id
);
3112 case 75: return inf_ric_desc(pkt
, id
);
3113 case 76: return inf_mgmt_mic(pkt
, id
);
3114 case 78: return inf_ev_req(pkt
, id
);
3115 case 79: return inf_ev_rep(pkt
, id
);
3116 case 80: return inf_diagn_req(pkt
, id
);
3117 case 81: return inf_diagn_rep(pkt
, id
);
3118 case 82: return inf_loc_para(pkt
, id
);
3119 case 83: return inf_nontr_bssid_cap(pkt
, id
);
3120 case 84: return inf_ssid_list(pkt
, id
);
3121 case 85: return inf_mult_bssid_index(pkt
, id
);
3122 case 86: return inf_fms_desc(pkt
, id
);
3123 case 87: return inf_fms_req(pkt
, id
);
3124 case 88: return inf_fms_resp(pkt
, id
);
3125 case 89: return inf_qos_tfc_cap(pkt
, id
);
3126 case 90: return inf_bss_max_idle_per(pkt
, id
);
3127 case 91: return inf_tfs_req(pkt
, id
);
3128 case 92: return inf_tfs_resp(pkt
, id
);
3129 case 93: return inf_wnm_sleep_mod(pkt
, id
);
3130 case 94: return inf_tim_bcst_req(pkt
, id
);
3131 case 95: return inf_tim_bcst_resp(pkt
, id
);
3132 case 96: return inf_coll_interf_rep(pkt
, id
);
3133 case 97: return inf_ch_usage(pkt
, id
);
3134 case 98: return inf_time_zone(pkt
, id
);
3135 case 99: return inf_dms_req(pkt
, id
);
3136 case 100: return inf_dms_resp(pkt
, id
);
3137 case 101: return inf_link_id(pkt
, id
);
3138 case 102: return inf_wakeup_sched(pkt
, id
);
3139 case 104: return inf_ch_sw_timing(pkt
, id
);
3140 case 105: return inf_pti_ctrl(pkt
, id
);
3141 case 106: return inf_tpu_buff_status(pkt
, id
);
3142 case 107: return inf_interw(pkt
, id
);
3143 case 108: return inf_adv_proto(pkt
, id
);
3144 case 109: return inf_exp_bandw_req(pkt
, id
);
3145 case 110: return inf_qos_map_set(pkt
, id
);
3146 case 111: return inf_roam_cons(pkt
, id
);
3147 case 112: return inf_emer_alert_id(pkt
, id
);
3148 case 113: return inf_mesh_conf(pkt
, id
);
3149 case 114: return inf_mesh_id(pkt
, id
);
3150 case 115: return inf_mesh_link_metr_rep(pkt
, id
);
3151 case 116: return inf_cong_notif(pkt
, id
);
3152 case 117: return inf_mesh_peer_mgmt(pkt
, id
);
3153 case 118: return inf_mesh_ch_sw_para(pkt
, id
);
3154 case 119: return inf_mesh_awake_win(pkt
, id
);
3155 case 120: return inf_beacon_timing(pkt
, id
);
3156 case 121: return inf_mccaop_setup_req(pkt
, id
);
3157 case 122: return inf_mccaop_setup_rep(pkt
, id
);
3158 case 123: return inf_mccaop_adv(pkt
, id
);
3159 case 124: return inf_mccaop_teardwn(pkt
, id
);
3160 case 125: return inf_gann(pkt
, id
);
3161 case 126: return inf_rann(pkt
, id
);
3162 case 127: return inf_ext_cap(pkt
, id
);
3163 case 128: return inf_reserved(pkt
, id
);
3164 case 129: return inf_reserved(pkt
, id
);
3165 case 130: return inf_preq(pkt
, id
);
3166 case 131: return inf_prep(pkt
, id
);
3167 case 132: return inf_perr(pkt
, id
);
3168 case 133: return inf_reserved(pkt
, id
);
3169 case 134: return inf_reserved(pkt
, id
);
3170 case 135: return inf_reserved(pkt
, id
);
3171 case 136: return inf_reserved(pkt
, id
);
3172 case 137: return inf_pxu(pkt
, id
);
3173 case 138: return inf_pxuc(pkt
, id
);
3174 case 139: return inf_auth_mesh_peer_exch(pkt
, id
);
3175 case 140: return inf_mic(pkt
, id
);
3176 case 141: return inf_dest_uri(pkt
, id
);
3177 case 142: return inf_u_apsd_coex(pkt
, id
);
3178 case 143 ... 173: return inf_reserved(pkt
, id
);
3179 case 174: return inf_mccaop_adv_overv(pkt
, id
);
3180 case 221: return inf_vend_spec(pkt
, id
);
3186 #define ESS 0b0000000000000001
3187 #define IBSS 0b0000000000000010
3188 #define CF_Pollable 0b0000000000000100
3189 #define CF_Poll_Req 0b0000000000001000
3190 #define Privacy 0b0000000000010000
3191 #define Short_Pre 0b0000000000100000
3192 #define PBCC 0b0000000001000000
3193 #define Ch_Agility 0b0000000010000000
3194 #define Spec_Mgmt 0b0000000100000000
3195 #define QoS 0b0000001000000000
3196 #define Short_Slot_t 0b0000010000000000
3197 #define APSD 0b0000100000000000
3198 #define Radio_Meas 0b0001000000000000
3199 #define DSSS_OFDM 0b0010000000000000
3200 #define Del_Block_ACK 0b0100000000000000
3201 #define Imm_Block_ACK 0b1000000000000000
3203 static int8_t cap_field(u16 cap_inf
)
3209 if (CF_Pollable
& cap_inf
)
3210 tprintf(" CF Pollable;");
3211 if (CF_Poll_Req
& cap_inf
)
3212 tprintf(" CF-Poll Request;");
3213 if (Privacy
& cap_inf
)
3214 tprintf(" Privacy;");
3215 if (Short_Pre
& cap_inf
)
3216 tprintf(" Short Preamble;");
3219 if (Ch_Agility
& cap_inf
)
3220 tprintf(" Channel Agility;");
3221 if (Spec_Mgmt
& cap_inf
)
3222 tprintf(" Spectrum Management;");
3225 if (Short_Slot_t
& cap_inf
)
3226 tprintf(" Short Slot Time;");
3229 if (Radio_Meas
& cap_inf
)
3230 tprintf(" Radio Measurement;");
3231 if (DSSS_OFDM
& cap_inf
)
3232 tprintf(" DSSS-OFDM;");
3233 if (Del_Block_ACK
& cap_inf
)
3234 tprintf(" Delayed Block Ack;");
3235 if (Imm_Block_ACK
& cap_inf
)
3236 tprintf(" Immediate Block Ack;");
3241 /* Management Dissectors */
3242 static int8_t assoc_req(struct pkt_buff
*pkt
) {
3246 static int8_t assoc_resp(struct pkt_buff
*pkt
) {
3250 static int8_t reassoc_req(struct pkt_buff
*pkt
) {
3254 static int8_t reassoc_resp(struct pkt_buff
*pkt
) {
3258 static int8_t probe_req(struct pkt_buff
*pkt
) {
3262 static int8_t probe_resp(struct pkt_buff
*pkt
) {
3266 static int8_t beacon(struct pkt_buff
*pkt
)
3268 struct ieee80211_mgmt_beacon
*beacon
;
3270 beacon
= (struct ieee80211_mgmt_beacon
*)
3271 pkt_pull(pkt
, sizeof(*beacon
));
3275 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon
->timestamp
));
3276 tprintf("Beacon Interval (%fs), ", le16_to_cpu(beacon
->beacon_int
)*TU
);
3277 tprintf("Capabilities (0x%x <->", le16_to_cpu(beacon
->capab_info
));
3278 cap_field(le16_to_cpu(beacon
->capab_info
));
3282 tprintf("\n\tParameters:");
3283 while (inf_elements(pkt
)) {
3293 static int8_t atim(struct pkt_buff
*pkt
) {
3297 static int8_t disassoc(struct pkt_buff
*pkt
) {
3301 static int8_t auth(struct pkt_buff
*pkt
) {
3305 static int8_t deauth(struct pkt_buff
*pkt
) {
3308 /* End Management Dissectors */
3310 /* Control Dissectors */
3311 static int8_t ps_poll(struct pkt_buff
*pkt
) {
3315 static int8_t rts(struct pkt_buff
*pkt
) {
3319 static int8_t cts(struct pkt_buff
*pkt
) {
3323 static int8_t ack(struct pkt_buff
*pkt
) {
3327 static int8_t cf_end(struct pkt_buff
*pkt
) {
3331 static int8_t cf_end_ack(struct pkt_buff
*pkt
) {
3334 /* End Control Dissectors */
3336 /* Data Dissectors */
3337 static int8_t data(struct pkt_buff
*pkt
) {
3341 static int8_t data_cf_ack(struct pkt_buff
*pkt
) {
3345 static int8_t data_cf_poll(struct pkt_buff
*pkt
) {
3349 static int8_t data_cf_ack_poll(struct pkt_buff
*pkt
) {
3353 static int8_t null(struct pkt_buff
*pkt
) {
3357 static int8_t cf_ack(struct pkt_buff
*pkt
) {
3361 static int8_t cf_poll(struct pkt_buff
*pkt
) {
3365 static int8_t cf_ack_poll(struct pkt_buff
*pkt
) {
3368 /* End Data Dissectors */
3370 static const char *mgt_sub(u8 subtype
, struct pkt_buff
*pkt
,
3371 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3374 struct ieee80211_mgmt
*mgmt
;
3375 const char *dst
, *src
, *bssid
;
3377 mgmt
= (struct ieee80211_mgmt
*) pkt_pull(pkt
, sizeof(*mgmt
));
3381 dst
= lookup_vendor((mgmt
->da
[0] << 16) |
3382 (mgmt
->da
[1] << 8) |
3384 src
= lookup_vendor((mgmt
->sa
[0] << 16) |
3385 (mgmt
->sa
[1] << 8) |
3388 bssid
= lookup_vendor((mgmt
->bssid
[0] << 16) |
3389 (mgmt
->bssid
[1] << 8) |
3391 seq_ctrl
= le16_to_cpu(mgmt
->seq_ctrl
);
3393 tprintf("Duration (%u),", le16_to_cpu(mgmt
->duration
));
3394 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3395 mgmt
->da
[0], mgmt
->da
[1], mgmt
->da
[2],
3396 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
3398 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst
,
3399 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
3402 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3403 mgmt
->sa
[0], mgmt
->sa
[1], mgmt
->sa
[2],
3404 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
3406 tprintf("=> (%s:%.2x:%.2x:%.2x)", src
,
3407 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
3410 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3411 mgmt
->bssid
[0], mgmt
->bssid
[1], mgmt
->bssid
[2],
3412 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
3414 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid
,
3415 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
3418 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ",
3419 seq_ctrl
& 0xf, seq_ctrl
>> 4);
3423 *get_content
= assoc_req
;
3424 return "Association Request";
3426 *get_content
= assoc_resp
;
3427 return "Association Response";
3429 *get_content
= reassoc_req
;
3430 return "Reassociation Request";
3432 *get_content
= reassoc_resp
;
3433 return "Reassociation Response";
3435 *get_content
= probe_req
;
3436 return "Probe Request";
3438 *get_content
= probe_resp
;
3439 return "Probe Response";
3441 *get_content
= beacon
;
3444 *get_content
= atim
;
3447 *get_content
= disassoc
;
3448 return "Disassociation";
3450 *get_content
= auth
;
3451 return "Authentication";
3453 *get_content
= deauth
;
3454 return "Deauthentication";
3455 case 0b0110 ... 0b0111:
3456 case 0b1101 ... 0b1111:
3457 *get_content
= NULL
;
3460 *get_content
= NULL
;
3461 return "Management SubType unknown";
3465 static const char *ctrl_sub(u8 subtype
, struct pkt_buff
*pkt
,
3466 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3470 *get_content
= ps_poll
;
3482 *get_content
= cf_end
;
3485 *get_content
= cf_end_ack
;
3486 return "CF End + CF-ACK";
3487 case 0b0000 ... 0b1001:
3488 *get_content
= NULL
;
3491 return "Control SubType unkown";
3495 static const char *data_sub(u8 subtype
, struct pkt_buff
*pkt
,
3496 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3500 *get_content
= data
;
3503 *get_content
= data_cf_ack
;
3504 return "Data + CF-ACK";
3506 *get_content
= data_cf_poll
;
3507 return "Data + CF-Poll";
3509 *get_content
= data_cf_ack_poll
;
3510 return "Data + CF-ACK + CF-Poll";
3512 *get_content
= null
;
3515 *get_content
= cf_ack
;
3518 *get_content
= cf_poll
;
3521 *get_content
= cf_ack_poll
;
3522 return "CF-ACK + CF-Poll";
3523 case 0b1000 ... 0b1111:
3524 *get_content
= NULL
;
3527 *get_content
= NULL
;
3528 return "Data SubType unkown";
3533 frame_control_type(u8 type
, const char *(**get_subtype
)(u8 subtype
,
3534 struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)))
3538 *get_subtype
= mgt_sub
;
3539 return "Management";
3541 *get_subtype
= ctrl_sub
;
3544 *get_subtype
= data_sub
;
3547 *get_subtype
= NULL
;
3550 *get_subtype
= NULL
;
3551 return "Control Type unkown";
3555 static void ieee80211(struct pkt_buff
*pkt
)
3557 int8_t (*get_content
)(struct pkt_buff
*pkt
) = NULL
;
3558 const char *(*get_subtype
)(u8 subtype
, struct pkt_buff
*pkt
,
3559 int8_t (**get_content
)(struct pkt_buff
*pkt
)) = NULL
;
3560 const char *subtype
= NULL
;
3561 struct ieee80211_frm_ctrl
*frm_ctrl
;
3563 frm_ctrl
= (struct ieee80211_frm_ctrl
*)
3564 pkt_pull(pkt
, sizeof(*frm_ctrl
));
3565 if (frm_ctrl
== NULL
)
3568 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
3569 le16_to_cpu(frm_ctrl
->frame_control
));
3571 tprintf(" [ Proto Version (%u), ", frm_ctrl
->proto_version
);
3572 tprintf("Type (%u, %s), ", frm_ctrl
->type
,
3573 frame_control_type(frm_ctrl
->type
, &get_subtype
));
3575 subtype
= (*get_subtype
)(frm_ctrl
->subtype
, pkt
, &get_content
);
3576 tprintf("Subtype (%u, %s)", frm_ctrl
->subtype
, subtype
);
3578 tprintf("%s%s%s", colorize_start_full(black
, red
),
3579 "No SubType Data available", colorize_end());
3582 tprintf("%s%s", frm_ctrl
->to_ds
? ", Frame goes to DS" : "",
3583 frm_ctrl
->from_ds
? ", Frame comes from DS" : "");
3584 tprintf("%s", frm_ctrl
->more_frags
? ", More Fragments" : "");
3585 tprintf("%s", frm_ctrl
->retry
? ", Frame is retransmitted" : "");
3586 tprintf("%s", frm_ctrl
->power_mgmt
? ", In Power Saving Mode" : "");
3587 tprintf("%s", frm_ctrl
->more_data
? ", More Data" : "");
3588 tprintf("%s", frm_ctrl
->wep
? ", Needs WEP" : "");
3589 tprintf("%s", frm_ctrl
->order
? ", Order" : "");
3593 tprintf(" [ Subtype %s: ", subtype
);
3594 if (!((*get_content
) (pkt
)))
3595 tprintf("%s%s%s", colorize_start_full(black
, red
),
3596 "Failed to dissect Subtype", colorize_end());
3599 tprintf("%s%s%s", colorize_start_full(black
, red
),
3600 "No SubType Data available", colorize_end());
3605 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
3608 static void ieee80211_less(struct pkt_buff
*pkt
)
3610 tprintf("802.11 frame (more on todo)");
3613 struct protocol ieee80211_ops
= {
3615 .print_full
= ieee80211
,
3616 .print_less
= ieee80211_less
,
3619 EXPORT_SYMBOL(ieee80211_ops
);