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.
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() */
20 #include "dissector_80211.h"
27 /* Note: Fields are encoded in little-endian! */
28 struct ieee80211_frm_ctrl
{
32 #if defined(__LITTLE_ENDIAN_BITFIELD)
33 /* Correct order here ... */
34 __extension__ u16 proto_version
:2,
45 #elif defined(__BIG_ENDIAN_BITFIELD)
46 __extension__ u16 subtype
:4,
58 # error "Adjust your <asm/byteorder.h> defines"
64 /* Management Frame start */
65 /* Note: Fields are encoded in little-endian! */
66 struct ieee80211_mgmt
{
74 struct ieee80211_mgmt_auth
{
78 /* possibly followed by Challenge text */
82 struct ieee80211_mgmt_deauth
{
86 struct ieee80211_mgmt_assoc_req
{
89 /* followed by SSID and Supported rates */
93 struct ieee80211_mgmt_assoc_resp
{
97 /* followed by Supported rates */
101 struct ieee80211_mgmt_reassoc_resp
{
105 /* followed by Supported rates */
109 struct ieee80211_mgmt_reassoc_req
{
113 /* followed by SSID and Supported rates */
117 struct ieee80211_mgmt_disassoc
{
121 struct ieee80211_mgmt_probe_req
{
124 struct ieee80211_mgmt_beacon
{
128 /* followed by some of SSID, Supported rates,
129 * FH Params, DS Params, CF Params, IBSS Params, TIM */
133 struct ieee80211_mgmt_probe_resp
{
137 /* followed by some of SSID, Supported rates,
138 * FH Params, DS Params, CF Params, IBSS Params, TIM */
141 /* Management Frame end */
143 /* Control Frame start */
144 /* Note: Fields are encoded in little-endian! */
145 struct ieee80211_ctrl
{
148 struct ieee80211_ctrl_rts
{
154 struct ieee80211_ctrl_cts
{
159 struct ieee80211_ctrl_ack
{
164 struct ieee80211_ctrl_ps_poll
{
170 struct ieee80211_ctrl_cf_end
{
176 struct ieee80211_ctrl_cf_end_ack
{
181 /* Control Frame end */
183 /* Data Frame start */
184 /* Note: Fields are encoded in little-endian! */
185 struct ieee80211_data
{
191 struct element_reserved
{
195 struct element_ssid
{
200 struct element_supp_rates
{
205 struct element_fh_ps
{
213 struct element_dsss_ps
{
218 struct element_cf_ps
{
234 struct element_ibss_ps
{
239 struct element_country_tripled
{
245 struct element_country
{
247 #if defined(__LITTLE_ENDIAN_BITFIELD)
248 /* Correct order here ... */
252 #elif defined(__BIG_ENDIAN_BITFIELD)
257 # error "Adjust your <asm/byteorder.h> defines"
259 /* triplet may repeat */
260 struct element_country_tripled tripled
[0];
265 struct element_hop_pp
{
271 struct element_hop_pt
{
285 struct element_bss_load
{
292 struct element_edca_ps
{
302 struct element_tspec
{
306 #if defined(__LITTLE_ENDIAN_BITFIELD)
307 /* Correct order here ... */
308 __extension__ u32 len
:8,
319 #elif defined(__BIG_ENDIAN_BITFIELD)
320 __extension__ u32 len
:8,
332 # error "Adjust your <asm/byteorder.h> defines"
349 u16 surplus_bandw_allow
;
353 struct element_tclas
{
359 struct element_tclas_frm_class
{
365 struct element_tclas_type0
{
371 struct element_tclas_type1
{
376 struct element_tclas_type1_ip4
{
386 struct element_tclas_type1_ip6
{
394 #if defined(__LITTLE_ENDIAN_BITFIELD)
395 __extension__ u8 flow_label3
:8;
396 __extension__ u8 flow_label2
:8;
397 __extension__ u8 flow_label1
:8;
398 #elif defined(__BIG_ENDIAN_BITFIELD)
399 __extension__ u8 flow_label1
:8;
400 __extension__ u8 flow_label2
:8;
401 __extension__ u8 flow_label3
:8;
403 # error "Adjust your <asm/byteorder.h> defines"
409 struct element_tclas_type2
{
413 struct element_tclas_type3
{
419 struct element_tclas_type4
{
424 struct element_tclas_type4_ip4
{
434 struct element_tclas_type4_ip6
{
444 #if defined(__LITTLE_ENDIAN_BITFIELD)
445 __extension__ u8 flow_label3
:8;
446 __extension__ u8 flow_label2
:8;
447 __extension__ u8 flow_label1
:8;
448 #elif defined(__BIG_ENDIAN_BITFIELD)
449 __extension__ u8 flow_label1
:8;
450 __extension__ u8 flow_label2
:8;
451 __extension__ u8 flow_label3
:8;
453 # error "Adjust your <asm/byteorder.h> defines"
459 struct element_tclas_type5
{
465 struct element_schedule
{
473 struct element_chall_txt
{
478 struct element_pwr_constr
{
483 struct element_pwr_cap
{
489 struct element_tpc_req
{
493 struct element_tpc_rep
{
499 struct element_supp_ch
{
505 struct element_supp_ch_tuple
{
510 struct element_ch_sw_ann
{
517 struct element_meas_basic
{
523 struct element_meas_cca
{
529 struct element_meas_rpi
{
535 struct element_meas_ch_load
{
543 struct element_meas_noise
{
551 struct element_meas_beacon
{
561 struct element_meas_frame
{
571 struct element_meas_sta
{
579 struct element_meas_lci
{
582 u8 longitude_req_res
;
587 struct element_meas_trans_str_cat
{
596 struct element_meas_mcast_diag
{
600 u8 mcast_triggered
[0];
604 struct element_meas_loc_civic
{
607 u8 loc_srv_intv_unit
;
612 struct element_meas_loc_id
{
614 u8 loc_srv_intv_unit
;
619 struct element_meas_pause
{
624 struct element_meas_req
{
632 struct element_meas_rep
{
640 struct element_quiet
{
648 struct element_ibss_dfs
{
655 struct element_ibss_dfs_tuple
{
665 struct element_ts_del
{
670 struct element_tclas_proc
{
675 struct element_ht_cap
{
680 #if defined(__LITTLE_ENDIAN_BITFIELD)
681 /* Correct order here ... */
682 __extension__ u16 ldpc
:1,
696 #elif defined(__BIG_ENDIAN_BITFIELD)
697 __extension__ u16 rx_stbc
:2,
712 # error "Adjust your <asm/byteorder.h> defines"
720 #if defined(__LITTLE_ENDIAN_BITFIELD)
721 /* Correct order here ... */
722 __extension__ u8 bitmask1
:8;
723 __extension__ u8 bitmask2
:8;
724 __extension__ u8 bitmask3
:8;
725 __extension__ u8 bitmask4
:8;
726 __extension__ u8 bitmask5
:8;
727 __extension__ u8 bitmask6
:8;
728 __extension__ u8 bitmask7
:8;
729 __extension__ u8 bitmask8
:8;
730 __extension__ u8 bitmask9
:8;
731 __extension__ u8 bitmask10_res
:8;
732 __extension__ u16 supp_rate_res
:16;
733 __extension__ u32 tx_param_res
:32;
735 #elif defined(__BIG_ENDIAN_BITFIELD)
736 __extension__ u32 tx_param_res
:32;
737 __extension__ u16 supp_rate_res
:16;
738 __extension__ u8 bitmask10_res
:8;
739 __extension__ u8 bitmask9
:8;
740 __extension__ u8 bitmask8
:8;
741 __extension__ u8 bitmask7
:8;
742 __extension__ u8 bitmask6
:8;
743 __extension__ u8 bitmask5
:8;
744 __extension__ u8 bitmask4
:8;
745 __extension__ u8 bitmask3
:8;
746 __extension__ u8 bitmask2
:8;
747 __extension__ u8 bitmask1
:8;
749 # error "Adjust your <asm/byteorder.h> defines"
758 struct element_qos_cap
{
763 struct element_ext_supp_rates
{
768 struct element_vend_spec
{
774 static int8_t len_neq_error(u8 len
, u8 intended
)
776 if(intended
!= len
) {
777 tprintf("Length should be %u Bytes", intended
);
784 static int8_t len_lt_error(u8 len
, u8 intended
)
787 tprintf("Length should be greater %u Bytes", intended
);
794 static float data_rates(u8 id
)
796 /* XXX Why not (id / 2.f)? */
804 case 11: return 5.5f
;
805 case 12: return 6.0f
;
806 case 18: return 9.0f
;
807 case 22: return 11.0f
;
808 case 24: return 12.0f
;
809 case 27: return 13.5f
;
810 case 36: return 18.0f
;
811 case 44: return 22.0f
;
812 case 48: return 24.0f
;
813 case 54: return 27.0f
;
814 case 66: return 33.0f
;
815 case 72: return 36.0f
;
816 case 96: return 48.0f
;
817 case 108: return 54.0f
;
830 static int8_t subelements(struct pkt_buff
*pkt
, u8 len
)
836 struct subelement
*sub
;
838 sub
= (struct subelement
*) pkt_pull(pkt
, sizeof(*sub
));
842 tprintf(", Subelement ID %u, ", sub
->id
);
843 tprintf("Length %u, ", sub
->len
);
845 data
= pkt_pull(pkt
, sub
->len
);
850 for(j
=0; j
< sub
->len
; j
++)
851 tprintf("%.2x ", data
[j
]);
856 /* Not needed ?! Should break before*/
859 * tprintf("Length error");
867 static int8_t inf_reserved(struct pkt_buff
*pkt
, u8
*id
)
871 struct element_reserved
*reserved
;
873 reserved
= (struct element_reserved
*) pkt_pull(pkt
, sizeof(*reserved
));
874 if (reserved
== NULL
)
877 tprintf("Reserved (%u, Len (%u)): ", *id
, reserved
->len
);
879 data
= pkt_pull(pkt
, reserved
->len
);
884 for (i
= 0; i
< reserved
->len
; i
++)
885 tprintf("%.2x", data
[i
]);
890 static int8_t inf_ssid(struct pkt_buff
*pkt
, u8
*id
)
893 struct element_ssid
*ssid
;
896 ssid
= (struct element_ssid
*) pkt_pull(pkt
, sizeof(*ssid
));
900 tprintf(" SSID (%u, Len (%u)): ", *id
, ssid
->len
);
902 if ((ssid
->len
- sizeof(*ssid
) + 1) > 0) {
903 ssid_name
= (char *) pkt_pull(pkt
, ssid
->len
);
904 if (ssid_name
== NULL
)
907 for (i
= 0; i
< ssid
->len
; i
++)
908 tprintf("%c",ssid_name
[i
]);
910 tprintf("Wildcard SSID");
916 static int8_t inf_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
920 struct element_supp_rates
*supp_rates
;
922 supp_rates
= (struct element_supp_rates
*)
923 pkt_pull(pkt
, sizeof(*supp_rates
));
924 if (supp_rates
== NULL
)
927 tprintf(" Supp. Rates (%u, Len (%u)): ", *id
, supp_rates
->len
);
928 if (len_lt_error(supp_rates
->len
, 1))
931 if ((supp_rates
->len
- sizeof(*supp_rates
) + 1) > 0) {
932 rates
= pkt_pull(pkt
, supp_rates
->len
);
936 for (i
= 0; i
< supp_rates
->len
; i
++)
937 tprintf("%g%s ", ((rates
[i
] & 0x80) >> 7) ?
938 data_rates(rates
[i
] & 0x3f) :
939 ((rates
[i
] & 0x3f) * 0.5),
940 ((rates
[i
] & 0x80) >> 7) ? "(B)" : "");
947 static int8_t inf_fh_ps(struct pkt_buff
*pkt
, u8
*id
)
949 struct element_fh_ps
*fh_ps
;
951 fh_ps
= (struct element_fh_ps
*) pkt_pull(pkt
, sizeof(*fh_ps
));
955 tprintf(" FH Param Set (%u, Len(%u)): ", *id
, fh_ps
->len
);
956 if (len_neq_error(fh_ps
->len
, 5))
958 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps
->dwell_time
) * TU
);
959 tprintf("HopSet: %u, ", fh_ps
->hop_set
);
960 tprintf("HopPattern: %u, ", fh_ps
->hop_pattern
);
961 tprintf("HopIndex: %u", fh_ps
->hop_index
);
966 static int8_t inf_dsss_ps(struct pkt_buff
*pkt
, u8
*id
)
968 struct element_dsss_ps
*dsss_ps
;
970 dsss_ps
= (struct element_dsss_ps
*) pkt_pull(pkt
, sizeof(*dsss_ps
));
974 tprintf(" DSSS Param Set (%u, Len(%u)): ", *id
, dsss_ps
->len
);
975 if (len_neq_error(dsss_ps
->len
, 1))
977 tprintf("Current Channel: %u", dsss_ps
->curr_ch
);
982 static int8_t inf_cf_ps(struct pkt_buff
*pkt
, u8
*id
)
984 struct element_cf_ps
*cf_ps
;
986 cf_ps
= (struct element_cf_ps
*) pkt_pull(pkt
, sizeof(*cf_ps
));
990 tprintf(" CF Param Set (%u, Len(%u)): ", *id
, cf_ps
->len
);
991 if (len_neq_error(cf_ps
->len
, 6))
993 tprintf("CFP Count: %u, ", cf_ps
->cfp_cnt
);
994 tprintf("CFP Period: %u, ", cf_ps
->cfp_period
);
995 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps
->cfp_max_dur
) * TU
);
996 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps
->cfp_dur_rem
) * TU
);
1001 static int8_t inf_tim(struct pkt_buff
*pkt
, u8
*id
)
1003 struct element_tim
*tim
;
1006 tim
= (struct element_tim
*) pkt_pull(pkt
, sizeof(*tim
));
1010 tprintf(" TIM (%u, Len(%u)): ", *id
, tim
->len
);
1011 if (len_lt_error(tim
->len
, 3))
1013 tprintf("DTIM Count: %u, ", tim
->dtim_cnt
);
1014 tprintf("DTIM Period: %u, ", tim
->dtim_period
);
1015 tprintf("Bitmap Control: %u, ", tim
->bmp_cntrl
);
1016 if ((tim
->len
- sizeof(*tim
) + 1) > 0) {
1017 u8
*bmp
= pkt_pull(pkt
, (tim
->len
- sizeof(*tim
) + 1));
1021 tprintf("Partial Virtual Bitmap: 0x");
1022 for (i
= 0; i
< (tim
->len
- sizeof(*tim
) + 1); i
++)
1023 tprintf("%.2x", bmp
[i
]);
1029 static int8_t inf_ibss_ps(struct pkt_buff
*pkt
, u8
*id
)
1031 struct element_ibss_ps
*ibss_ps
;
1033 ibss_ps
= (struct element_ibss_ps
*) pkt_pull(pkt
, sizeof(*ibss_ps
));
1034 if (ibss_ps
== NULL
)
1037 tprintf(" IBSS Param Set (%u, Len(%u)): ", *id
, ibss_ps
->len
);
1038 if (len_neq_error(ibss_ps
->len
, 2))
1040 tprintf("ATIM Window: %fs", le16_to_cpu(ibss_ps
->atim_win
) * TU
);
1045 static int8_t inf_country(struct pkt_buff
*pkt
, u8
*id
)
1049 struct element_country
*country
;
1051 country
= (struct element_country
*) pkt_pull(pkt
, sizeof(*country
));
1052 if (country
== NULL
)
1055 tprintf(" Country (%u, Len(%u)): ", *id
, country
->len
);
1056 if (len_lt_error(country
->len
, 6))
1058 tprintf("Country String: %c%c%c", country
->country_first
,
1059 country
->country_sec
, country
->country_third
);
1061 for (i
= country
->len
% 3; i
< (country
->len
- 3); i
+= 3) {
1062 struct element_country_tripled
*country_tripled
;
1064 country_tripled
= (struct element_country_tripled
*)
1065 pkt_pull(pkt
, sizeof(*country_tripled
));
1066 if (country_tripled
== NULL
)
1069 if(country_tripled
->frst_ch
>= 201) {
1070 tprintf("Oper Ext ID: %u, ", country_tripled
->frst_ch
);
1071 tprintf("Operating Class: %u, ", country_tripled
->nr_ch
);
1072 tprintf("Coverage Class: %u", country_tripled
->max_trans
);
1074 tprintf("First Ch Nr: %u, ", country_tripled
->frst_ch
);
1075 tprintf("Nr of Ch: %u, ", country_tripled
->nr_ch
);
1076 tprintf("Max Transmit Pwr Lvl: %u", country_tripled
->max_trans
);
1080 if(country
->len
% 3) {
1081 pad
= pkt_pull(pkt
, 1);
1085 tprintf(", Pad: 0x%x", *pad
);
1091 static int8_t inf_hop_pp(struct pkt_buff
*pkt
, u8
*id
)
1093 struct element_hop_pp
*hop_pp
;
1095 hop_pp
= (struct element_hop_pp
*) pkt_pull(pkt
, sizeof(*hop_pp
));
1099 tprintf(" Hopping Pattern Param (%u, Len(%u)): ", *id
, hop_pp
->len
);
1100 if (len_neq_error(hop_pp
->len
, 2))
1102 tprintf("Prime Radix: %u, ", hop_pp
->prime_radix
);
1103 tprintf("Nr of Ch: %u", hop_pp
->nr_ch
);
1108 static int8_t inf_hop_pt(struct pkt_buff
*pkt
, u8
*id
)
1112 struct element_hop_pt
*hop_pt
;
1114 hop_pt
= (struct element_hop_pt
*) pkt_pull(pkt
, sizeof(*hop_pt
));
1118 tprintf(" Hopping Pattern Table (%u, Len(%u)): ", *id
, hop_pt
->len
);
1119 if (len_lt_error(hop_pt
->len
, 4))
1121 tprintf("Flag: %u, ", hop_pt
->flag
);
1122 tprintf("Nr of Sets: %u, ", hop_pt
->nr_sets
);
1123 tprintf("Modulus: %u, ", hop_pt
->modules
);
1124 tprintf("Offs: %u", hop_pt
->offs
);
1126 if ((hop_pt
->len
- sizeof(*hop_pt
) + 1) > 0) {
1127 rand_tabl
= pkt_pull(pkt
, (hop_pt
->len
- sizeof(*hop_pt
) + 1));
1128 if (rand_tabl
== NULL
)
1131 tprintf(", Rand table: 0x");
1132 for (i
= 0; i
< (hop_pt
->len
- sizeof(*hop_pt
) + 1); i
++)
1133 tprintf("%.2x", rand_tabl
[i
]);
1139 static int8_t inf_req(struct pkt_buff
*pkt
, u8
*id
)
1142 struct element_req
*req
;
1145 req
= (struct element_req
*) pkt_pull(pkt
, sizeof(*req
));
1149 tprintf(" Request Element (%u, Len(%u)): ", *id
, req
->len
);
1150 if ((req
->len
- sizeof(*req
) + 1) > 0) {
1151 req_ids
= pkt_pull(pkt
, (req
->len
- sizeof(*req
) + 1));
1152 if (req_ids
== NULL
)
1155 tprintf(", Requested Element IDs: ");
1156 for (i
= 0; i
< (req
->len
- sizeof(*req
) + 1); i
++)
1157 tprintf("%u ", req_ids
[i
]);
1163 static int8_t inf_bss_load(struct pkt_buff
*pkt
, u8
*id
)
1165 struct element_bss_load
*bss_load
;
1167 bss_load
= (struct element_bss_load
*) pkt_pull(pkt
, sizeof(*bss_load
));
1168 if (bss_load
== NULL
)
1171 tprintf(" BSS Load element (%u, Len(%u)): ", *id
, bss_load
->len
);
1172 if (len_neq_error(bss_load
->len
, 5))
1174 tprintf("Station Count: %u, ", le16_to_cpu(bss_load
->station_cnt
));
1175 tprintf("Channel Utilization: %u, ", bss_load
->ch_util
);
1176 tprintf("Available Admission Capacity: %uus",
1177 bss_load
->avlb_adm_cap
* 32);
1182 static int8_t inf_edca_ps(struct pkt_buff
*pkt
, u8
*id
)
1184 u32 ac_be
, ac_bk
, ac_vi
, ac_vo
;
1185 struct element_edca_ps
*edca_ps
;
1187 edca_ps
= (struct element_edca_ps
*) pkt_pull(pkt
, sizeof(*edca_ps
));
1188 if (edca_ps
== NULL
)
1191 ac_be
= le32_to_cpu(edca_ps
->ac_be
);
1192 ac_bk
= le32_to_cpu(edca_ps
->ac_bk
);
1193 ac_vi
= le32_to_cpu(edca_ps
->ac_vi
);
1194 ac_vo
= le32_to_cpu(edca_ps
->ac_vo
);
1196 tprintf(" EDCA Param Set (%u, Len(%u)): ", *id
, edca_ps
->len
);
1197 if (len_neq_error(edca_ps
->len
, 18))
1199 tprintf("QoS Info: 0x%x (-> EDCA Param Set Update Count (%u),"
1200 "Q-Ack (%u), Queue Re (%u), TXOP Req(%u), Res(%u)), ",
1201 edca_ps
->qos_inf
, edca_ps
->qos_inf
>> 4,
1202 (edca_ps
->qos_inf
>> 3) & 1, (edca_ps
->qos_inf
>> 2) & 1,
1203 (edca_ps
->qos_inf
>> 1) & 1, edca_ps
->qos_inf
& 1);
1204 tprintf("Reserved: 0x%x, ", edca_ps
->res
);
1205 tprintf("AC_BE Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1206 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_be
,
1207 ac_be
>> 28, (ac_be
>> 27) & 1, (ac_be
>> 25) & 3,
1208 (ac_be
>> 24) & 1, (ac_be
>> 20) & 15, (ac_be
>> 16) & 15,
1209 bswap_16(ac_be
& 0xFFFF) * 32);
1210 tprintf("AC_BK Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1211 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_bk
,
1212 ac_bk
>> 28, (ac_bk
>> 27) & 1, (ac_bk
>> 25) & 3,
1213 (ac_bk
>> 24) & 1, (ac_bk
>> 20) & 15, (ac_bk
>> 16) & 15,
1214 bswap_16(ac_bk
& 0xFFFF) * 32);
1215 tprintf("AC_VI Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1216 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_vi
,
1217 ac_vi
>> 28, (ac_vi
>> 27) & 1, (ac_vi
>> 25) & 3,
1218 (ac_vi
>> 24) & 1, (ac_vi
>> 20) & 15, (ac_vi
>> 16) & 15,
1219 bswap_16(ac_vi
& 0xFFFF) * 32);
1220 tprintf("AC_VO Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1221 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)", ac_vo
,
1222 ac_vo
>> 28, (ac_vo
>> 27) & 1, (ac_vo
>> 25) & 3,
1223 (ac_vo
>> 24) & 1, (ac_vo
>> 20) & 15, (ac_vo
>> 16) & 15,
1224 bswap_16(ac_vo
& 0xFFFF) * 32);
1229 static int8_t inf_tspec(struct pkt_buff
*pkt
, u8
*id
)
1231 u16 nom_msdu_size
, surplus_bandw_allow
;
1232 struct element_tspec
*tspec
;
1234 tspec
= (struct element_tspec
*) pkt_pull(pkt
, sizeof(*tspec
));
1238 nom_msdu_size
= le16_to_cpu(tspec
->nom_msdu_size
);
1239 surplus_bandw_allow
= le16_to_cpu(tspec
->surplus_bandw_allow
);
1241 tprintf(" TSPEC (%u, Len(%u)): ", *id
, tspec
->len
);
1242 if (len_neq_error(tspec
->len
, 55))
1244 tprintf("Traffic Type: %u, ", tspec
->traffic_type
);
1245 tprintf("TSID: %u, ", tspec
->tsid
);
1246 tprintf("Direction: %u, ", tspec
->direction
);
1247 tprintf("Access Policy: %u, ", tspec
->access_policy
);
1248 tprintf("Aggregation: %u, ", tspec
->aggr
);
1249 tprintf("APSD: %u, ", tspec
->apsd
);
1250 tprintf("User Priority: %u, ", tspec
->user_prior
);
1251 tprintf("TSinfo Ack Policy: %u, ", tspec
->tsinfo_ack_pol
);
1252 tprintf("Schedule: %u, ", tspec
->schedule
);
1253 tprintf("Reserved: 0x%x, ", tspec
->res
);
1254 tprintf("Nominal MSDU Size: %uB (Fixed (%u)), ",
1255 nom_msdu_size
>> 1, nom_msdu_size
& 1);
1256 tprintf("Maximum MSDU Size: %uB, ", le16_to_cpu(tspec
->max_msdu_size
));
1257 tprintf("Minimum Service Interval: %uus, ",
1258 le32_to_cpu(tspec
->min_srv_intv
));
1259 tprintf("Maximum Service Interval: %uus, ",
1260 le32_to_cpu(tspec
->max_srv_intv
));
1261 tprintf("Inactivity Interval: %uus, ",
1262 le32_to_cpu(tspec
->inactive_intv
));
1263 tprintf("Suspension Interval: %uus, ", le32_to_cpu(tspec
->susp_intv
));
1264 tprintf("Service Start Time: %uus, ",
1265 le32_to_cpu(tspec
->srv_start_time
));
1266 tprintf("Minimum Data Rate: %ub/s, ",le32_to_cpu(tspec
->min_data_rate
));
1267 tprintf("Mean Data Rate: %ub/s, ", le32_to_cpu(tspec
->mean_data_rate
));
1268 tprintf("Peak Data Rate: %ub/s, ",le32_to_cpu(tspec
->peak_data_rate
));
1269 tprintf("Burst Size: %uB, ", le32_to_cpu(tspec
->burst_size
));
1270 tprintf("Delay Bound: %uus, ", le32_to_cpu(tspec
->delay_bound
));
1271 tprintf("Minimum PHY Rate: %ub/s, ", le32_to_cpu(tspec
->min_phy_rate
));
1272 tprintf("Surplus Bandwidth: %u.%u, ", surplus_bandw_allow
>> 13,
1273 surplus_bandw_allow
& 0x1FFF);
1274 tprintf("Medium Time: %uus", le16_to_cpu(tspec
->med_time
) * 32);
1279 static const char *class_type(u8 type
)
1282 case 0: return "Ethernet parameters";
1283 case 1: return "TCP/UDP IP parameters";
1284 case 2: return "IEEE 802.1Q parameters";
1285 case 3: return "Filter Offset parameters";
1286 case 4: return "IP and higher layer parameters";
1287 case 5: return "IEEE 802.1D/Q parameters";
1288 default: return "Reserved";
1292 static int8_t inf_tclas(struct pkt_buff
*pkt
, u8
*id
)
1294 struct element_tclas
*tclas
;
1295 struct element_tclas_frm_class
*frm_class
;
1297 tclas
= (struct element_tclas
*) pkt_pull(pkt
, sizeof(*tclas
));
1301 frm_class
= (struct element_tclas_frm_class
*)
1302 pkt_pull(pkt
, sizeof(*frm_class
));
1303 if (frm_class
== NULL
)
1306 tprintf(" TCLAS (%u, Len(%u)): ", *id
, tclas
->len
);
1307 if (len_lt_error(tclas
->len
, 3))
1309 tprintf("User Priority: %u, ", tclas
->user_priority
);
1310 tprintf("Classifier Type: %s (%u), ", class_type(frm_class
->type
),
1312 tprintf("Classifier Mask: 0x%x, ", frm_class
->mask
);
1314 if(frm_class
->type
== 0) {
1315 struct element_tclas_type0
*type0
;
1317 type0
= (struct element_tclas_type0
*)
1318 pkt_pull(pkt
, sizeof(*type0
));
1322 /* I think little endian, like the rest */
1323 tprintf("Src Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1324 type0
->sa
[5], type0
->sa
[4], type0
->sa
[3],
1325 type0
->sa
[2], type0
->sa
[1], type0
->sa
[0]);
1326 tprintf("Dst Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1327 type0
->da
[5], type0
->da
[4], type0
->da
[3],
1328 type0
->da
[2], type0
->da
[1], type0
->da
[0]);
1329 tprintf("Type: 0x%x", le16_to_cpu(type0
->type
));
1331 else if(frm_class
->type
== 1) {
1332 struct element_tclas_type1
*type1
;
1334 type1
= (struct element_tclas_type1
*)
1335 pkt_pull(pkt
, sizeof(*type1
));
1339 tprintf("Version: %u, ", type1
->version
);
1340 /* big endian format follows */
1341 if(type1
->version
== 4) {
1342 struct element_tclas_type1_ip4
*type1_ip4
;
1343 char src_ip
[INET_ADDRSTRLEN
];
1344 char dst_ip
[INET_ADDRSTRLEN
];
1346 type1_ip4
= (struct element_tclas_type1_ip4
*)
1347 pkt_pull(pkt
, sizeof(*type1_ip4
));
1348 if (type1_ip4
== NULL
)
1351 inet_ntop(AF_INET
, &type1_ip4
->sa
, src_ip
, sizeof(src_ip
));
1352 inet_ntop(AF_INET
, &type1_ip4
->da
, dst_ip
, sizeof(dst_ip
));
1354 tprintf("Src IP: %s, ", src_ip
);
1355 tprintf("Dst IP: %s, ", dst_ip
);
1356 tprintf("Src Port: %u, ", ntohs(type1_ip4
->sp
));
1357 tprintf("Dst Port: %u, ", ntohs(type1_ip4
->dp
));
1358 tprintf("DSCP: 0x%x, ", type1_ip4
->dscp
);
1359 tprintf("Proto: %u, ", type1_ip4
->proto
);
1360 tprintf("Res: 0x%x", type1_ip4
->reserved
);
1362 else if(type1
->version
== 6) {
1363 struct element_tclas_type1_ip6
*type1_ip6
;
1364 char src_ip
[INET6_ADDRSTRLEN
];
1365 char dst_ip
[INET6_ADDRSTRLEN
];
1367 type1_ip6
= (struct element_tclas_type1_ip6
*)
1368 pkt_pull(pkt
, sizeof(*type1_ip6
));
1369 if (type1_ip6
== NULL
)
1372 inet_ntop(AF_INET6
, &type1_ip6
->sa
,
1373 src_ip
, sizeof(src_ip
));
1374 inet_ntop(AF_INET6
, &type1_ip6
->da
,
1375 dst_ip
, sizeof(dst_ip
));
1377 tprintf("Src IP: %s, ", src_ip
);
1378 tprintf("Dst IP: %s, ", dst_ip
);
1379 tprintf("Src Port: %u, ", ntohs(type1_ip6
->sp
));
1380 tprintf("Dst Port: %u, ", ntohs(type1_ip6
->dp
));
1381 tprintf("Flow Label: 0x%x%x%x", type1_ip6
->flow_label1
,
1382 type1_ip6
->flow_label2
, type1_ip6
->flow_label3
);
1385 tprintf("Version (%u) not supported", type1
->version
);
1390 else if(frm_class
->type
== 2) {
1391 struct element_tclas_type2
*type2
;
1393 type2
= (struct element_tclas_type2
*)
1394 pkt_pull(pkt
, sizeof(*type2
));
1398 tprintf("802.1Q VLAN TCI: 0x%x", ntohs(type2
->vlan_tci
));
1400 else if(frm_class
->type
== 3) {
1401 struct element_tclas_type3
*type3
;
1405 type3
= (struct element_tclas_type3
*)
1406 pkt_pull(pkt
, sizeof(*type3
));
1410 len
= (tclas
->len
- 5) / 2;
1412 tprintf("Filter Offset: %u, ", type3
->offs
);
1414 if((len
& 1) || (len_lt_error(tclas
->len
, 5))) {
1415 tprintf("Length of TCLAS (%u) not correct", tclas
->len
);
1419 val
= pkt_pull(pkt
, len
);
1423 tprintf("Filter Value: 0x");
1424 for (i
= 0; i
< len
/ 2; i
++)
1425 tprintf("%x ", val
[i
]);
1427 tprintf("Filter Mask: 0x");
1428 for (i
= len
/ 2; i
< len
; i
++)
1429 tprintf("%x ", val
[i
]);
1433 else if(frm_class
->type
== 4) {
1434 struct element_tclas_type4
*type4
;
1436 type4
= (struct element_tclas_type4
*)
1437 pkt_pull(pkt
, sizeof(*type4
));
1441 tprintf("Version: %u, ", type4
->version
);
1442 /* big endian format follows */
1443 if(type4
->version
== 4) {
1444 struct element_tclas_type4_ip4
*type4_ip4
;
1445 char src_ip
[INET_ADDRSTRLEN
];
1446 char dst_ip
[INET_ADDRSTRLEN
];
1448 type4_ip4
= (struct element_tclas_type4_ip4
*)
1449 pkt_pull(pkt
, sizeof(*type4_ip4
));
1450 if (type4_ip4
== NULL
)
1453 inet_ntop(AF_INET
, &type4_ip4
->sa
, src_ip
, sizeof(src_ip
));
1454 inet_ntop(AF_INET
, &type4_ip4
->da
, dst_ip
, sizeof(dst_ip
));
1456 tprintf("Src IP: %s, ", src_ip
);
1457 tprintf("Dst IP: %s, ", dst_ip
);
1458 tprintf("Src Port: %u, ", ntohs(type4_ip4
->sp
));
1459 tprintf("Dst Port: %u, ", ntohs(type4_ip4
->dp
));
1460 tprintf("DSCP: 0x%x, ", type4_ip4
->dscp
);
1461 tprintf("Proto: %u, ", type4_ip4
->proto
);
1462 tprintf("Res: 0x%x", type4_ip4
->reserved
);
1464 else if(type4
->version
== 6) {
1465 struct element_tclas_type4_ip6
*type4_ip6
;
1466 char src_ip
[INET6_ADDRSTRLEN
];
1467 char dst_ip
[INET6_ADDRSTRLEN
];
1469 type4_ip6
= (struct element_tclas_type4_ip6
*)
1470 pkt_pull(pkt
, sizeof(*type4_ip6
));
1471 if (type4_ip6
== NULL
)
1474 inet_ntop(AF_INET6
, &type4_ip6
->sa
,
1475 src_ip
, sizeof(src_ip
));
1476 inet_ntop(AF_INET6
, &type4_ip6
->da
,
1477 dst_ip
, sizeof(dst_ip
));
1479 tprintf("Src IP: %s, ", src_ip
);
1480 tprintf("Dst IP: %s, ", dst_ip
);
1481 tprintf("Src Port: %u, ", ntohs(type4_ip6
->sp
));
1482 tprintf("Dst Port: %u, ", ntohs(type4_ip6
->dp
));
1483 tprintf("DSCP: 0x%x, ", type4_ip6
->dscp
);
1484 tprintf("Nxt Hdr: %u, ", type4_ip6
->nxt_hdr
);
1485 tprintf("Flow Label: 0x%x%x%x", type4_ip6
->flow_label1
,
1486 type4_ip6
->flow_label2
, type4_ip6
->flow_label3
);
1489 tprintf("Version (%u) not supported", type4
->version
);
1493 else if(frm_class
->type
== 5) {
1494 struct element_tclas_type5
*type5
;
1496 type5
= (struct element_tclas_type5
*)
1497 pkt_pull(pkt
, sizeof(*type5
));
1501 tprintf("802.1Q PCP: 0x%x, ", type5
->pcp
);
1502 tprintf("802.1Q CFI: 0x%x, ", type5
->cfi
);
1503 tprintf("802.1Q VID: 0x%x", type5
->vid
);
1506 tprintf("Classifier Type (%u) not supported", frm_class
->type
);
1513 static int8_t inf_sched(struct pkt_buff
*pkt
, u8
*id
)
1515 struct element_schedule
*schedule
;
1518 schedule
= (struct element_schedule
*) pkt_pull(pkt
, sizeof(*schedule
));
1519 if (schedule
== NULL
)
1522 info
= le16_to_cpu(schedule
->inf
);
1524 tprintf(" Schedule (%u, Len(%u)): ", *id
, schedule
->len
);
1525 if (len_neq_error(schedule
->len
, 12))
1528 tprintf("Aggregation: %u, ", info
>> 15);
1529 tprintf("TSID: %u, ", (info
>> 11) & 0xF);
1530 tprintf("Direction: %u, ", (info
>> 9) & 0x3);
1531 tprintf("Res: %u, ", info
& 0x1FF);
1532 tprintf("Serv Start Time: %uus, ", le32_to_cpu(schedule
->start
));
1533 tprintf("Serv Interval: %uus, ", le32_to_cpu(schedule
->serv_intv
));
1534 tprintf("Spec Interval: %fs", le32_to_cpu(schedule
->spec_intv
) * TU
);
1539 static int8_t inf_chall_txt(struct pkt_buff
*pkt
, u8
*id
)
1541 struct element_chall_txt
*chall_txt
;
1545 chall_txt
= (struct element_chall_txt
*)
1546 pkt_pull(pkt
, sizeof(*chall_txt
));
1547 if (chall_txt
== NULL
)
1550 tprintf(" Challenge Text (%u, Len(%u)): ", *id
, chall_txt
->len
);
1551 if ((chall_txt
->len
- sizeof(*chall_txt
) + 1) > 0) {
1552 txt
= pkt_pull(pkt
, (chall_txt
->len
- sizeof(*chall_txt
) + 1));
1557 for (i
= 0; i
< (chall_txt
->len
- sizeof(*chall_txt
) + 1); i
++)
1558 tprintf("%x", txt
[i
]);
1564 static int8_t inf_pwr_constr(struct pkt_buff
*pkt
, u8
*id
)
1566 struct element_pwr_constr
*pwr_constr
;
1568 pwr_constr
= (struct element_pwr_constr
*) pkt_pull(pkt
, sizeof(*pwr_constr
));
1569 if (pwr_constr
== NULL
)
1572 tprintf(" Power Constraint (%u, Len(%u)): ", *id
, pwr_constr
->len
);
1573 if (len_neq_error(pwr_constr
->len
, 1))
1576 tprintf("Local Power Constraint: %udB", pwr_constr
->local_pwr_constr
);
1581 static int8_t inf_pwr_cap(struct pkt_buff
*pkt
, u8
*id
)
1583 struct element_pwr_cap
*pwr_cap
;
1585 pwr_cap
= (struct element_pwr_cap
*) pkt_pull(pkt
, sizeof(*pwr_cap
));
1586 if (pwr_cap
== NULL
)
1589 tprintf(" Power Capability (%u, Len(%u)): ", *id
, pwr_cap
->len
);
1590 if (len_neq_error(pwr_cap
->len
, 2))
1593 tprintf("Min. Transm. Pwr Cap.: %ddBm, ", (int8_t)pwr_cap
->min_pwr_cap
);
1594 tprintf("Max. Transm. Pwr Cap.: %ddBm", (int8_t)pwr_cap
->max_pwr_cap
);
1599 static int8_t inf_tpc_req(struct pkt_buff
*pkt
, u8
*id
)
1601 struct element_tpc_req
*tpc_req
;
1603 tpc_req
= (struct element_tpc_req
*) pkt_pull(pkt
, sizeof(*tpc_req
));
1604 if (tpc_req
== NULL
)
1607 tprintf(" TPC Request (%u, Len(%u))", *id
, tpc_req
->len
);
1608 if (len_neq_error(tpc_req
->len
, 0))
1614 static int8_t inf_tpc_rep(struct pkt_buff
*pkt
, u8
*id
)
1616 struct element_tpc_rep
*tpc_rep
;
1618 tpc_rep
= (struct element_tpc_rep
*) pkt_pull(pkt
, sizeof(*tpc_rep
));
1619 if (tpc_rep
== NULL
)
1622 tprintf(" TPC Report (%u, Len(%u)): ", *id
, tpc_rep
->len
);
1623 if (len_neq_error(tpc_rep
->len
, 2))
1626 tprintf("Transmit Power: %udBm, ", (int8_t)tpc_rep
->trans_pwr
);
1627 tprintf("Link Margin: %udB", (int8_t)tpc_rep
->trans_pwr
);
1632 static int8_t inf_supp_ch(struct pkt_buff
*pkt
, u8
*id
)
1634 struct element_supp_ch
*supp_ch
;
1637 supp_ch
= (struct element_supp_ch
*) pkt_pull(pkt
, sizeof(*supp_ch
));
1638 if (supp_ch
== NULL
)
1641 tprintf(" Supp Channels (%u, Len(%u)): ", *id
, supp_ch
->len
);
1642 if (len_lt_error(supp_ch
->len
, 2))
1645 if(supp_ch
->len
& 1) {
1646 tprintf("Length should be even");
1650 for (i
= 0; i
< supp_ch
->len
; i
+= 2) {
1651 struct element_supp_ch_tuple
*supp_ch_tuple
;
1653 supp_ch_tuple
= (struct element_supp_ch_tuple
*)
1654 pkt_pull(pkt
, sizeof(*supp_ch_tuple
));
1655 if (supp_ch_tuple
== NULL
)
1658 tprintf("First Channel Nr: %u, ", supp_ch_tuple
->first_ch_nr
);
1659 tprintf("Nr of Channels: %u, ", supp_ch_tuple
->nr_ch
);
1665 static int8_t inf_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
)
1667 struct element_ch_sw_ann
*ch_sw_ann
;
1669 ch_sw_ann
= (struct element_ch_sw_ann
*)
1670 pkt_pull(pkt
, sizeof(*ch_sw_ann
));
1671 if (ch_sw_ann
== NULL
)
1674 tprintf(" Channel Switch Announc (%u, Len(%u)): ", *id
, ch_sw_ann
->len
);
1675 if (len_neq_error(ch_sw_ann
->len
, 3))
1678 tprintf("Switch Mode: %u, ", ch_sw_ann
->switch_mode
);
1679 tprintf("New Nr: %u, ", ch_sw_ann
->new_nr
);
1680 tprintf("Switch Count: %u", ch_sw_ann
->switch_cnt
);
1685 static const char *meas_type(u8 type
)
1688 case 0: return "Basic";
1689 case 1: return "Clear Channel assesment (CCA)";
1690 case 2: return "Receive power indication (RPI) histogram";
1691 case 3: return "Channel load";
1692 case 4: return "Noise histogram";
1693 case 5: return "Beacon";
1694 case 6: return "Frame";
1695 case 7: return "STA statistics";
1696 case 8: return "LCI";
1697 case 9: return "Transmit stream/category measurement";
1698 case 10: return "Multicast diagnostics";
1699 case 11: return "Location Civic";
1700 case 12: return "Location Identifier";
1701 case 13 ... 255: return "Reserved";
1705 static int8_t inf_meas_req(struct pkt_buff
*pkt
, u8
*id
)
1707 struct element_meas_req
*meas_req
;
1709 meas_req
= (struct element_meas_req
*) pkt_pull(pkt
, sizeof(*meas_req
));
1710 if (meas_req
== NULL
)
1713 tprintf(" Measurement Req (%u, Len(%u)): ", *id
, meas_req
->len
);
1714 if (len_lt_error(meas_req
->len
, 3))
1717 tprintf("Token: %u, ", meas_req
->token
);
1718 tprintf("Req Mode: 0x%x (Parallel (%u), Enable(%u), Request(%u), "
1719 "Report(%u), Dur Mand(%u), Res(0x%x)), ", meas_req
->req_mode
,
1720 meas_req
->req_mode
& 0x1,
1721 (meas_req
->req_mode
>> 1) & 0x1,
1722 (meas_req
->req_mode
>> 2) & 0x1,
1723 (meas_req
->req_mode
>> 3) & 0x1,
1724 (meas_req
->req_mode
>> 4) & 0x1,
1725 meas_req
->req_mode
>> 7);
1726 tprintf("Type: %s (%u), ", meas_type(meas_req
->type
), meas_req
->type
);
1728 if(meas_req
->len
> 3) {
1729 if(meas_req
->type
== 0) {
1730 struct element_meas_basic
*basic
;
1732 basic
= (struct element_meas_basic
*)
1733 pkt_pull(pkt
, sizeof(*basic
));
1737 if ((meas_req
->len
- 3 - sizeof(*basic
)) != 0) {
1738 tprintf("Length of Req matchs not Type %u",
1743 tprintf("Ch Nr: %uus, ", basic
->ch_nr
);
1744 tprintf("Meas Start Time: %lu, ",
1745 le64_to_cpu(basic
->start
));
1746 tprintf("Meas Duration: %fs",
1747 le16_to_cpu(basic
->dur
) * TU
);
1750 else if(meas_req
->type
== 1) {
1751 struct element_meas_cca
*cca
;
1753 cca
= (struct element_meas_cca
*)
1754 pkt_pull(pkt
, sizeof(*cca
));
1758 if ((meas_req
->len
- 3 - sizeof(*cca
)) != 0) {
1759 tprintf("Length of Req matchs not Type %u",
1764 tprintf("Ch Nr: %uus, ", cca
->ch_nr
);
1765 tprintf("Meas Start Time: %lu, ",
1766 le64_to_cpu(cca
->start
));
1767 tprintf("Meas Duration: %fs",
1768 le16_to_cpu(cca
->dur
) * TU
);
1770 else if(meas_req
->type
== 2) {
1771 struct element_meas_rpi
*rpi
;
1773 rpi
= (struct element_meas_rpi
*)
1774 pkt_pull(pkt
, sizeof(*rpi
));
1778 if ((meas_req
->len
- 3 - sizeof(*rpi
)) != 0) {
1779 tprintf("Length of Req matchs not Type %u",
1784 tprintf("Ch Nr: %uus, ", rpi
->ch_nr
);
1785 tprintf("Meas Start Time: %lu, ",
1786 le64_to_cpu(rpi
->start
));
1787 tprintf("Meas Duration: %fs",
1788 le16_to_cpu(rpi
->dur
) * TU
);
1790 else if(meas_req
->type
== 3) {
1791 struct element_meas_ch_load
*ch_load
;
1793 ch_load
= (struct element_meas_ch_load
*)
1794 pkt_pull(pkt
, sizeof(*ch_load
));
1795 if (ch_load
== NULL
)
1798 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*ch_load
)) < 0) {
1799 tprintf("Length of Req matchs not Type %u",
1804 tprintf("OP Class: %u, ", ch_load
->op_class
);
1805 tprintf("Ch Nr: %u, ", ch_load
->ch_nr
);
1806 tprintf("Rand Intv: %fs, ",
1807 le16_to_cpu(ch_load
->rand_intv
) * TU
);
1808 tprintf("Meas Duration: %fs",
1809 le16_to_cpu(ch_load
->dur
) * TU
);
1811 if(!subelements(pkt
,
1812 meas_req
->len
- 3 - sizeof(*ch_load
)))
1815 else if(meas_req
->type
== 4) {
1816 struct element_meas_noise
*noise
;
1818 noise
= (struct element_meas_noise
*)
1819 pkt_pull(pkt
, sizeof(*noise
));
1823 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*noise
)) < 0) {
1824 tprintf("Length of Req matchs not Type %u",
1829 tprintf("OP Class: %u, ", noise
->op_class
);
1830 tprintf("Ch Nr: %u, ", noise
->ch_nr
);
1831 tprintf("Rand Intv: %fs, ",
1832 le16_to_cpu(noise
->rand_intv
) * TU
);
1833 tprintf("Meas Duration: %fs",
1834 le16_to_cpu(noise
->dur
) * TU
);
1836 if(!subelements(pkt
,
1837 meas_req
->len
- 3 - sizeof(*noise
)))
1840 else if(meas_req
->type
== 5) {
1841 struct element_meas_beacon
*beacon
;
1843 beacon
= (struct element_meas_beacon
*)
1844 pkt_pull(pkt
, sizeof(*beacon
));
1848 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*beacon
)) < 0) {
1849 tprintf("Length of Req matchs not Type %u",
1854 tprintf("OP Class: %u, ", beacon
->op_class
);
1855 tprintf("Ch Nr: %u, ", beacon
->ch_nr
);
1856 tprintf("Rand Intv: %fs, ",
1857 le16_to_cpu(beacon
->rand_intv
) * TU
);
1858 tprintf("Meas Duration: %fs",
1859 le16_to_cpu(beacon
->dur
) * TU
);
1860 tprintf("Mode: %u, ", beacon
->mode
);
1861 tprintf("BSSID: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1862 beacon
->bssid
[0], beacon
->bssid
[1],
1863 beacon
->bssid
[2], beacon
->bssid
[3],
1864 beacon
->bssid
[4], beacon
->bssid
[5]);
1866 if(!subelements(pkt
,
1867 meas_req
->len
- 3 - sizeof(*beacon
)))
1870 else if(meas_req
->type
== 6) {
1871 struct element_meas_frame
*frame
;
1873 frame
= (struct element_meas_frame
*)
1874 pkt_pull(pkt
, sizeof(*frame
));
1878 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*frame
)) < 0) {
1879 tprintf("Length of Req matchs not Type %u",
1884 tprintf("OP Class: %u, ", frame
->op_class
);
1885 tprintf("Ch Nr: %u, ", frame
->ch_nr
);
1886 tprintf("Rand Intv: %fs, ",
1887 le16_to_cpu(frame
->rand_intv
) * TU
);
1888 tprintf("Meas Duration: %fs",
1889 le16_to_cpu(frame
->dur
) * TU
);
1890 tprintf("Request Type: %u, ", frame
->frame
);
1891 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1892 frame
->mac
[0], frame
->mac
[1],
1893 frame
->mac
[2], frame
->mac
[3],
1894 frame
->mac
[4], frame
->mac
[5]);
1896 if(!subelements(pkt
,
1897 meas_req
->len
- 3 - sizeof(*frame
)))
1900 else if(meas_req
->type
== 7) {
1901 struct element_meas_sta
*sta
;
1903 sta
= (struct element_meas_sta
*)
1904 pkt_pull(pkt
, sizeof(*sta
));
1908 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*sta
)) < 0) {
1909 tprintf("Length of Req matchs not Type %u",
1914 tprintf("Peer MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1915 sta
->peer_mac
[0], sta
->peer_mac
[1],
1916 sta
->peer_mac
[2], sta
->peer_mac
[3],
1917 sta
->peer_mac
[4], sta
->peer_mac
[5]);
1918 tprintf("Rand Intv: %fs, ",
1919 le16_to_cpu(sta
->rand_intv
) * TU
);
1920 tprintf("Meas Duration: %fs",
1921 le16_to_cpu(sta
->dur
) * TU
);
1922 tprintf("Group ID: %u, ", sta
->group_id
);
1924 if(!subelements(pkt
,
1925 meas_req
->len
- 3 - sizeof(*sta
)))
1928 else if(meas_req
->type
== 8) {
1929 struct element_meas_lci
*lci
;
1931 lci
= (struct element_meas_lci
*)
1932 pkt_pull(pkt
, sizeof(*lci
));
1936 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*lci
)) < 0) {
1937 tprintf("Length of Req matchs not Type %u",
1942 tprintf("Location Subj: %u, ", lci
->loc_subj
);
1943 tprintf("Latitude Req Res: %udeg",
1944 lci
->latitude_req_res
);
1945 tprintf("Longitude Req Res: %udeg",
1946 lci
->longitude_req_res
);
1947 tprintf("Altitude Req Res: %udeg",
1948 lci
->altitude_req_res
);
1950 if(!subelements(pkt
,
1951 meas_req
->len
- 3 - sizeof(*lci
)))
1954 else if(meas_req
->type
== 9) {
1955 struct element_meas_trans_str_cat
*trans
;
1957 trans
= (struct element_meas_trans_str_cat
*)
1958 pkt_pull(pkt
, sizeof(*trans
));
1962 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*trans
)) < 0) {
1963 tprintf("Length of Req matchs not Type %u",
1968 tprintf("Rand Intv: %fs, ",
1969 le16_to_cpu(trans
->rand_intv
) * TU
);
1970 tprintf("Meas Duration: %fs",
1971 le16_to_cpu(trans
->dur
) * TU
);
1972 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1973 trans
->peer_sta_addr
[0], trans
->peer_sta_addr
[1],
1974 trans
->peer_sta_addr
[2], trans
->peer_sta_addr
[3],
1975 trans
->peer_sta_addr
[4], trans
->peer_sta_addr
[5]);
1976 tprintf("Traffic ID: %u, ", trans
->traffic_id
);
1977 tprintf("Bin 0 Range: %u, ", trans
->bin_0_range
);
1979 if(!subelements(pkt
,
1980 meas_req
->len
- 3 - sizeof(*trans
)))
1983 else if(meas_req
->type
== 10) {
1984 struct element_meas_mcast_diag
*mcast
;
1986 mcast
= (struct element_meas_mcast_diag
*)
1987 pkt_pull(pkt
, sizeof(*mcast
));
1991 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*mcast
)) < 0) {
1992 tprintf("Length of Req matchs not Type %u",
1997 tprintf("Rand Intv: %fs, ",
1998 le16_to_cpu(mcast
->rand_intv
) * TU
);
1999 tprintf("Meas Duration: %fs",
2000 le16_to_cpu(mcast
->dur
) * TU
);
2001 tprintf("Group MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2002 mcast
->group_mac
[0], mcast
->group_mac
[1],
2003 mcast
->group_mac
[2], mcast
->group_mac
[3],
2004 mcast
->group_mac
[4], mcast
->group_mac
[5]);
2006 if(!subelements(pkt
,
2007 meas_req
->len
- 3 - sizeof(*mcast
)))
2010 else if(meas_req
->type
== 11) {
2011 struct element_meas_loc_civic
*civic
;
2013 civic
= (struct element_meas_loc_civic
*)
2014 pkt_pull(pkt
, sizeof(*civic
));
2018 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*civic
)) < 0) {
2019 tprintf("Length of Req matchs not Type %u",
2024 tprintf("Location Subj: %u, ", civic
->loc_subj
);
2025 tprintf("Type: %u, ", civic
->civic_loc
);
2026 tprintf("Srv Intv Units: %u, ",
2027 le16_to_cpu(civic
->loc_srv_intv_unit
));
2028 tprintf("Srv Intv: %u, ", civic
->loc_srv_intv
);
2030 if(!subelements(pkt
,
2031 meas_req
->len
- 3 - sizeof(*civic
)))
2034 else if(meas_req
->type
== 12) {
2035 struct element_meas_loc_id
*id
;
2037 id
= (struct element_meas_loc_id
*)
2038 pkt_pull(pkt
, sizeof(*id
));
2042 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*id
)) < 0) {
2043 tprintf("Length of Req matchs not Type %u",
2048 tprintf("Location Subj: %u, ", id
->loc_subj
);
2049 tprintf("Srv Intv Units: %u, ",
2050 le16_to_cpu(id
->loc_srv_intv_unit
));
2051 tprintf("Srv Intv: %u", id
->loc_srv_intv
);
2053 if(!subelements(pkt
,
2054 meas_req
->len
- 3 - sizeof(*id
)))
2057 else if(meas_req
->type
== 255) {
2058 struct element_meas_pause
*pause
;
2060 pause
= (struct element_meas_pause
*)
2061 pkt_pull(pkt
, sizeof(*pause
));
2065 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*pause
)) < 0) {
2066 tprintf("Length of Req matchs not Type %u",
2071 tprintf("Pause Time: %fs, ", pause
->time
* 10 * TU
);
2073 if(!subelements(pkt
,
2074 meas_req
->len
- 3 - sizeof(*pause
)))
2078 tprintf("Length field indicates data,"
2079 " but could not interpreted");
2087 static int8_t inf_meas_rep(struct pkt_buff
*pkt
, u8
*id
)
2089 struct element_meas_rep
*meas_rep
;
2091 meas_rep
= (struct element_meas_rep
*) pkt_pull(pkt
, sizeof(*meas_rep
));
2092 if (meas_rep
== NULL
)
2095 tprintf(" Measurement Rep (%u, Len(%u)): ", *id
, meas_rep
->len
);
2096 if (len_lt_error(meas_rep
->len
, 3))
2099 tprintf("Token: %u, ", meas_rep
->token
);
2100 tprintf("Rep Mode: 0x%x (Late (%u), Incapable(%u), Refused(%u), ",
2101 meas_rep
->rep_mode
, meas_rep
->rep_mode
>> 7,
2102 (meas_rep
->rep_mode
>> 6) & 0x1,
2103 (meas_rep
->rep_mode
>> 5) & 0x1);
2104 tprintf("Type: %s (%u), ", meas_type(meas_rep
->type
), meas_rep
->type
);
2106 if(meas_rep
->len
> 3) {
2107 if(meas_rep
->type
== 0) {
2108 struct element_meas_basic
*basic
;
2110 basic
= (struct element_meas_basic
*)
2111 pkt_pull(pkt
, sizeof(*basic
));
2115 if ((meas_rep
->len
- 3 - sizeof(*basic
)) != 0) {
2116 tprintf("Length of Req matchs not Type %u",
2121 tprintf("Ch Nr: %uus, ", basic
->ch_nr
);
2122 tprintf("Meas Start Time: %lu, ",
2123 le64_to_cpu(basic
->start
));
2124 tprintf("Meas Duration: %fs",
2125 le16_to_cpu(basic
->dur
) * TU
);
2128 else if(meas_rep
->type
== 1) {
2129 struct element_meas_cca
*cca
;
2131 cca
= (struct element_meas_cca
*)
2132 pkt_pull(pkt
, sizeof(*cca
));
2136 if ((meas_rep
->len
- 3 - sizeof(*cca
)) != 0) {
2137 tprintf("Length of Req matchs not Type %u",
2142 tprintf("Ch Nr: %uus, ", cca
->ch_nr
);
2143 tprintf("Meas Start Time: %lu, ",
2144 le64_to_cpu(cca
->start
));
2145 tprintf("Meas Duration: %fs",
2146 le16_to_cpu(cca
->dur
) * TU
);
2148 else if(meas_rep
->type
== 2) {
2149 struct element_meas_rpi
*rpi
;
2151 rpi
= (struct element_meas_rpi
*)
2152 pkt_pull(pkt
, sizeof(*rpi
));
2156 if ((meas_rep
->len
- 3 - sizeof(*rpi
)) != 0) {
2157 tprintf("Length of Req matchs not Type %u",
2162 tprintf("Ch Nr: %uus, ", rpi
->ch_nr
);
2163 tprintf("Meas Start Time: %lu, ",
2164 le64_to_cpu(rpi
->start
));
2165 tprintf("Meas Duration: %fs",
2166 le16_to_cpu(rpi
->dur
) * TU
);
2168 else if(meas_rep
->type
== 3) {
2169 struct element_meas_ch_load
*ch_load
;
2171 ch_load
= (struct element_meas_ch_load
*)
2172 pkt_pull(pkt
, sizeof(*ch_load
));
2173 if (ch_load
== NULL
)
2176 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*ch_load
)) < 0) {
2177 tprintf("Length of Req matchs not Type %u",
2182 tprintf("OP Class: %u, ", ch_load
->op_class
);
2183 tprintf("Ch Nr: %u, ", ch_load
->ch_nr
);
2184 tprintf("Rand Intv: %fs, ",
2185 le16_to_cpu(ch_load
->rand_intv
) * TU
);
2186 tprintf("Meas Duration: %fs",
2187 le16_to_cpu(ch_load
->dur
) * TU
);
2189 if(!subelements(pkt
,
2190 meas_rep
->len
- 3 - sizeof(*ch_load
)))
2193 else if(meas_rep
->type
== 4) {
2194 struct element_meas_noise
*noise
;
2196 noise
= (struct element_meas_noise
*)
2197 pkt_pull(pkt
, sizeof(*noise
));
2201 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*noise
)) < 0) {
2202 tprintf("Length of Req matchs not Type %u",
2207 tprintf("OP Class: %u, ", noise
->op_class
);
2208 tprintf("Ch Nr: %u, ", noise
->ch_nr
);
2209 tprintf("Rand Intv: %fs, ",
2210 le16_to_cpu(noise
->rand_intv
) * TU
);
2211 tprintf("Meas Duration: %fs",
2212 le16_to_cpu(noise
->dur
) * TU
);
2214 if(!subelements(pkt
,
2215 meas_rep
->len
- 3 - sizeof(*noise
)))
2218 else if(meas_rep
->type
== 5) {
2219 struct element_meas_beacon
*beacon
;
2221 beacon
= (struct element_meas_beacon
*)
2222 pkt_pull(pkt
, sizeof(*beacon
));
2226 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*beacon
)) < 0) {
2227 tprintf("Length of Req matchs not Type %u",
2232 tprintf("OP Class: %u, ", beacon
->op_class
);
2233 tprintf("Ch Nr: %u, ", beacon
->ch_nr
);
2234 tprintf("Rand Intv: %fs, ",
2235 le16_to_cpu(beacon
->rand_intv
) * TU
);
2236 tprintf("Meas Duration: %fs",
2237 le16_to_cpu(beacon
->dur
) * TU
);
2238 tprintf("Mode: %u, ", beacon
->mode
);
2239 tprintf("BSSID: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2240 beacon
->bssid
[0], beacon
->bssid
[1],
2241 beacon
->bssid
[2], beacon
->bssid
[3],
2242 beacon
->bssid
[4], beacon
->bssid
[5]);
2244 if(!subelements(pkt
,
2245 meas_rep
->len
- 3 - sizeof(*beacon
)))
2248 else if(meas_rep
->type
== 6) {
2249 struct element_meas_frame
*frame
;
2251 frame
= (struct element_meas_frame
*)
2252 pkt_pull(pkt
, sizeof(*frame
));
2256 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*frame
)) < 0) {
2257 tprintf("Length of Req matchs not Type %u",
2262 tprintf("OP Class: %u, ", frame
->op_class
);
2263 tprintf("Ch Nr: %u, ", frame
->ch_nr
);
2264 tprintf("Rand Intv: %fs, ",
2265 le16_to_cpu(frame
->rand_intv
) * TU
);
2266 tprintf("Meas Duration: %fs",
2267 le16_to_cpu(frame
->dur
) * TU
);
2268 tprintf("Request Type: %u, ", frame
->frame
);
2269 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2270 frame
->mac
[0], frame
->mac
[1],
2271 frame
->mac
[2], frame
->mac
[3],
2272 frame
->mac
[4], frame
->mac
[5]);
2274 if(!subelements(pkt
,
2275 meas_rep
->len
- 3 - sizeof(*frame
)))
2278 else if(meas_rep
->type
== 7) {
2279 struct element_meas_sta
*sta
;
2281 sta
= (struct element_meas_sta
*)
2282 pkt_pull(pkt
, sizeof(*sta
));
2286 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*sta
)) < 0) {
2287 tprintf("Length of Req matchs not Type %u",
2292 tprintf("Peer MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2293 sta
->peer_mac
[0], sta
->peer_mac
[1],
2294 sta
->peer_mac
[2], sta
->peer_mac
[3],
2295 sta
->peer_mac
[4], sta
->peer_mac
[5]);
2296 tprintf("Rand Intv: %fs, ",
2297 le16_to_cpu(sta
->rand_intv
) * TU
);
2298 tprintf("Meas Duration: %fs",
2299 le16_to_cpu(sta
->dur
) * TU
);
2300 tprintf("Group ID: %u, ", sta
->group_id
);
2302 if(!subelements(pkt
,
2303 meas_rep
->len
- 3 - sizeof(*sta
)))
2306 else if(meas_rep
->type
== 8) {
2307 struct element_meas_lci
*lci
;
2309 lci
= (struct element_meas_lci
*)
2310 pkt_pull(pkt
, sizeof(*lci
));
2314 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*lci
)) < 0) {
2315 tprintf("Length of Req matchs not Type %u",
2320 tprintf("Location Subj: %u, ", lci
->loc_subj
);
2321 tprintf("Latitude Req Res: %udeg",
2322 lci
->latitude_req_res
);
2323 tprintf("Longitude Req Res: %udeg",
2324 lci
->longitude_req_res
);
2325 tprintf("Altitude Req Res: %udeg",
2326 lci
->altitude_req_res
);
2328 if(!subelements(pkt
,
2329 meas_rep
->len
- 3 - sizeof(*lci
)))
2332 else if(meas_rep
->type
== 9) {
2333 struct element_meas_trans_str_cat
*trans
;
2335 trans
= (struct element_meas_trans_str_cat
*)
2336 pkt_pull(pkt
, sizeof(*trans
));
2340 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*trans
)) < 0) {
2341 tprintf("Length of Req matchs not Type %u",
2346 tprintf("Rand Intv: %fs, ",
2347 le16_to_cpu(trans
->rand_intv
) * TU
);
2348 tprintf("Meas Duration: %fs",
2349 le16_to_cpu(trans
->dur
) * TU
);
2350 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2351 trans
->peer_sta_addr
[0], trans
->peer_sta_addr
[1],
2352 trans
->peer_sta_addr
[2], trans
->peer_sta_addr
[3],
2353 trans
->peer_sta_addr
[4], trans
->peer_sta_addr
[5]);
2354 tprintf("Traffic ID: %u, ", trans
->traffic_id
);
2355 tprintf("Bin 0 Range: %u, ", trans
->bin_0_range
);
2357 if(!subelements(pkt
,
2358 meas_rep
->len
- 3 - sizeof(*trans
)))
2361 else if(meas_rep
->type
== 10) {
2362 struct element_meas_mcast_diag
*mcast
;
2364 mcast
= (struct element_meas_mcast_diag
*)
2365 pkt_pull(pkt
, sizeof(*mcast
));
2369 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*mcast
)) < 0) {
2370 tprintf("Length of Req matchs not Type %u",
2375 tprintf("Rand Intv: %fs, ",
2376 le16_to_cpu(mcast
->rand_intv
) * TU
);
2377 tprintf("Meas Duration: %fs",
2378 le16_to_cpu(mcast
->dur
) * TU
);
2379 tprintf("Group MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2380 mcast
->group_mac
[0], mcast
->group_mac
[1],
2381 mcast
->group_mac
[2], mcast
->group_mac
[3],
2382 mcast
->group_mac
[4], mcast
->group_mac
[5]);
2384 if(!subelements(pkt
,
2385 meas_rep
->len
- 3 - sizeof(*mcast
)))
2388 else if(meas_rep
->type
== 11) {
2389 struct element_meas_loc_civic
*civic
;
2391 civic
= (struct element_meas_loc_civic
*)
2392 pkt_pull(pkt
, sizeof(*civic
));
2396 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*civic
)) < 0) {
2397 tprintf("Length of Req matchs not Type %u",
2402 tprintf("Location Subj: %u, ", civic
->loc_subj
);
2403 tprintf("Type: %u, ", civic
->civic_loc
);
2404 tprintf("Srv Intv Units: %u, ",
2405 le16_to_cpu(civic
->loc_srv_intv_unit
));
2406 tprintf("Srv Intv: %u, ", civic
->loc_srv_intv
);
2408 if(!subelements(pkt
,
2409 meas_rep
->len
- 3 - sizeof(*civic
)))
2412 else if(meas_rep
->type
== 12) {
2413 struct element_meas_loc_id
*id
;
2415 id
= (struct element_meas_loc_id
*)
2416 pkt_pull(pkt
, sizeof(*id
));
2420 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*id
)) < 0) {
2421 tprintf("Length of Req matchs not Type %u",
2426 tprintf("Location Subj: %u, ", id
->loc_subj
);
2427 tprintf("Srv Intv Units: %u, ",
2428 le16_to_cpu(id
->loc_srv_intv_unit
));
2429 tprintf("Srv Intv: %u", id
->loc_srv_intv
);
2431 if(!subelements(pkt
,
2432 meas_rep
->len
- 3 - sizeof(*id
)))
2436 tprintf("Length field indicates data,"
2437 " but could not interpreted");
2445 static int8_t inf_quiet(struct pkt_buff
*pkt
, u8
*id
)
2447 struct element_quiet
*quiet
;
2449 quiet
= (struct element_quiet
*) pkt_pull(pkt
, sizeof(*quiet
));
2453 tprintf(" Quit (%u, Len(%u)): ", *id
, quiet
->len
);
2454 if (len_neq_error(quiet
->len
, 6))
2457 tprintf("Count: %ud, ", quiet
->cnt
);
2458 tprintf("Period: %u, ", quiet
->period
);
2459 tprintf("Duration: %fs, ", le16_to_cpu(quiet
->dur
) * TU
);
2460 tprintf("Offs: %fs", le16_to_cpu(quiet
->offs
) * TU
);
2466 static int8_t inf_ibss_dfs(struct pkt_buff
*pkt
, u8
*id
)
2468 struct element_ibss_dfs
*ibss_dfs
;
2471 ibss_dfs
= (struct element_ibss_dfs
*) pkt_pull(pkt
, sizeof(*ibss_dfs
));
2472 if (ibss_dfs
== NULL
)
2475 tprintf(" IBSS DFS (%u, Len(%u)): ", *id
, ibss_dfs
->len
);
2476 if (len_lt_error(ibss_dfs
->len
, 7))
2479 tprintf("Owner: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2480 ibss_dfs
->owner
[0], ibss_dfs
->owner
[1],
2481 ibss_dfs
->owner
[2], ibss_dfs
->owner
[3],
2482 ibss_dfs
->owner
[4], ibss_dfs
->owner
[5]);
2483 tprintf("Recovery Intv: %u, ", ibss_dfs
->rec_intv
);
2485 if((ibss_dfs
->len
- sizeof(*ibss_dfs
) + 1) & 1) {
2486 tprintf("Length of Channel Map should be modulo 2");
2490 for (i
= 0; i
< ibss_dfs
->len
; i
+= 2) {
2491 struct element_ibss_dfs_tuple
*ibss_dfs_tuple
;
2493 ibss_dfs_tuple
= (struct element_ibss_dfs_tuple
*)
2494 pkt_pull(pkt
, sizeof(*ibss_dfs_tuple
));
2495 if (ibss_dfs_tuple
== NULL
)
2498 tprintf("Channel Nr: %u, ", ibss_dfs_tuple
->ch_nr
);
2499 tprintf("Map: %u, ", ibss_dfs_tuple
->map
);
2505 static int8_t inf_erp(struct pkt_buff
*pkt
, u8
*id
)
2507 struct element_erp
*erp
;
2509 erp
= (struct element_erp
*) pkt_pull(pkt
, sizeof(*erp
));
2513 tprintf(" ERP (%u, Len(%u)): ", *id
, erp
->len
);
2514 if (len_neq_error(erp
->len
, 1))
2516 tprintf("Non ERP Present (%u), ", erp
->param
& 0x1);
2517 tprintf("Use Protection (%u), ", (erp
->param
>> 1) & 0x1);
2518 tprintf("Barker Preamble Mode (%u), ", (erp
->param
>> 2) & 0x1);
2519 tprintf("Reserved (0x%.5x)", erp
->param
>> 3);
2524 static int8_t inf_ts_del(struct pkt_buff
*pkt
, u8
*id
)
2526 struct element_ts_del
*ts_del
;
2528 ts_del
= (struct element_ts_del
*) pkt_pull(pkt
, sizeof(*ts_del
));
2532 tprintf(" TS Delay (%u, Len(%u)): ", *id
, ts_del
->len
);
2533 if (len_neq_error(ts_del
->len
, 4))
2535 tprintf("Delay (%fs)", le32_to_cpu(ts_del
->delay
) * TU
);
2540 static int8_t inf_tclas_proc(struct pkt_buff
*pkt
, u8
*id
)
2542 struct element_tclas_proc
*tclas_proc
;
2544 tclas_proc
= (struct element_tclas_proc
*)
2545 pkt_pull(pkt
, sizeof(*tclas_proc
));
2546 if (tclas_proc
== NULL
)
2549 tprintf(" TCLAS Procesing (%u, Len(%u)): ", *id
, tclas_proc
->len
);
2550 if (len_neq_error(tclas_proc
->len
, 1))
2552 tprintf("Processing (%u)", tclas_proc
->proc
);
2557 static int8_t inf_ht_cap(struct pkt_buff
*pkt
, u8
*id
)
2559 struct element_ht_cap
*ht_cap
;
2560 u32 tx_param_res
, beam_cap
;
2563 ht_cap
= (struct element_ht_cap
*)
2564 pkt_pull(pkt
, sizeof(*ht_cap
));
2568 tx_param_res
= le32_to_cpu(ht_cap
->tx_param_res
);
2569 beam_cap
= le32_to_cpu(ht_cap
->beam_cap
);
2570 ext_cap
= le16_to_cpu(ht_cap
->ext_cap
);
2572 tprintf(" HT Capabilities (%u, Len(%u)): ", *id
, ht_cap
->len
);
2573 if (len_neq_error(ht_cap
->len
, 26))
2575 tprintf("Info (LDCP Cod Cap (%u), Supp Ch Width Set (%u),"
2576 " SM Pwr Save(%u), HT-Greenfield (%u), Short GI for 20/40 MHz"
2577 " (%u/%u), Tx/Rx STBC (%u/%u), HT-Delayed Block Ack (%u),"
2578 " Max A-MSDU Len (%u), DSSS/CCK Mode in 40 MHz (%u),"
2579 " Res (0x%x), Forty MHz Intol (%u), L-SIG TXOP Protection Supp"
2580 " (%u)), ", ht_cap
->ldpc
, ht_cap
->supp_width
,
2581 ht_cap
->sm_pwr
, ht_cap
->ht_green
, ht_cap
->gi_20mhz
,
2582 ht_cap
->gi_40mhz
, ht_cap
->tx_stbc
, ht_cap
->rx_stbc
,
2583 ht_cap
->ht_ack
, ht_cap
->max_msdu_length
, ht_cap
->dsss_ck_mode
,
2584 ht_cap
->res
, ht_cap
->forty_int
, ht_cap
->prot_supp
);
2585 tprintf("A-MPDU Params (Max Len Exp (%u), Min Start Spacing (%u),"
2586 " Res (0x%x)), ", ht_cap
->param
>> 6, (ht_cap
->param
>> 3) & 0x7,
2587 ht_cap
->param
& 0x07);
2588 tprintf("Supp MCS Set (Rx MCS Bitmask (0x%x%x%x%x%x%x%x%x%x%x),"
2589 " Res (0x%x), Rx High Supp Data Rate (%u), Res (0x%x),"
2590 " Tx MCS Set Def (%u), Tx Rx MCS Set Not Eq (%u),"
2591 " Tx Max Number Spat Str Supp (%u),"
2592 " Tx Uneq Mod Supp (%u), Res (0x%x)), ",
2593 ht_cap
->bitmask1
, ht_cap
->bitmask2
, ht_cap
->bitmask3
,
2594 ht_cap
->bitmask4
, ht_cap
->bitmask5
, ht_cap
->bitmask6
,
2595 ht_cap
->bitmask7
, ht_cap
->bitmask8
, ht_cap
->bitmask9
,
2596 ht_cap
->bitmask10_res
>> 3, ht_cap
->bitmask10_res
& 0x7,
2597 le16_to_cpu(ht_cap
->supp_rate_res
) >> 6,
2598 le16_to_cpu(ht_cap
->supp_rate_res
) & 0x3F,
2599 tx_param_res
>> 31, (tx_param_res
>> 30) & 1,
2600 (tx_param_res
>> 28) & 3, (tx_param_res
>> 27) & 1,
2601 tx_param_res
& 0x7FFFFFF);
2602 tprintf("Ext Cap (PCO (%u), PCO Trans Time (%u), Res (0x%x),"
2603 " MCS Feedb (%u), +HTC Supp (%u), RD Resp (%u), Res (0x%x)), ",
2604 ext_cap
>> 15, (ext_cap
>> 13) & 3, (ext_cap
>> 8) & 0x1F,
2605 (ext_cap
>> 6) & 3, (ext_cap
>> 5) & 1, (ext_cap
>> 4) & 1,
2607 tprintf("Transm Beamf (Impl Transm Beamf Rec Cap (%u),"
2608 " Rec/Transm Stagg Sound Cap (%u/%u),"
2609 " Rec/Trans NDP Cap (%u/%u), Impl Transm Beamf Cap (%u),"
2610 " Cal (%u), Expl CSI Transm Beamf Cap (%u),"
2611 " Expl Noncmpr/Compr Steering Cap (%u/%u),"
2612 " Expl Trans Beamf CSI Feedb (%u),"
2613 " Expl Noncmpr/Cmpr Feedb Cap (%u/%u),"
2614 " Min Grpg (%u), CSI Num Beamf Ant Supp (%u),"
2615 " Noncmpr/Cmpr Steering Nr Beamf Ant Supp (%u/%u),"
2616 " CSI Max Nr Rows Beamf Supp (%u),"
2617 " Ch Estim Cap (%u), Res (0x%x)), ",
2618 beam_cap
>> 31, (beam_cap
>> 30) & 1, (beam_cap
>> 29) & 1,
2619 (beam_cap
>> 28) & 1, (beam_cap
>> 27) & 1, (beam_cap
>> 26) & 1,
2620 (beam_cap
>> 24) & 3, (beam_cap
>> 23) & 1, (beam_cap
>> 22) & 1,
2621 (beam_cap
>> 21) & 1, (beam_cap
>> 19) & 3, (beam_cap
>> 17) & 3,
2622 (beam_cap
>> 15) & 3, (beam_cap
>> 13) & 3, (beam_cap
>> 11) & 3,
2623 (beam_cap
>> 9) & 3, (beam_cap
>> 7) & 3, (beam_cap
>> 5) & 3,
2624 (beam_cap
>> 3) & 3, beam_cap
& 7);
2625 tprintf("ASEL (Ant Select Cap (%u),"
2626 " Expl CSI Feedb Based Transm ASEL Cap (%u),"
2627 " Ant Indic Feedb Based Transm ASEL Cap (%u),"
2628 " Expl CSI Feedb Cap (%u), Ant Indic Feedb Cap (%u),"
2629 " Rec ASEL Cap (%u), Transm Sound PPDUs Cap (%u), Res (0x%x))",
2630 ht_cap
->asel_cap
>> 7, (ht_cap
->asel_cap
>> 6) & 1,
2631 (ht_cap
->asel_cap
>> 5) & 1, (ht_cap
->asel_cap
>> 4) & 1,
2632 (ht_cap
->asel_cap
>> 3) & 1, (ht_cap
->asel_cap
>> 2) & 1,
2633 (ht_cap
->asel_cap
>> 1) & 1, ht_cap
->asel_cap
& 1);
2638 static int8_t inf_qos_cap(struct pkt_buff
*pkt
, u8
*id
)
2640 struct element_qos_cap
*qos_cap
;
2642 qos_cap
= (struct element_qos_cap
*)
2643 pkt_pull(pkt
, sizeof(*qos_cap
));
2644 if (qos_cap
== NULL
)
2647 tprintf(" QoS Capabilities (%u, Len(%u)): ", *id
, qos_cap
->len
);
2648 if (len_neq_error(qos_cap
->len
, 1))
2651 tprintf("Info (0x%x)", qos_cap
->info
);
2656 static int8_t inf_ext_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
2660 struct element_ext_supp_rates
*ext_supp_rates
;
2662 ext_supp_rates
= (struct element_ext_supp_rates
*)
2663 pkt_pull(pkt
, sizeof(*ext_supp_rates
));
2664 if (ext_supp_rates
== NULL
)
2667 tprintf(" Ext Support Rates (%u, Len(%u)): ", *id
, ext_supp_rates
->len
);
2669 if ((ext_supp_rates
->len
- sizeof(*ext_supp_rates
) + 1) > 0) {
2670 rates
= pkt_pull(pkt
, ext_supp_rates
->len
);
2674 for (i
= 0; i
< ext_supp_rates
->len
; i
++)
2675 tprintf("%g ", (rates
[i
] & 0x80) ?
2676 ((rates
[i
] & 0x3f) * 0.5) :
2677 data_rates(rates
[i
]));
2684 static int8_t inf_vend_spec(struct pkt_buff
*pkt
, u8
*id
)
2688 struct element_vend_spec
*vend_spec
;
2690 vend_spec
= (struct element_vend_spec
*)
2691 pkt_pull(pkt
, sizeof(*vend_spec
));
2692 if (vend_spec
== NULL
)
2695 tprintf(" Vendor Specific (%u, Len (%u)): ", *id
, vend_spec
->len
);
2697 data
= pkt_pull(pkt
, vend_spec
->len
);
2702 for (i
= 0; i
< vend_spec
->len
; i
++)
2703 tprintf("%.2x", data
[i
]);
2708 static int8_t inf_unimplemented(struct pkt_buff
*pkt __maybe_unused
,
2709 u8
*id __maybe_unused
)
2714 static int8_t inf_elements(struct pkt_buff
*pkt
)
2716 u8
*id
= pkt_pull(pkt
, 1);
2721 case 0: return inf_ssid(pkt
, id
);
2722 case 1: return inf_supp_rates(pkt
, id
);
2723 case 2: return inf_fh_ps(pkt
, id
);
2724 case 3: return inf_dsss_ps(pkt
, id
);
2725 case 4: return inf_cf_ps(pkt
, id
);
2726 case 5: return inf_tim(pkt
, id
);
2727 case 6: return inf_ibss_ps(pkt
, id
);
2728 case 7: return inf_country(pkt
, id
);
2729 case 8: return inf_hop_pp(pkt
, id
);
2730 case 9: return inf_hop_pt(pkt
, id
);
2731 case 10: return inf_req(pkt
, id
);
2732 case 11: return inf_bss_load(pkt
, id
);
2733 case 12: return inf_edca_ps(pkt
, id
);
2734 case 13: return inf_tspec(pkt
, id
);
2735 case 14: return inf_tclas(pkt
, id
);
2736 case 15: return inf_sched(pkt
, id
);
2737 case 16: return inf_chall_txt(pkt
, id
);
2738 case 17 ... 31: return inf_reserved(pkt
, id
);
2739 case 32: return inf_pwr_constr(pkt
, id
);
2740 case 33: return inf_pwr_cap(pkt
, id
);
2741 case 34: return inf_tpc_req(pkt
, id
);
2742 case 35: return inf_tpc_rep(pkt
, id
);
2743 case 36: return inf_supp_ch(pkt
, id
);
2744 case 37: return inf_ch_sw_ann(pkt
, id
);
2745 case 38: return inf_meas_req(pkt
, id
);
2746 case 39: return inf_meas_rep(pkt
, id
);
2747 case 40: return inf_quiet(pkt
, id
);
2748 case 41: return inf_ibss_dfs(pkt
, id
);
2749 case 42: return inf_erp(pkt
, id
);
2750 case 43: return inf_ts_del(pkt
, id
);
2751 case 44: return inf_tclas_proc(pkt
, id
);
2752 case 45: return inf_ht_cap(pkt
, id
);
2753 case 46: return inf_qos_cap(pkt
, id
);
2754 case 47: return inf_reserved(pkt
, id
);
2755 case 48: return inf_unimplemented(pkt
, id
);
2756 case 49: return inf_unimplemented(pkt
, id
);
2757 case 50: return inf_ext_supp_rates(pkt
, id
);
2758 case 51: return inf_unimplemented(pkt
, id
);
2759 case 52: return inf_unimplemented(pkt
, id
);
2760 case 53: return inf_unimplemented(pkt
, id
);
2761 case 54: return inf_unimplemented(pkt
, id
);
2762 case 55: return inf_unimplemented(pkt
, id
);
2763 case 56: return inf_unimplemented(pkt
, id
);
2764 case 57: return inf_unimplemented(pkt
, id
);
2765 case 58: return inf_unimplemented(pkt
, id
);
2766 case 59: return inf_unimplemented(pkt
, id
);
2767 case 60: return inf_unimplemented(pkt
, id
);
2768 case 61: return inf_unimplemented(pkt
, id
);
2769 case 62: return inf_unimplemented(pkt
, id
);
2770 case 63: return inf_unimplemented(pkt
, id
);
2771 case 64: return inf_unimplemented(pkt
, id
);
2772 case 65: return inf_unimplemented(pkt
, id
);
2773 case 66: return inf_unimplemented(pkt
, id
);
2774 case 67: return inf_unimplemented(pkt
, id
);
2775 case 68: return inf_unimplemented(pkt
, id
);
2776 case 69: return inf_unimplemented(pkt
, id
);
2777 case 70: return inf_unimplemented(pkt
, id
);
2778 case 71: return inf_unimplemented(pkt
, id
);
2779 case 72: return inf_unimplemented(pkt
, id
);
2780 case 73: return inf_unimplemented(pkt
, id
);
2781 case 74: return inf_unimplemented(pkt
, id
);
2782 case 75: return inf_unimplemented(pkt
, id
);
2783 case 76: return inf_unimplemented(pkt
, id
);
2784 case 78: return inf_unimplemented(pkt
, id
);
2785 case 79: return inf_unimplemented(pkt
, id
);
2786 case 80: return inf_unimplemented(pkt
, id
);
2787 case 81: return inf_unimplemented(pkt
, id
);
2788 case 82: return inf_unimplemented(pkt
, id
);
2789 case 83: return inf_unimplemented(pkt
, id
);
2790 case 84: return inf_unimplemented(pkt
, id
);
2791 case 85: return inf_unimplemented(pkt
, id
);
2792 case 86: return inf_unimplemented(pkt
, id
);
2793 case 87: return inf_unimplemented(pkt
, id
);
2794 case 88: return inf_unimplemented(pkt
, id
);
2795 case 89: return inf_unimplemented(pkt
, id
);
2796 case 90: return inf_unimplemented(pkt
, id
);
2797 case 91: return inf_unimplemented(pkt
, id
);
2798 case 92: return inf_unimplemented(pkt
, id
);
2799 case 93: return inf_unimplemented(pkt
, id
);
2800 case 94: return inf_unimplemented(pkt
, id
);
2801 case 95: return inf_unimplemented(pkt
, id
);
2802 case 96: return inf_unimplemented(pkt
, id
);
2803 case 97: return inf_unimplemented(pkt
, id
);
2804 case 98: return inf_unimplemented(pkt
, id
);
2805 case 99: return inf_unimplemented(pkt
, id
);
2806 case 100: return inf_unimplemented(pkt
, id
);
2807 case 101: return inf_unimplemented(pkt
, id
);
2808 case 102: return inf_unimplemented(pkt
, id
);
2809 case 104: return inf_unimplemented(pkt
, id
);
2810 case 105: return inf_unimplemented(pkt
, id
);
2811 case 106: return inf_unimplemented(pkt
, id
);
2812 case 107: return inf_unimplemented(pkt
, id
);
2813 case 108: return inf_unimplemented(pkt
, id
);
2814 case 109: return inf_unimplemented(pkt
, id
);
2815 case 110: return inf_unimplemented(pkt
, id
);
2816 case 111: return inf_unimplemented(pkt
, id
);
2817 case 112: return inf_unimplemented(pkt
, id
);
2818 case 113: return inf_unimplemented(pkt
, id
);
2819 case 114: return inf_unimplemented(pkt
, id
);
2820 case 115: return inf_unimplemented(pkt
, id
);
2821 case 116: return inf_unimplemented(pkt
, id
);
2822 case 117: return inf_unimplemented(pkt
, id
);
2823 case 118: return inf_unimplemented(pkt
, id
);
2824 case 119: return inf_unimplemented(pkt
, id
);
2825 case 120: return inf_unimplemented(pkt
, id
);
2826 case 121: return inf_unimplemented(pkt
, id
);
2827 case 122: return inf_unimplemented(pkt
, id
);
2828 case 123: return inf_unimplemented(pkt
, id
);
2829 case 124: return inf_unimplemented(pkt
, id
);
2830 case 125: return inf_unimplemented(pkt
, id
);
2831 case 126: return inf_unimplemented(pkt
, id
);
2832 case 127: return inf_unimplemented(pkt
, id
);
2833 case 128: return inf_reserved(pkt
, id
);
2834 case 129: return inf_reserved(pkt
, id
);
2835 case 130: return inf_unimplemented(pkt
, id
);
2836 case 131: return inf_unimplemented(pkt
, id
);
2837 case 132: return inf_unimplemented(pkt
, id
);
2838 case 133: return inf_reserved(pkt
, id
);
2839 case 134: return inf_reserved(pkt
, id
);
2840 case 135: return inf_reserved(pkt
, id
);
2841 case 136: return inf_reserved(pkt
, id
);
2842 case 137: return inf_unimplemented(pkt
, id
);
2843 case 138: return inf_unimplemented(pkt
, id
);
2844 case 139: return inf_unimplemented(pkt
, id
);
2845 case 140: return inf_unimplemented(pkt
, id
);
2846 case 141: return inf_unimplemented(pkt
, id
);
2847 case 142: return inf_unimplemented(pkt
, id
);
2848 case 143 ... 173: return inf_reserved(pkt
, id
);
2849 case 174: return inf_unimplemented(pkt
, id
);
2850 case 221: return inf_vend_spec(pkt
, id
);
2856 #define ESS 0b0000000000000001
2857 #define IBSS 0b0000000000000010
2858 #define CF_Pollable 0b0000000000000100
2859 #define CF_Poll_Req 0b0000000000001000
2860 #define Privacy 0b0000000000010000
2861 #define Short_Pre 0b0000000000100000
2862 #define PBCC 0b0000000001000000
2863 #define Ch_Agility 0b0000000010000000
2864 #define Spec_Mgmt 0b0000000100000000
2865 #define QoS 0b0000001000000000
2866 #define Short_Slot_t 0b0000010000000000
2867 #define APSD 0b0000100000000000
2868 #define Radio_Meas 0b0001000000000000
2869 #define DSSS_OFDM 0b0010000000000000
2870 #define Del_Block_ACK 0b0100000000000000
2871 #define Imm_Block_ACK 0b1000000000000000
2873 static int8_t cap_field(u16 cap_inf
)
2879 if (CF_Pollable
& cap_inf
)
2880 tprintf(" CF Pollable;");
2881 if (CF_Poll_Req
& cap_inf
)
2882 tprintf(" CF-Poll Request;");
2883 if (Privacy
& cap_inf
)
2884 tprintf(" Privacy;");
2885 if (Short_Pre
& cap_inf
)
2886 tprintf(" Short Preamble;");
2889 if (Ch_Agility
& cap_inf
)
2890 tprintf(" Channel Agility;");
2891 if (Spec_Mgmt
& cap_inf
)
2892 tprintf(" Spectrum Management;");
2895 if (Short_Slot_t
& cap_inf
)
2896 tprintf(" Short Slot Time;");
2899 if (Radio_Meas
& cap_inf
)
2900 tprintf(" Radio Measurement;");
2901 if (DSSS_OFDM
& cap_inf
)
2902 tprintf(" DSSS-OFDM;");
2903 if (Del_Block_ACK
& cap_inf
)
2904 tprintf(" Delayed Block Ack;");
2905 if (Imm_Block_ACK
& cap_inf
)
2906 tprintf(" Immediate Block Ack;");
2911 /* Management Dissectors */
2912 static int8_t beacon(struct pkt_buff
*pkt
)
2914 struct ieee80211_mgmt_beacon
*beacon
;
2916 beacon
= (struct ieee80211_mgmt_beacon
*)
2917 pkt_pull(pkt
, sizeof(*beacon
));
2921 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon
->timestamp
));
2922 tprintf("Beacon Interval (%fs), ", le16_to_cpu(beacon
->beacon_int
)*TU
);
2923 tprintf("Capabilities (0x%x <->", le16_to_cpu(beacon
->capab_info
));
2924 cap_field(le16_to_cpu(beacon
->capab_info
));
2928 tprintf("\n\tParameters:");
2929 while (inf_elements(pkt
)) {
2939 static int8_t mgmt_unimplemented(struct pkt_buff
*pkt __maybe_unused
)
2943 /* End Management Dissectors */
2945 /* Control Dissectors */
2946 static int8_t ctrl_unimplemented(struct pkt_buff
*pkt __maybe_unused
)
2950 /* End Control Dissectors */
2952 /* Data Dissectors */
2953 static int8_t data_unimplemented(struct pkt_buff
*pkt __maybe_unused
)
2957 /* End Data Dissectors */
2959 static const char *mgt_sub(u8 subtype
, struct pkt_buff
*pkt
,
2960 int8_t (**get_content
)(struct pkt_buff
*pkt
))
2963 struct ieee80211_mgmt
*mgmt
;
2964 const char *dst
, *src
, *bssid
;
2966 mgmt
= (struct ieee80211_mgmt
*) pkt_pull(pkt
, sizeof(*mgmt
));
2970 dst
= lookup_vendor((mgmt
->da
[0] << 16) |
2971 (mgmt
->da
[1] << 8) |
2973 src
= lookup_vendor((mgmt
->sa
[0] << 16) |
2974 (mgmt
->sa
[1] << 8) |
2977 bssid
= lookup_vendor((mgmt
->bssid
[0] << 16) |
2978 (mgmt
->bssid
[1] << 8) |
2980 seq_ctrl
= le16_to_cpu(mgmt
->seq_ctrl
);
2982 tprintf("Duration (%u),", le16_to_cpu(mgmt
->duration
));
2983 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
2984 mgmt
->da
[0], mgmt
->da
[1], mgmt
->da
[2],
2985 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
2987 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst
,
2988 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
2991 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
2992 mgmt
->sa
[0], mgmt
->sa
[1], mgmt
->sa
[2],
2993 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
2995 tprintf("=> (%s:%.2x:%.2x:%.2x)", src
,
2996 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
2999 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3000 mgmt
->bssid
[0], mgmt
->bssid
[1], mgmt
->bssid
[2],
3001 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
3003 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid
,
3004 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
3007 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ",
3008 seq_ctrl
& 0xf, seq_ctrl
>> 4);
3012 *get_content
= mgmt_unimplemented
;
3013 return "Association Request";
3015 *get_content
= mgmt_unimplemented
;
3016 return "Association Response";
3018 *get_content
= mgmt_unimplemented
;
3019 return "Reassociation Request";
3021 *get_content
= mgmt_unimplemented
;
3022 return "Reassociation Response";
3024 *get_content
= mgmt_unimplemented
;
3025 return "Probe Request";
3027 *get_content
= mgmt_unimplemented
;
3028 return "Probe Response";
3030 *get_content
= beacon
;
3033 *get_content
= mgmt_unimplemented
;
3036 *get_content
= mgmt_unimplemented
;
3037 return "Disassociation";
3039 *get_content
= mgmt_unimplemented
;
3040 return "Authentication";
3042 *get_content
= mgmt_unimplemented
;
3043 return "Deauthentication";
3044 case 0b0110 ... 0b0111:
3045 case 0b1101 ... 0b1111:
3046 *get_content
= NULL
;
3049 *get_content
= NULL
;
3050 return "Management SubType unknown";
3054 static const char *ctrl_sub(u8 subtype
, struct pkt_buff
*pkt __maybe_unused
,
3055 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3059 *get_content
= ctrl_unimplemented
;
3062 *get_content
= ctrl_unimplemented
;
3065 *get_content
= ctrl_unimplemented
;
3068 *get_content
= ctrl_unimplemented
;
3071 *get_content
= ctrl_unimplemented
;
3074 *get_content
= ctrl_unimplemented
;
3075 return "CF End + CF-ACK";
3076 case 0b0000 ... 0b1001:
3077 *get_content
= NULL
;
3080 return "Control SubType unknown";
3084 static const char *data_sub(u8 subtype
, struct pkt_buff
*pkt __maybe_unused
,
3085 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3089 *get_content
= data_unimplemented
;
3092 *get_content
= data_unimplemented
;
3093 return "Data + CF-ACK";
3095 *get_content
= data_unimplemented
;
3096 return "Data + CF-Poll";
3098 *get_content
= data_unimplemented
;
3099 return "Data + CF-ACK + CF-Poll";
3101 *get_content
= data_unimplemented
;
3104 *get_content
= data_unimplemented
;
3107 *get_content
= data_unimplemented
;
3110 *get_content
= data_unimplemented
;
3111 return "CF-ACK + CF-Poll";
3112 case 0b1000 ... 0b1111:
3113 *get_content
= NULL
;
3116 *get_content
= NULL
;
3117 return "Data SubType unknown";
3122 frame_control_type(u8 type
, const char *(**get_subtype
)(u8 subtype
,
3123 struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)))
3127 *get_subtype
= mgt_sub
;
3128 return "Management";
3130 *get_subtype
= ctrl_sub
;
3133 *get_subtype
= data_sub
;
3136 *get_subtype
= NULL
;
3139 *get_subtype
= NULL
;
3140 return "Control Type unknown";
3144 static void ieee80211(struct pkt_buff
*pkt
)
3146 int8_t (*get_content
)(struct pkt_buff
*pkt
) = NULL
;
3147 const char *(*get_subtype
)(u8 subtype
, struct pkt_buff
*pkt
,
3148 int8_t (**get_content
)(struct pkt_buff
*pkt
)) = NULL
;
3149 const char *subtype
= NULL
;
3150 struct ieee80211_frm_ctrl
*frm_ctrl
;
3152 frm_ctrl
= (struct ieee80211_frm_ctrl
*)
3153 pkt_pull(pkt
, sizeof(*frm_ctrl
));
3154 if (frm_ctrl
== NULL
)
3157 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
3158 le16_to_cpu(frm_ctrl
->frame_control
));
3160 tprintf(" [ Proto Version (%u), ", frm_ctrl
->proto_version
);
3161 tprintf("Type (%u, %s), ", frm_ctrl
->type
,
3162 frame_control_type(frm_ctrl
->type
, &get_subtype
));
3164 subtype
= (*get_subtype
)(frm_ctrl
->subtype
, pkt
, &get_content
);
3165 tprintf("Subtype (%u, %s)", frm_ctrl
->subtype
, subtype
);
3167 tprintf("%s%s%s", colorize_start_full(black
, red
),
3168 "No SubType Data available", colorize_end());
3171 tprintf("%s%s", frm_ctrl
->to_ds
? ", Frame goes to DS" : "",
3172 frm_ctrl
->from_ds
? ", Frame comes from DS" : "");
3173 tprintf("%s", frm_ctrl
->more_frags
? ", More Fragments" : "");
3174 tprintf("%s", frm_ctrl
->retry
? ", Frame is retransmitted" : "");
3175 tprintf("%s", frm_ctrl
->power_mgmt
? ", In Power Saving Mode" : "");
3176 tprintf("%s", frm_ctrl
->more_data
? ", More Data" : "");
3177 tprintf("%s", frm_ctrl
->wep
? ", Needs WEP" : "");
3178 tprintf("%s", frm_ctrl
->order
? ", Order" : "");
3182 tprintf(" [ Subtype %s: ", subtype
);
3183 if (!((*get_content
) (pkt
)))
3184 tprintf("%s%s%s", colorize_start_full(black
, red
),
3185 "Failed to dissect Subtype", colorize_end());
3188 tprintf("%s%s%s", colorize_start_full(black
, red
),
3189 "No SubType Data available", colorize_end());
3194 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
3197 static void ieee80211_less(struct pkt_buff
*pkt __maybe_unused
)
3199 tprintf("802.11 frame (more on todo)");
3202 struct protocol ieee80211_ops
= {
3204 .print_full
= ieee80211
,
3205 .print_less
= ieee80211_less
,