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)
16 #include <netinet/in.h> /* for ntohs() */
17 #include <asm/byteorder.h>
18 #include <arpa/inet.h> /* for inet_ntop() */
21 #include "dissector_80211.h"
29 /* Note: Fields are encoded in little-endian! */
30 struct ieee80211_frm_ctrl
{
34 #if defined(__LITTLE_ENDIAN_BITFIELD)
35 /* Correct order here ... */
36 __extension__ u16 proto_version
:2,
47 #elif defined(__BIG_ENDIAN_BITFIELD)
48 __extension__ u16 subtype
:4,
60 # error "Adjust your <asm/byteorder.h> defines"
66 /* Management Frame start */
67 /* Note: Fields are encoded in little-endian! */
68 struct ieee80211_mgmt
{
76 struct ieee80211_mgmt_auth
{
80 /* possibly followed by Challenge text */
84 struct ieee80211_mgmt_deauth
{
88 struct ieee80211_mgmt_assoc_req
{
91 /* followed by SSID and Supported rates */
95 struct ieee80211_mgmt_assoc_resp
{
99 /* followed by Supported rates */
103 struct ieee80211_mgmt_reassoc_resp
{
107 /* followed by Supported rates */
111 struct ieee80211_mgmt_reassoc_req
{
115 /* followed by SSID and Supported rates */
119 struct ieee80211_mgmt_disassoc
{
123 struct ieee80211_mgmt_probe_req
{
126 struct ieee80211_mgmt_beacon
{
130 /* followed by some of SSID, Supported rates,
131 * FH Params, DS Params, CF Params, IBSS Params, TIM */
135 struct ieee80211_mgmt_probe_resp
{
139 /* followed by some of SSID, Supported rates,
140 * FH Params, DS Params, CF Params, IBSS Params, TIM */
143 /* Management Frame end */
145 /* Control Frame start */
146 /* Note: Fields are encoded in little-endian! */
147 struct ieee80211_ctrl
{
150 struct ieee80211_ctrl_rts
{
156 struct ieee80211_ctrl_cts
{
161 struct ieee80211_ctrl_ack
{
166 struct ieee80211_ctrl_ps_poll
{
172 struct ieee80211_ctrl_cf_end
{
178 struct ieee80211_ctrl_cf_end_ack
{
183 /* Control Frame end */
185 /* Data Frame start */
186 /* Note: Fields are encoded in little-endian! */
187 struct ieee80211_data
{
193 struct element_reserved
{
197 struct element_ssid
{
202 struct element_supp_rates
{
207 struct element_fh_ps
{
215 struct element_dsss_ps
{
220 struct element_cf_ps
{
236 struct element_ibss_ps
{
241 struct element_country_tripled
{
247 struct element_country
{
249 #if defined(__LITTLE_ENDIAN_BITFIELD)
250 /* Correct order here ... */
254 #elif defined(__BIG_ENDIAN_BITFIELD)
259 # error "Adjust your <asm/byteorder.h> defines"
261 /* triplet may repeat */
262 struct element_country_tripled tripled
[0];
267 struct element_hop_pp
{
273 struct element_hop_pt
{
287 struct element_bss_load
{
294 struct element_edca_ps
{
304 struct element_tspec
{
308 #if defined(__LITTLE_ENDIAN_BITFIELD)
309 /* Correct order here ... */
310 __extension__ u32 len
:8,
321 #elif defined(__BIG_ENDIAN_BITFIELD)
322 __extension__ u32 len
:8,
334 # error "Adjust your <asm/byteorder.h> defines"
351 u16 surplus_bandw_allow
;
355 struct element_tclas
{
361 struct element_tclas_frm_class
{
367 struct element_tclas_type0
{
373 struct element_tclas_type1
{
378 struct element_tclas_type1_ip4
{
388 struct element_tclas_type1_ip6
{
396 #if defined(__LITTLE_ENDIAN_BITFIELD)
397 __extension__ u8 flow_label3
:8;
398 __extension__ u8 flow_label2
:8;
399 __extension__ u8 flow_label1
:8;
400 #elif defined(__BIG_ENDIAN_BITFIELD)
401 __extension__ u8 flow_label1
:8;
402 __extension__ u8 flow_label2
:8;
403 __extension__ u8 flow_label3
:8;
405 # error "Adjust your <asm/byteorder.h> defines"
411 struct element_tclas_type2
{
415 struct element_tclas_type3
{
421 struct element_tclas_type4
{
426 struct element_tclas_type4_ip4
{
436 struct element_tclas_type4_ip6
{
446 #if defined(__LITTLE_ENDIAN_BITFIELD)
447 __extension__ u8 flow_label3
:8;
448 __extension__ u8 flow_label2
:8;
449 __extension__ u8 flow_label1
:8;
450 #elif defined(__BIG_ENDIAN_BITFIELD)
451 __extension__ u8 flow_label1
:8;
452 __extension__ u8 flow_label2
:8;
453 __extension__ u8 flow_label3
:8;
455 # error "Adjust your <asm/byteorder.h> defines"
461 struct element_tclas_type5
{
467 struct element_schedule
{
475 struct element_chall_txt
{
480 struct element_pwr_constr
{
485 struct element_pwr_cap
{
491 struct element_tpc_req
{
495 struct element_tpc_rep
{
501 struct element_supp_ch
{
507 struct element_supp_ch_tuple
{
512 struct element_ch_sw_ann
{
519 struct element_meas_basic
{
525 struct element_meas_cca
{
531 struct element_meas_rpi
{
537 struct element_meas_ch_load
{
545 struct element_meas_noise
{
553 struct element_meas_beacon
{
563 struct element_meas_frame
{
573 struct element_meas_sta
{
581 struct element_meas_lci
{
584 u8 longitude_req_res
;
589 struct element_meas_trans_str_cat
{
598 struct element_meas_mcast_diag
{
602 u8 mcast_triggered
[0];
606 struct element_meas_loc_civic
{
609 u8 loc_srv_intv_unit
;
614 struct element_meas_loc_id
{
616 u8 loc_srv_intv_unit
;
621 struct element_meas_pause
{
626 struct element_meas_req
{
634 struct element_meas_rep
{
642 struct element_quiet
{
650 struct element_ibss_dfs
{
657 struct element_ibss_dfs_tuple
{
667 struct element_ts_del
{
672 struct element_tclas_proc
{
677 struct element_ht_cap
{
682 #if defined(__LITTLE_ENDIAN_BITFIELD)
683 /* Correct order here ... */
684 __extension__ u16 ldpc
:1,
698 #elif defined(__BIG_ENDIAN_BITFIELD)
699 __extension__ u16 rx_stbc
:2,
714 # error "Adjust your <asm/byteorder.h> defines"
722 #if defined(__LITTLE_ENDIAN_BITFIELD)
723 /* Correct order here ... */
724 __extension__ u8 bitmask1
:8;
725 __extension__ u8 bitmask2
:8;
726 __extension__ u8 bitmask3
:8;
727 __extension__ u8 bitmask4
:8;
728 __extension__ u8 bitmask5
:8;
729 __extension__ u8 bitmask6
:8;
730 __extension__ u8 bitmask7
:8;
731 __extension__ u8 bitmask8
:8;
732 __extension__ u8 bitmask9
:8;
733 __extension__ u8 bitmask10_res
:8;
734 __extension__ u16 supp_rate_res
:16;
735 __extension__ u32 tx_param_res
:32;
737 #elif defined(__BIG_ENDIAN_BITFIELD)
738 __extension__ u32 tx_param_res
:32;
739 __extension__ u16 supp_rate_res
:16;
740 __extension__ u8 bitmask10_res
:8;
741 __extension__ u8 bitmask9
:8;
742 __extension__ u8 bitmask8
:8;
743 __extension__ u8 bitmask7
:8;
744 __extension__ u8 bitmask6
:8;
745 __extension__ u8 bitmask5
:8;
746 __extension__ u8 bitmask4
:8;
747 __extension__ u8 bitmask3
:8;
748 __extension__ u8 bitmask2
:8;
749 __extension__ u8 bitmask1
:8;
751 # error "Adjust your <asm/byteorder.h> defines"
760 struct element_qos_cap
{
765 struct element_ext_supp_rates
{
770 struct element_vend_spec
{
776 struct ieee80211_radiotap_header
{
777 u8 version
; /* set to 0 */
779 u16 len
; /* entire length */
780 u32 present
; /* fields present */
783 static int8_t len_neq_error(u8 len
, u8 intended
)
785 if(intended
!= len
) {
786 tprintf("Length should be %u Bytes", intended
);
793 static int8_t len_lt_error(u8 len
, u8 intended
)
796 tprintf("Length should be greater %u Bytes", intended
);
803 static float data_rates(u8 id
)
805 /* XXX Why not (id / 2.f)? */
813 case 11: return 5.5f
;
814 case 12: return 6.0f
;
815 case 18: return 9.0f
;
816 case 22: return 11.0f
;
817 case 24: return 12.0f
;
818 case 27: return 13.5f
;
819 case 36: return 18.0f
;
820 case 44: return 22.0f
;
821 case 48: return 24.0f
;
822 case 54: return 27.0f
;
823 case 66: return 33.0f
;
824 case 72: return 36.0f
;
825 case 96: return 48.0f
;
826 case 108: return 54.0f
;
839 static int8_t subelements(struct pkt_buff
*pkt
, u8 len
)
845 struct subelement
*sub
;
847 sub
= (struct subelement
*) pkt_pull(pkt
, sizeof(*sub
));
851 tprintf(", Subelement ID %u, ", sub
->id
);
852 tprintf("Length %u, ", sub
->len
);
854 data
= pkt_pull(pkt
, sub
->len
);
859 for(j
=0; j
< sub
->len
; j
++)
860 tprintf("%.2x ", data
[j
]);
865 /* Not needed ?! Should break before*/
868 * tprintf("Length error");
876 static int8_t inf_reserved(struct pkt_buff
*pkt
, u8
*id
)
880 struct element_reserved
*reserved
;
882 reserved
= (struct element_reserved
*) pkt_pull(pkt
, sizeof(*reserved
));
883 if (reserved
== NULL
)
886 tprintf(" Reserved (%u, Len (%u)): ", *id
, reserved
->len
);
888 data
= pkt_pull(pkt
, reserved
->len
);
893 for (i
= 0; i
< reserved
->len
; i
++)
894 tprintf("%.2x", data
[i
]);
899 static int8_t inf_ssid(struct pkt_buff
*pkt
, u8
*id
)
902 struct element_ssid
*ssid
;
905 ssid
= (struct element_ssid
*) pkt_pull(pkt
, sizeof(*ssid
));
909 tprintf(" SSID (%u, Len (%u)): ", *id
, ssid
->len
);
911 if ((ssid
->len
- sizeof(*ssid
) + 1) > 0) {
912 ssid_name
= (char *) pkt_pull(pkt
, ssid
->len
);
913 if (ssid_name
== NULL
)
916 for (i
= 0; i
< ssid
->len
; i
++)
917 tprintf("%c",ssid_name
[i
]);
919 tprintf("Wildcard SSID");
925 static int8_t inf_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
929 struct element_supp_rates
*supp_rates
;
931 supp_rates
= (struct element_supp_rates
*)
932 pkt_pull(pkt
, sizeof(*supp_rates
));
933 if (supp_rates
== NULL
)
936 tprintf(" Supp. Rates (%u, Len (%u)): ", *id
, supp_rates
->len
);
937 if (len_lt_error(supp_rates
->len
, 1))
940 if ((supp_rates
->len
- sizeof(*supp_rates
) + 1) > 0) {
941 rates
= pkt_pull(pkt
, supp_rates
->len
);
945 for (i
= 0; i
< supp_rates
->len
; i
++)
946 tprintf("%g%s ", ((rates
[i
] & 0x80) >> 7) ?
947 data_rates(rates
[i
] & 0x3f) :
948 ((rates
[i
] & 0x3f) * 0.5),
949 ((rates
[i
] & 0x80) >> 7) ? "(B)" : "");
956 static int8_t inf_fh_ps(struct pkt_buff
*pkt
, u8
*id
)
958 struct element_fh_ps
*fh_ps
;
960 fh_ps
= (struct element_fh_ps
*) pkt_pull(pkt
, sizeof(*fh_ps
));
964 tprintf(" FH Param Set (%u, Len(%u)): ", *id
, fh_ps
->len
);
965 if (len_neq_error(fh_ps
->len
, 5))
967 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps
->dwell_time
) * TU
);
968 tprintf("HopSet: %u, ", fh_ps
->hop_set
);
969 tprintf("HopPattern: %u, ", fh_ps
->hop_pattern
);
970 tprintf("HopIndex: %u", fh_ps
->hop_index
);
975 static int8_t inf_dsss_ps(struct pkt_buff
*pkt
, u8
*id
)
977 struct element_dsss_ps
*dsss_ps
;
979 dsss_ps
= (struct element_dsss_ps
*) pkt_pull(pkt
, sizeof(*dsss_ps
));
983 tprintf(" DSSS Param Set (%u, Len(%u)): ", *id
, dsss_ps
->len
);
984 if (len_neq_error(dsss_ps
->len
, 1))
986 tprintf("Current Channel: %u", dsss_ps
->curr_ch
);
991 static int8_t inf_cf_ps(struct pkt_buff
*pkt
, u8
*id
)
993 struct element_cf_ps
*cf_ps
;
995 cf_ps
= (struct element_cf_ps
*) pkt_pull(pkt
, sizeof(*cf_ps
));
999 tprintf(" CF Param Set (%u, Len(%u)): ", *id
, cf_ps
->len
);
1000 if (len_neq_error(cf_ps
->len
, 6))
1002 tprintf("CFP Count: %u, ", cf_ps
->cfp_cnt
);
1003 tprintf("CFP Period: %u, ", cf_ps
->cfp_period
);
1004 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps
->cfp_max_dur
) * TU
);
1005 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps
->cfp_dur_rem
) * TU
);
1010 static int8_t inf_tim(struct pkt_buff
*pkt
, u8
*id
)
1012 struct element_tim
*tim
;
1015 tim
= (struct element_tim
*) pkt_pull(pkt
, sizeof(*tim
));
1019 tprintf(" TIM (%u, Len(%u)): ", *id
, tim
->len
);
1020 if (len_lt_error(tim
->len
, 3))
1022 tprintf("DTIM Count: %u, ", tim
->dtim_cnt
);
1023 tprintf("DTIM Period: %u, ", tim
->dtim_period
);
1024 tprintf("Bitmap Control: %u, ", tim
->bmp_cntrl
);
1025 if ((tim
->len
- sizeof(*tim
) + 1) > 0) {
1026 u8
*bmp
= pkt_pull(pkt
, (tim
->len
- sizeof(*tim
) + 1));
1030 tprintf("Partial Virtual Bitmap: 0x");
1031 for (i
= 0; i
< (tim
->len
- sizeof(*tim
) + 1); i
++)
1032 tprintf("%.2x", bmp
[i
]);
1038 static int8_t inf_ibss_ps(struct pkt_buff
*pkt
, u8
*id
)
1040 struct element_ibss_ps
*ibss_ps
;
1042 ibss_ps
= (struct element_ibss_ps
*) pkt_pull(pkt
, sizeof(*ibss_ps
));
1043 if (ibss_ps
== NULL
)
1046 tprintf(" IBSS Param Set (%u, Len(%u)): ", *id
, ibss_ps
->len
);
1047 if (len_neq_error(ibss_ps
->len
, 2))
1049 tprintf("ATIM Window: %fs", le16_to_cpu(ibss_ps
->atim_win
) * TU
);
1054 static int8_t inf_country(struct pkt_buff
*pkt
, u8
*id
)
1058 struct element_country
*country
;
1060 country
= (struct element_country
*) pkt_pull(pkt
, sizeof(*country
));
1061 if (country
== NULL
)
1064 tprintf(" Country (%u, Len(%u)): ", *id
, country
->len
);
1065 if (len_lt_error(country
->len
, 6))
1067 tprintf("Country String: %c%c%c", country
->country_first
,
1068 country
->country_sec
, country
->country_third
);
1070 for (i
= country
->len
% 3; i
< (country
->len
- 3); i
+= 3) {
1071 struct element_country_tripled
*country_tripled
;
1073 country_tripled
= (struct element_country_tripled
*)
1074 pkt_pull(pkt
, sizeof(*country_tripled
));
1075 if (country_tripled
== NULL
)
1078 if(country_tripled
->frst_ch
>= 201) {
1079 tprintf("Oper Ext ID: %u, ", country_tripled
->frst_ch
);
1080 tprintf("Operating Class: %u, ", country_tripled
->nr_ch
);
1081 tprintf("Coverage Class: %u", country_tripled
->max_trans
);
1083 tprintf("First Ch Nr: %u, ", country_tripled
->frst_ch
);
1084 tprintf("Nr of Ch: %u, ", country_tripled
->nr_ch
);
1085 tprintf("Max Transmit Pwr Lvl: %u", country_tripled
->max_trans
);
1089 if(country
->len
% 3) {
1090 pad
= pkt_pull(pkt
, 1);
1094 tprintf(", Pad: 0x%x", *pad
);
1100 static int8_t inf_hop_pp(struct pkt_buff
*pkt
, u8
*id
)
1102 struct element_hop_pp
*hop_pp
;
1104 hop_pp
= (struct element_hop_pp
*) pkt_pull(pkt
, sizeof(*hop_pp
));
1108 tprintf(" Hopping Pattern Param (%u, Len(%u)): ", *id
, hop_pp
->len
);
1109 if (len_neq_error(hop_pp
->len
, 2))
1111 tprintf("Prime Radix: %u, ", hop_pp
->prime_radix
);
1112 tprintf("Nr of Ch: %u", hop_pp
->nr_ch
);
1117 static int8_t inf_hop_pt(struct pkt_buff
*pkt
, u8
*id
)
1121 struct element_hop_pt
*hop_pt
;
1123 hop_pt
= (struct element_hop_pt
*) pkt_pull(pkt
, sizeof(*hop_pt
));
1127 tprintf(" Hopping Pattern Table (%u, Len(%u)): ", *id
, hop_pt
->len
);
1128 if (len_lt_error(hop_pt
->len
, 4))
1130 tprintf("Flag: %u, ", hop_pt
->flag
);
1131 tprintf("Nr of Sets: %u, ", hop_pt
->nr_sets
);
1132 tprintf("Modulus: %u, ", hop_pt
->modules
);
1133 tprintf("Offs: %u", hop_pt
->offs
);
1135 if ((hop_pt
->len
- sizeof(*hop_pt
) + 1) > 0) {
1136 rand_tabl
= pkt_pull(pkt
, (hop_pt
->len
- sizeof(*hop_pt
) + 1));
1137 if (rand_tabl
== NULL
)
1140 tprintf(", Rand table: 0x");
1141 for (i
= 0; i
< (hop_pt
->len
- sizeof(*hop_pt
) + 1); i
++)
1142 tprintf("%.2x", rand_tabl
[i
]);
1148 static int8_t inf_req(struct pkt_buff
*pkt
, u8
*id
)
1151 struct element_req
*req
;
1154 req
= (struct element_req
*) pkt_pull(pkt
, sizeof(*req
));
1158 tprintf(" Request Element (%u, Len(%u)): ", *id
, req
->len
);
1159 if ((req
->len
- sizeof(*req
) + 1) > 0) {
1160 req_ids
= pkt_pull(pkt
, (req
->len
- sizeof(*req
) + 1));
1161 if (req_ids
== NULL
)
1164 tprintf(", Requested Element IDs: ");
1165 for (i
= 0; i
< (req
->len
- sizeof(*req
) + 1); i
++)
1166 tprintf("%u ", req_ids
[i
]);
1172 static int8_t inf_bss_load(struct pkt_buff
*pkt
, u8
*id
)
1174 struct element_bss_load
*bss_load
;
1176 bss_load
= (struct element_bss_load
*) pkt_pull(pkt
, sizeof(*bss_load
));
1177 if (bss_load
== NULL
)
1180 tprintf(" BSS Load element (%u, Len(%u)): ", *id
, bss_load
->len
);
1181 if (len_neq_error(bss_load
->len
, 5))
1183 tprintf("Station Count: %u, ", le16_to_cpu(bss_load
->station_cnt
));
1184 tprintf("Channel Utilization: %u, ", bss_load
->ch_util
);
1185 tprintf("Available Admission Capacity: %uus",
1186 bss_load
->avlb_adm_cap
* 32);
1191 static int8_t inf_edca_ps(struct pkt_buff
*pkt
, u8
*id
)
1193 u32 ac_be
, ac_bk
, ac_vi
, ac_vo
;
1194 struct element_edca_ps
*edca_ps
;
1196 edca_ps
= (struct element_edca_ps
*) pkt_pull(pkt
, sizeof(*edca_ps
));
1197 if (edca_ps
== NULL
)
1200 ac_be
= le32_to_cpu(edca_ps
->ac_be
);
1201 ac_bk
= le32_to_cpu(edca_ps
->ac_bk
);
1202 ac_vi
= le32_to_cpu(edca_ps
->ac_vi
);
1203 ac_vo
= le32_to_cpu(edca_ps
->ac_vo
);
1205 tprintf(" EDCA Param Set (%u, Len(%u)): ", *id
, edca_ps
->len
);
1206 if (len_neq_error(edca_ps
->len
, 18))
1208 tprintf("QoS Info: 0x%x (-> EDCA Param Set Update Count (%u),"
1209 "Q-Ack (%u), Queue Re (%u), TXOP Req(%u), Res(%u)), ",
1210 edca_ps
->qos_inf
, edca_ps
->qos_inf
>> 4,
1211 (edca_ps
->qos_inf
>> 3) & 1, (edca_ps
->qos_inf
>> 2) & 1,
1212 (edca_ps
->qos_inf
>> 1) & 1, edca_ps
->qos_inf
& 1);
1213 tprintf("Reserved: 0x%x, ", edca_ps
->res
);
1214 tprintf("AC_BE Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1215 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_be
,
1216 ac_be
>> 28, (ac_be
>> 27) & 1, (ac_be
>> 25) & 3,
1217 (ac_be
>> 24) & 1, (ac_be
>> 20) & 15, (ac_be
>> 16) & 15,
1218 bswap_16(ac_be
& 0xFFFF) * 32);
1219 tprintf("AC_BK Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1220 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_bk
,
1221 ac_bk
>> 28, (ac_bk
>> 27) & 1, (ac_bk
>> 25) & 3,
1222 (ac_bk
>> 24) & 1, (ac_bk
>> 20) & 15, (ac_bk
>> 16) & 15,
1223 bswap_16(ac_bk
& 0xFFFF) * 32);
1224 tprintf("AC_VI Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1225 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_vi
,
1226 ac_vi
>> 28, (ac_vi
>> 27) & 1, (ac_vi
>> 25) & 3,
1227 (ac_vi
>> 24) & 1, (ac_vi
>> 20) & 15, (ac_vi
>> 16) & 15,
1228 bswap_16(ac_vi
& 0xFFFF) * 32);
1229 tprintf("AC_VO Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1230 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)", ac_vo
,
1231 ac_vo
>> 28, (ac_vo
>> 27) & 1, (ac_vo
>> 25) & 3,
1232 (ac_vo
>> 24) & 1, (ac_vo
>> 20) & 15, (ac_vo
>> 16) & 15,
1233 bswap_16(ac_vo
& 0xFFFF) * 32);
1238 static int8_t inf_tspec(struct pkt_buff
*pkt
, u8
*id
)
1240 u16 nom_msdu_size
, surplus_bandw_allow
;
1241 struct element_tspec
*tspec
;
1243 tspec
= (struct element_tspec
*) pkt_pull(pkt
, sizeof(*tspec
));
1247 nom_msdu_size
= le16_to_cpu(tspec
->nom_msdu_size
);
1248 surplus_bandw_allow
= le16_to_cpu(tspec
->surplus_bandw_allow
);
1250 tprintf(" TSPEC (%u, Len(%u)): ", *id
, tspec
->len
);
1251 if (len_neq_error(tspec
->len
, 55))
1253 tprintf("Traffic Type: %u, ", tspec
->traffic_type
);
1254 tprintf("TSID: %u, ", tspec
->tsid
);
1255 tprintf("Direction: %u, ", tspec
->direction
);
1256 tprintf("Access Policy: %u, ", tspec
->access_policy
);
1257 tprintf("Aggregation: %u, ", tspec
->aggr
);
1258 tprintf("APSD: %u, ", tspec
->apsd
);
1259 tprintf("User Priority: %u, ", tspec
->user_prior
);
1260 tprintf("TSinfo Ack Policy: %u, ", tspec
->tsinfo_ack_pol
);
1261 tprintf("Schedule: %u, ", tspec
->schedule
);
1262 tprintf("Reserved: 0x%x, ", tspec
->res
);
1263 tprintf("Nominal MSDU Size: %uB (Fixed (%u)), ",
1264 nom_msdu_size
>> 1, nom_msdu_size
& 1);
1265 tprintf("Maximum MSDU Size: %uB, ", le16_to_cpu(tspec
->max_msdu_size
));
1266 tprintf("Minimum Service Interval: %uus, ",
1267 le32_to_cpu(tspec
->min_srv_intv
));
1268 tprintf("Maximum Service Interval: %uus, ",
1269 le32_to_cpu(tspec
->max_srv_intv
));
1270 tprintf("Inactivity Interval: %uus, ",
1271 le32_to_cpu(tspec
->inactive_intv
));
1272 tprintf("Suspension Interval: %uus, ", le32_to_cpu(tspec
->susp_intv
));
1273 tprintf("Service Start Time: %uus, ",
1274 le32_to_cpu(tspec
->srv_start_time
));
1275 tprintf("Minimum Data Rate: %ub/s, ",le32_to_cpu(tspec
->min_data_rate
));
1276 tprintf("Mean Data Rate: %ub/s, ", le32_to_cpu(tspec
->mean_data_rate
));
1277 tprintf("Peak Data Rate: %ub/s, ",le32_to_cpu(tspec
->peak_data_rate
));
1278 tprintf("Burst Size: %uB, ", le32_to_cpu(tspec
->burst_size
));
1279 tprintf("Delay Bound: %uus, ", le32_to_cpu(tspec
->delay_bound
));
1280 tprintf("Minimum PHY Rate: %ub/s, ", le32_to_cpu(tspec
->min_phy_rate
));
1281 tprintf("Surplus Bandwidth: %u.%u, ", surplus_bandw_allow
>> 13,
1282 surplus_bandw_allow
& 0x1FFF);
1283 tprintf("Medium Time: %uus", le16_to_cpu(tspec
->med_time
) * 32);
1288 static const char *class_type(u8 type
)
1291 case 0: return "Ethernet parameters";
1292 case 1: return "TCP/UDP IP parameters";
1293 case 2: return "IEEE 802.1Q parameters";
1294 case 3: return "Filter Offset parameters";
1295 case 4: return "IP and higher layer parameters";
1296 case 5: return "IEEE 802.1D/Q parameters";
1297 default: return "Reserved";
1301 static int8_t inf_tclas(struct pkt_buff
*pkt
, u8
*id
)
1303 struct element_tclas
*tclas
;
1304 struct element_tclas_frm_class
*frm_class
;
1306 tclas
= (struct element_tclas
*) pkt_pull(pkt
, sizeof(*tclas
));
1310 frm_class
= (struct element_tclas_frm_class
*)
1311 pkt_pull(pkt
, sizeof(*frm_class
));
1312 if (frm_class
== NULL
)
1315 tprintf(" TCLAS (%u, Len(%u)): ", *id
, tclas
->len
);
1316 if (len_lt_error(tclas
->len
, 3))
1318 tprintf("User Priority: %u, ", tclas
->user_priority
);
1319 tprintf("Classifier Type: %s (%u), ", class_type(frm_class
->type
),
1321 tprintf("Classifier Mask: 0x%x, ", frm_class
->mask
);
1323 if(frm_class
->type
== 0) {
1324 struct element_tclas_type0
*type0
;
1326 type0
= (struct element_tclas_type0
*)
1327 pkt_pull(pkt
, sizeof(*type0
));
1331 /* I think little endian, like the rest */
1332 tprintf("Src Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1333 type0
->sa
[5], type0
->sa
[4], type0
->sa
[3],
1334 type0
->sa
[2], type0
->sa
[1], type0
->sa
[0]);
1335 tprintf("Dst Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1336 type0
->da
[5], type0
->da
[4], type0
->da
[3],
1337 type0
->da
[2], type0
->da
[1], type0
->da
[0]);
1338 tprintf("Type: 0x%x", le16_to_cpu(type0
->type
));
1340 else if(frm_class
->type
== 1) {
1341 struct element_tclas_type1
*type1
;
1343 type1
= (struct element_tclas_type1
*)
1344 pkt_pull(pkt
, sizeof(*type1
));
1348 tprintf("Version: %u, ", type1
->version
);
1349 /* big endian format follows */
1350 if(type1
->version
== 4) {
1351 struct element_tclas_type1_ip4
*type1_ip4
;
1352 char src_ip
[INET_ADDRSTRLEN
];
1353 char dst_ip
[INET_ADDRSTRLEN
];
1355 type1_ip4
= (struct element_tclas_type1_ip4
*)
1356 pkt_pull(pkt
, sizeof(*type1_ip4
));
1357 if (type1_ip4
== NULL
)
1360 inet_ntop(AF_INET
, &type1_ip4
->sa
, src_ip
, sizeof(src_ip
));
1361 inet_ntop(AF_INET
, &type1_ip4
->da
, dst_ip
, sizeof(dst_ip
));
1363 tprintf("Src IP: %s, ", src_ip
);
1364 tprintf("Dst IP: %s, ", dst_ip
);
1365 tprintf("Src Port: %u, ", ntohs(type1_ip4
->sp
));
1366 tprintf("Dst Port: %u, ", ntohs(type1_ip4
->dp
));
1367 tprintf("DSCP: 0x%x, ", type1_ip4
->dscp
);
1368 tprintf("Proto: %u, ", type1_ip4
->proto
);
1369 tprintf("Res: 0x%x", type1_ip4
->reserved
);
1371 else if(type1
->version
== 6) {
1372 struct element_tclas_type1_ip6
*type1_ip6
;
1373 char src_ip
[INET6_ADDRSTRLEN
];
1374 char dst_ip
[INET6_ADDRSTRLEN
];
1376 type1_ip6
= (struct element_tclas_type1_ip6
*)
1377 pkt_pull(pkt
, sizeof(*type1_ip6
));
1378 if (type1_ip6
== NULL
)
1381 inet_ntop(AF_INET6
, &type1_ip6
->sa
,
1382 src_ip
, sizeof(src_ip
));
1383 inet_ntop(AF_INET6
, &type1_ip6
->da
,
1384 dst_ip
, sizeof(dst_ip
));
1386 tprintf("Src IP: %s, ", src_ip
);
1387 tprintf("Dst IP: %s, ", dst_ip
);
1388 tprintf("Src Port: %u, ", ntohs(type1_ip6
->sp
));
1389 tprintf("Dst Port: %u, ", ntohs(type1_ip6
->dp
));
1390 tprintf("Flow Label: 0x%x%x%x", type1_ip6
->flow_label1
,
1391 type1_ip6
->flow_label2
, type1_ip6
->flow_label3
);
1394 tprintf("Version (%u) not supported", type1
->version
);
1399 else if(frm_class
->type
== 2) {
1400 struct element_tclas_type2
*type2
;
1402 type2
= (struct element_tclas_type2
*)
1403 pkt_pull(pkt
, sizeof(*type2
));
1407 tprintf("802.1Q VLAN TCI: 0x%x", ntohs(type2
->vlan_tci
));
1409 else if(frm_class
->type
== 3) {
1410 struct element_tclas_type3
*type3
;
1414 type3
= (struct element_tclas_type3
*)
1415 pkt_pull(pkt
, sizeof(*type3
));
1419 len
= (tclas
->len
- 5) / 2;
1421 tprintf("Filter Offset: %u, ", type3
->offs
);
1423 if((len
& 1) || (len_lt_error(tclas
->len
, 5))) {
1424 tprintf("Length of TCLAS (%u) not correct", tclas
->len
);
1428 val
= pkt_pull(pkt
, len
);
1432 tprintf("Filter Value: 0x");
1433 for (i
= 0; i
< len
/ 2; i
++)
1434 tprintf("%x ", val
[i
]);
1436 tprintf("Filter Mask: 0x");
1437 for (i
= len
/ 2; i
< len
; i
++)
1438 tprintf("%x ", val
[i
]);
1442 else if(frm_class
->type
== 4) {
1443 struct element_tclas_type4
*type4
;
1445 type4
= (struct element_tclas_type4
*)
1446 pkt_pull(pkt
, sizeof(*type4
));
1450 tprintf("Version: %u, ", type4
->version
);
1451 /* big endian format follows */
1452 if(type4
->version
== 4) {
1453 struct element_tclas_type4_ip4
*type4_ip4
;
1454 char src_ip
[INET_ADDRSTRLEN
];
1455 char dst_ip
[INET_ADDRSTRLEN
];
1457 type4_ip4
= (struct element_tclas_type4_ip4
*)
1458 pkt_pull(pkt
, sizeof(*type4_ip4
));
1459 if (type4_ip4
== NULL
)
1462 inet_ntop(AF_INET
, &type4_ip4
->sa
, src_ip
, sizeof(src_ip
));
1463 inet_ntop(AF_INET
, &type4_ip4
->da
, dst_ip
, sizeof(dst_ip
));
1465 tprintf("Src IP: %s, ", src_ip
);
1466 tprintf("Dst IP: %s, ", dst_ip
);
1467 tprintf("Src Port: %u, ", ntohs(type4_ip4
->sp
));
1468 tprintf("Dst Port: %u, ", ntohs(type4_ip4
->dp
));
1469 tprintf("DSCP: 0x%x, ", type4_ip4
->dscp
);
1470 tprintf("Proto: %u, ", type4_ip4
->proto
);
1471 tprintf("Res: 0x%x", type4_ip4
->reserved
);
1473 else if(type4
->version
== 6) {
1474 struct element_tclas_type4_ip6
*type4_ip6
;
1475 char src_ip
[INET6_ADDRSTRLEN
];
1476 char dst_ip
[INET6_ADDRSTRLEN
];
1478 type4_ip6
= (struct element_tclas_type4_ip6
*)
1479 pkt_pull(pkt
, sizeof(*type4_ip6
));
1480 if (type4_ip6
== NULL
)
1483 inet_ntop(AF_INET6
, &type4_ip6
->sa
,
1484 src_ip
, sizeof(src_ip
));
1485 inet_ntop(AF_INET6
, &type4_ip6
->da
,
1486 dst_ip
, sizeof(dst_ip
));
1488 tprintf("Src IP: %s, ", src_ip
);
1489 tprintf("Dst IP: %s, ", dst_ip
);
1490 tprintf("Src Port: %u, ", ntohs(type4_ip6
->sp
));
1491 tprintf("Dst Port: %u, ", ntohs(type4_ip6
->dp
));
1492 tprintf("DSCP: 0x%x, ", type4_ip6
->dscp
);
1493 tprintf("Nxt Hdr: %u, ", type4_ip6
->nxt_hdr
);
1494 tprintf("Flow Label: 0x%x%x%x", type4_ip6
->flow_label1
,
1495 type4_ip6
->flow_label2
, type4_ip6
->flow_label3
);
1498 tprintf("Version (%u) not supported", type4
->version
);
1502 else if(frm_class
->type
== 5) {
1503 struct element_tclas_type5
*type5
;
1505 type5
= (struct element_tclas_type5
*)
1506 pkt_pull(pkt
, sizeof(*type5
));
1510 tprintf("802.1Q PCP: 0x%x, ", type5
->pcp
);
1511 tprintf("802.1Q CFI: 0x%x, ", type5
->cfi
);
1512 tprintf("802.1Q VID: 0x%x", type5
->vid
);
1515 tprintf("Classifier Type (%u) not supported", frm_class
->type
);
1522 static int8_t inf_sched(struct pkt_buff
*pkt
, u8
*id
)
1524 struct element_schedule
*schedule
;
1527 schedule
= (struct element_schedule
*) pkt_pull(pkt
, sizeof(*schedule
));
1528 if (schedule
== NULL
)
1531 info
= le16_to_cpu(schedule
->inf
);
1533 tprintf(" Schedule (%u, Len(%u)): ", *id
, schedule
->len
);
1534 if (len_neq_error(schedule
->len
, 12))
1537 tprintf("Aggregation: %u, ", info
>> 15);
1538 tprintf("TSID: %u, ", (info
>> 11) & 0xF);
1539 tprintf("Direction: %u, ", (info
>> 9) & 0x3);
1540 tprintf("Res: %u, ", info
& 0x1FF);
1541 tprintf("Serv Start Time: %uus, ", le32_to_cpu(schedule
->start
));
1542 tprintf("Serv Interval: %uus, ", le32_to_cpu(schedule
->serv_intv
));
1543 tprintf("Spec Interval: %fs", le32_to_cpu(schedule
->spec_intv
) * TU
);
1548 static int8_t inf_chall_txt(struct pkt_buff
*pkt
, u8
*id
)
1550 struct element_chall_txt
*chall_txt
;
1554 chall_txt
= (struct element_chall_txt
*)
1555 pkt_pull(pkt
, sizeof(*chall_txt
));
1556 if (chall_txt
== NULL
)
1559 tprintf(" Challenge Text (%u, Len(%u)): ", *id
, chall_txt
->len
);
1560 if ((chall_txt
->len
- sizeof(*chall_txt
) + 1) > 0) {
1561 txt
= pkt_pull(pkt
, (chall_txt
->len
- sizeof(*chall_txt
) + 1));
1566 for (i
= 0; i
< (chall_txt
->len
- sizeof(*chall_txt
) + 1); i
++)
1567 tprintf("%x", txt
[i
]);
1573 static int8_t inf_pwr_constr(struct pkt_buff
*pkt
, u8
*id
)
1575 struct element_pwr_constr
*pwr_constr
;
1577 pwr_constr
= (struct element_pwr_constr
*) pkt_pull(pkt
, sizeof(*pwr_constr
));
1578 if (pwr_constr
== NULL
)
1581 tprintf(" Power Constraint (%u, Len(%u)): ", *id
, pwr_constr
->len
);
1582 if (len_neq_error(pwr_constr
->len
, 1))
1585 tprintf("Local Power Constraint: %udB", pwr_constr
->local_pwr_constr
);
1590 static int8_t inf_pwr_cap(struct pkt_buff
*pkt
, u8
*id
)
1592 struct element_pwr_cap
*pwr_cap
;
1594 pwr_cap
= (struct element_pwr_cap
*) pkt_pull(pkt
, sizeof(*pwr_cap
));
1595 if (pwr_cap
== NULL
)
1598 tprintf(" Power Capability (%u, Len(%u)): ", *id
, pwr_cap
->len
);
1599 if (len_neq_error(pwr_cap
->len
, 2))
1602 tprintf("Min. Transm. Pwr Cap.: %ddBm, ", (int8_t)pwr_cap
->min_pwr_cap
);
1603 tprintf("Max. Transm. Pwr Cap.: %ddBm", (int8_t)pwr_cap
->max_pwr_cap
);
1608 static int8_t inf_tpc_req(struct pkt_buff
*pkt
, u8
*id
)
1610 struct element_tpc_req
*tpc_req
;
1612 tpc_req
= (struct element_tpc_req
*) pkt_pull(pkt
, sizeof(*tpc_req
));
1613 if (tpc_req
== NULL
)
1616 tprintf(" TPC Request (%u, Len(%u))", *id
, tpc_req
->len
);
1617 if (len_neq_error(tpc_req
->len
, 0))
1623 static int8_t inf_tpc_rep(struct pkt_buff
*pkt
, u8
*id
)
1625 struct element_tpc_rep
*tpc_rep
;
1627 tpc_rep
= (struct element_tpc_rep
*) pkt_pull(pkt
, sizeof(*tpc_rep
));
1628 if (tpc_rep
== NULL
)
1631 tprintf(" TPC Report (%u, Len(%u)): ", *id
, tpc_rep
->len
);
1632 if (len_neq_error(tpc_rep
->len
, 2))
1635 tprintf("Transmit Power: %udBm, ", (int8_t)tpc_rep
->trans_pwr
);
1636 tprintf("Link Margin: %udB", (int8_t)tpc_rep
->trans_pwr
);
1641 static int8_t inf_supp_ch(struct pkt_buff
*pkt
, u8
*id
)
1643 struct element_supp_ch
*supp_ch
;
1646 supp_ch
= (struct element_supp_ch
*) pkt_pull(pkt
, sizeof(*supp_ch
));
1647 if (supp_ch
== NULL
)
1650 tprintf(" Supp Channels (%u, Len(%u)): ", *id
, supp_ch
->len
);
1651 if (len_lt_error(supp_ch
->len
, 2))
1654 if(supp_ch
->len
& 1) {
1655 tprintf("Length should be even");
1659 for (i
= 0; i
< supp_ch
->len
; i
+= 2) {
1660 struct element_supp_ch_tuple
*supp_ch_tuple
;
1662 supp_ch_tuple
= (struct element_supp_ch_tuple
*)
1663 pkt_pull(pkt
, sizeof(*supp_ch_tuple
));
1664 if (supp_ch_tuple
== NULL
)
1667 tprintf("First Channel Nr: %u, ", supp_ch_tuple
->first_ch_nr
);
1668 tprintf("Nr of Channels: %u, ", supp_ch_tuple
->nr_ch
);
1674 static int8_t inf_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
)
1676 struct element_ch_sw_ann
*ch_sw_ann
;
1678 ch_sw_ann
= (struct element_ch_sw_ann
*)
1679 pkt_pull(pkt
, sizeof(*ch_sw_ann
));
1680 if (ch_sw_ann
== NULL
)
1683 tprintf(" Channel Switch Announc (%u, Len(%u)): ", *id
, ch_sw_ann
->len
);
1684 if (len_neq_error(ch_sw_ann
->len
, 3))
1687 tprintf("Switch Mode: %u, ", ch_sw_ann
->switch_mode
);
1688 tprintf("New Nr: %u, ", ch_sw_ann
->new_nr
);
1689 tprintf("Switch Count: %u", ch_sw_ann
->switch_cnt
);
1694 static const char *meas_type(u8 type
)
1697 case 0: return "Basic";
1698 case 1: return "Clear Channel assesment (CCA)";
1699 case 2: return "Receive power indication (RPI) histogram";
1700 case 3: return "Channel load";
1701 case 4: return "Noise histogram";
1702 case 5: return "Beacon";
1703 case 6: return "Frame";
1704 case 7: return "STA statistics";
1705 case 8: return "LCI";
1706 case 9: return "Transmit stream/category measurement";
1707 case 10: return "Multicast diagnostics";
1708 case 11: return "Location Civic";
1709 case 12: return "Location Identifier";
1710 default: return "Reserved";
1714 static int8_t inf_meas_req(struct pkt_buff
*pkt
, u8
*id
)
1716 struct element_meas_req
*meas_req
;
1718 meas_req
= (struct element_meas_req
*) pkt_pull(pkt
, sizeof(*meas_req
));
1719 if (meas_req
== NULL
)
1722 tprintf(" Measurement Req (%u, Len(%u)): ", *id
, meas_req
->len
);
1723 if (len_lt_error(meas_req
->len
, 3))
1726 tprintf("Token: %u, ", meas_req
->token
);
1727 tprintf("Req Mode: 0x%x (Parallel (%u), Enable(%u), Request(%u), "
1728 "Report(%u), Dur Mand(%u), Res(0x%x)), ", meas_req
->req_mode
,
1729 meas_req
->req_mode
& 0x1,
1730 (meas_req
->req_mode
>> 1) & 0x1,
1731 (meas_req
->req_mode
>> 2) & 0x1,
1732 (meas_req
->req_mode
>> 3) & 0x1,
1733 (meas_req
->req_mode
>> 4) & 0x1,
1734 meas_req
->req_mode
>> 7);
1735 tprintf("Type: %s (%u), ", meas_type(meas_req
->type
), meas_req
->type
);
1737 if(meas_req
->len
> 3) {
1738 if(meas_req
->type
== 0) {
1739 struct element_meas_basic
*basic
;
1741 basic
= (struct element_meas_basic
*)
1742 pkt_pull(pkt
, sizeof(*basic
));
1746 if ((meas_req
->len
- 3 - sizeof(*basic
)) != 0) {
1747 tprintf("Length of Req matchs not Type %u",
1752 tprintf("Ch Nr: %uus, ", basic
->ch_nr
);
1753 tprintf("Meas Start Time: %"PRIu64
", ",
1754 le64_to_cpu(basic
->start
));
1755 tprintf("Meas Duration: %fs",
1756 le16_to_cpu(basic
->dur
) * TU
);
1759 else if(meas_req
->type
== 1) {
1760 struct element_meas_cca
*cca
;
1762 cca
= (struct element_meas_cca
*)
1763 pkt_pull(pkt
, sizeof(*cca
));
1767 if ((meas_req
->len
- 3 - sizeof(*cca
)) != 0) {
1768 tprintf("Length of Req matchs not Type %u",
1773 tprintf("Ch Nr: %uus, ", cca
->ch_nr
);
1774 tprintf("Meas Start Time: %"PRIu64
", ",
1775 le64_to_cpu(cca
->start
));
1776 tprintf("Meas Duration: %fs",
1777 le16_to_cpu(cca
->dur
) * TU
);
1779 else if(meas_req
->type
== 2) {
1780 struct element_meas_rpi
*rpi
;
1782 rpi
= (struct element_meas_rpi
*)
1783 pkt_pull(pkt
, sizeof(*rpi
));
1787 if ((meas_req
->len
- 3 - sizeof(*rpi
)) != 0) {
1788 tprintf("Length of Req matchs not Type %u",
1793 tprintf("Ch Nr: %uus, ", rpi
->ch_nr
);
1794 tprintf("Meas Start Time: %"PRIu64
", ",
1795 le64_to_cpu(rpi
->start
));
1796 tprintf("Meas Duration: %fs",
1797 le16_to_cpu(rpi
->dur
) * TU
);
1799 else if(meas_req
->type
== 3) {
1800 struct element_meas_ch_load
*ch_load
;
1802 ch_load
= (struct element_meas_ch_load
*)
1803 pkt_pull(pkt
, sizeof(*ch_load
));
1804 if (ch_load
== NULL
)
1807 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*ch_load
)) < 0) {
1808 tprintf("Length of Req matchs not Type %u",
1813 tprintf("OP Class: %u, ", ch_load
->op_class
);
1814 tprintf("Ch Nr: %u, ", ch_load
->ch_nr
);
1815 tprintf("Rand Intv: %fs, ",
1816 le16_to_cpu(ch_load
->rand_intv
) * TU
);
1817 tprintf("Meas Duration: %fs",
1818 le16_to_cpu(ch_load
->dur
) * TU
);
1820 if(!subelements(pkt
,
1821 meas_req
->len
- 3 - sizeof(*ch_load
)))
1824 else if(meas_req
->type
== 4) {
1825 struct element_meas_noise
*noise
;
1827 noise
= (struct element_meas_noise
*)
1828 pkt_pull(pkt
, sizeof(*noise
));
1832 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*noise
)) < 0) {
1833 tprintf("Length of Req matchs not Type %u",
1838 tprintf("OP Class: %u, ", noise
->op_class
);
1839 tprintf("Ch Nr: %u, ", noise
->ch_nr
);
1840 tprintf("Rand Intv: %fs, ",
1841 le16_to_cpu(noise
->rand_intv
) * TU
);
1842 tprintf("Meas Duration: %fs",
1843 le16_to_cpu(noise
->dur
) * TU
);
1845 if(!subelements(pkt
,
1846 meas_req
->len
- 3 - sizeof(*noise
)))
1849 else if(meas_req
->type
== 5) {
1850 struct element_meas_beacon
*beacon
;
1852 beacon
= (struct element_meas_beacon
*)
1853 pkt_pull(pkt
, sizeof(*beacon
));
1857 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*beacon
)) < 0) {
1858 tprintf("Length of Req matchs not Type %u",
1863 tprintf("OP Class: %u, ", beacon
->op_class
);
1864 tprintf("Ch Nr: %u, ", beacon
->ch_nr
);
1865 tprintf("Rand Intv: %fs, ",
1866 le16_to_cpu(beacon
->rand_intv
) * TU
);
1867 tprintf("Meas Duration: %fs",
1868 le16_to_cpu(beacon
->dur
) * TU
);
1869 tprintf("Mode: %u, ", beacon
->mode
);
1870 tprintf("BSSID: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1871 beacon
->bssid
[0], beacon
->bssid
[1],
1872 beacon
->bssid
[2], beacon
->bssid
[3],
1873 beacon
->bssid
[4], beacon
->bssid
[5]);
1875 if(!subelements(pkt
,
1876 meas_req
->len
- 3 - sizeof(*beacon
)))
1879 else if(meas_req
->type
== 6) {
1880 struct element_meas_frame
*frame
;
1882 frame
= (struct element_meas_frame
*)
1883 pkt_pull(pkt
, sizeof(*frame
));
1887 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*frame
)) < 0) {
1888 tprintf("Length of Req matchs not Type %u",
1893 tprintf("OP Class: %u, ", frame
->op_class
);
1894 tprintf("Ch Nr: %u, ", frame
->ch_nr
);
1895 tprintf("Rand Intv: %fs, ",
1896 le16_to_cpu(frame
->rand_intv
) * TU
);
1897 tprintf("Meas Duration: %fs",
1898 le16_to_cpu(frame
->dur
) * TU
);
1899 tprintf("Request Type: %u, ", frame
->frame
);
1900 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1901 frame
->mac
[0], frame
->mac
[1],
1902 frame
->mac
[2], frame
->mac
[3],
1903 frame
->mac
[4], frame
->mac
[5]);
1905 if(!subelements(pkt
,
1906 meas_req
->len
- 3 - sizeof(*frame
)))
1909 else if(meas_req
->type
== 7) {
1910 struct element_meas_sta
*sta
;
1912 sta
= (struct element_meas_sta
*)
1913 pkt_pull(pkt
, sizeof(*sta
));
1917 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*sta
)) < 0) {
1918 tprintf("Length of Req matchs not Type %u",
1923 tprintf("Peer MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1924 sta
->peer_mac
[0], sta
->peer_mac
[1],
1925 sta
->peer_mac
[2], sta
->peer_mac
[3],
1926 sta
->peer_mac
[4], sta
->peer_mac
[5]);
1927 tprintf("Rand Intv: %fs, ",
1928 le16_to_cpu(sta
->rand_intv
) * TU
);
1929 tprintf("Meas Duration: %fs",
1930 le16_to_cpu(sta
->dur
) * TU
);
1931 tprintf("Group ID: %u, ", sta
->group_id
);
1933 if(!subelements(pkt
,
1934 meas_req
->len
- 3 - sizeof(*sta
)))
1937 else if(meas_req
->type
== 8) {
1938 struct element_meas_lci
*lci
;
1940 lci
= (struct element_meas_lci
*)
1941 pkt_pull(pkt
, sizeof(*lci
));
1945 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*lci
)) < 0) {
1946 tprintf("Length of Req matchs not Type %u",
1951 tprintf("Location Subj: %u, ", lci
->loc_subj
);
1952 tprintf("Latitude Req Res: %udeg",
1953 lci
->latitude_req_res
);
1954 tprintf("Longitude Req Res: %udeg",
1955 lci
->longitude_req_res
);
1956 tprintf("Altitude Req Res: %udeg",
1957 lci
->altitude_req_res
);
1959 if(!subelements(pkt
,
1960 meas_req
->len
- 3 - sizeof(*lci
)))
1963 else if(meas_req
->type
== 9) {
1964 struct element_meas_trans_str_cat
*trans
;
1966 trans
= (struct element_meas_trans_str_cat
*)
1967 pkt_pull(pkt
, sizeof(*trans
));
1971 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*trans
)) < 0) {
1972 tprintf("Length of Req matchs not Type %u",
1977 tprintf("Rand Intv: %fs, ",
1978 le16_to_cpu(trans
->rand_intv
) * TU
);
1979 tprintf("Meas Duration: %fs",
1980 le16_to_cpu(trans
->dur
) * TU
);
1981 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1982 trans
->peer_sta_addr
[0], trans
->peer_sta_addr
[1],
1983 trans
->peer_sta_addr
[2], trans
->peer_sta_addr
[3],
1984 trans
->peer_sta_addr
[4], trans
->peer_sta_addr
[5]);
1985 tprintf("Traffic ID: %u, ", trans
->traffic_id
);
1986 tprintf("Bin 0 Range: %u, ", trans
->bin_0_range
);
1988 if(!subelements(pkt
,
1989 meas_req
->len
- 3 - sizeof(*trans
)))
1992 else if(meas_req
->type
== 10) {
1993 struct element_meas_mcast_diag
*mcast
;
1995 mcast
= (struct element_meas_mcast_diag
*)
1996 pkt_pull(pkt
, sizeof(*mcast
));
2000 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*mcast
)) < 0) {
2001 tprintf("Length of Req matchs not Type %u",
2006 tprintf("Rand Intv: %fs, ",
2007 le16_to_cpu(mcast
->rand_intv
) * TU
);
2008 tprintf("Meas Duration: %fs",
2009 le16_to_cpu(mcast
->dur
) * TU
);
2010 tprintf("Group MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2011 mcast
->group_mac
[0], mcast
->group_mac
[1],
2012 mcast
->group_mac
[2], mcast
->group_mac
[3],
2013 mcast
->group_mac
[4], mcast
->group_mac
[5]);
2015 if(!subelements(pkt
,
2016 meas_req
->len
- 3 - sizeof(*mcast
)))
2019 else if(meas_req
->type
== 11) {
2020 struct element_meas_loc_civic
*civic
;
2022 civic
= (struct element_meas_loc_civic
*)
2023 pkt_pull(pkt
, sizeof(*civic
));
2027 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*civic
)) < 0) {
2028 tprintf("Length of Req matchs not Type %u",
2033 tprintf("Location Subj: %u, ", civic
->loc_subj
);
2034 tprintf("Type: %u, ", civic
->civic_loc
);
2035 tprintf("Srv Intv Units: %u, ",
2036 le16_to_cpu(civic
->loc_srv_intv_unit
));
2037 tprintf("Srv Intv: %u, ", civic
->loc_srv_intv
);
2039 if(!subelements(pkt
,
2040 meas_req
->len
- 3 - sizeof(*civic
)))
2043 else if(meas_req
->type
== 12) {
2044 struct element_meas_loc_id
*id
;
2046 id
= (struct element_meas_loc_id
*)
2047 pkt_pull(pkt
, sizeof(*id
));
2051 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*id
)) < 0) {
2052 tprintf("Length of Req matchs not Type %u",
2057 tprintf("Location Subj: %u, ", id
->loc_subj
);
2058 tprintf("Srv Intv Units: %u, ",
2059 le16_to_cpu(id
->loc_srv_intv_unit
));
2060 tprintf("Srv Intv: %u", id
->loc_srv_intv
);
2062 if(!subelements(pkt
,
2063 meas_req
->len
- 3 - sizeof(*id
)))
2066 else if(meas_req
->type
== 255) {
2067 struct element_meas_pause
*pause
;
2069 pause
= (struct element_meas_pause
*)
2070 pkt_pull(pkt
, sizeof(*pause
));
2074 if ((ssize_t
)(meas_req
->len
- 3 - sizeof(*pause
)) < 0) {
2075 tprintf("Length of Req matchs not Type %u",
2080 tprintf("Pause Time: %fs, ", pause
->time
* 10 * TU
);
2082 if(!subelements(pkt
,
2083 meas_req
->len
- 3 - sizeof(*pause
)))
2087 tprintf("Length field indicates data,"
2088 " but could not interpreted");
2096 static int8_t inf_meas_rep(struct pkt_buff
*pkt
, u8
*id
)
2098 struct element_meas_rep
*meas_rep
;
2100 meas_rep
= (struct element_meas_rep
*) pkt_pull(pkt
, sizeof(*meas_rep
));
2101 if (meas_rep
== NULL
)
2104 tprintf(" Measurement Rep (%u, Len(%u)): ", *id
, meas_rep
->len
);
2105 if (len_lt_error(meas_rep
->len
, 3))
2108 tprintf("Token: %u, ", meas_rep
->token
);
2109 tprintf("Rep Mode: 0x%x (Late (%u), Incapable(%u), Refused(%u), ",
2110 meas_rep
->rep_mode
, meas_rep
->rep_mode
>> 7,
2111 (meas_rep
->rep_mode
>> 6) & 0x1,
2112 (meas_rep
->rep_mode
>> 5) & 0x1);
2113 tprintf("Type: %s (%u), ", meas_type(meas_rep
->type
), meas_rep
->type
);
2115 if(meas_rep
->len
> 3) {
2116 if(meas_rep
->type
== 0) {
2117 struct element_meas_basic
*basic
;
2119 basic
= (struct element_meas_basic
*)
2120 pkt_pull(pkt
, sizeof(*basic
));
2124 if ((meas_rep
->len
- 3 - sizeof(*basic
)) != 0) {
2125 tprintf("Length of Req matchs not Type %u",
2130 tprintf("Ch Nr: %uus, ", basic
->ch_nr
);
2131 tprintf("Meas Start Time: %"PRIu64
", ",
2132 le64_to_cpu(basic
->start
));
2133 tprintf("Meas Duration: %fs",
2134 le16_to_cpu(basic
->dur
) * TU
);
2137 else if(meas_rep
->type
== 1) {
2138 struct element_meas_cca
*cca
;
2140 cca
= (struct element_meas_cca
*)
2141 pkt_pull(pkt
, sizeof(*cca
));
2145 if ((meas_rep
->len
- 3 - sizeof(*cca
)) != 0) {
2146 tprintf("Length of Req matchs not Type %u",
2151 tprintf("Ch Nr: %uus, ", cca
->ch_nr
);
2152 tprintf("Meas Start Time: %"PRIu64
", ",
2153 le64_to_cpu(cca
->start
));
2154 tprintf("Meas Duration: %fs",
2155 le16_to_cpu(cca
->dur
) * TU
);
2157 else if(meas_rep
->type
== 2) {
2158 struct element_meas_rpi
*rpi
;
2160 rpi
= (struct element_meas_rpi
*)
2161 pkt_pull(pkt
, sizeof(*rpi
));
2165 if ((meas_rep
->len
- 3 - sizeof(*rpi
)) != 0) {
2166 tprintf("Length of Req matchs not Type %u",
2171 tprintf("Ch Nr: %uus, ", rpi
->ch_nr
);
2172 tprintf("Meas Start Time: %"PRIu64
", ",
2173 le64_to_cpu(rpi
->start
));
2174 tprintf("Meas Duration: %fs",
2175 le16_to_cpu(rpi
->dur
) * TU
);
2177 else if(meas_rep
->type
== 3) {
2178 struct element_meas_ch_load
*ch_load
;
2180 ch_load
= (struct element_meas_ch_load
*)
2181 pkt_pull(pkt
, sizeof(*ch_load
));
2182 if (ch_load
== NULL
)
2185 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*ch_load
)) < 0) {
2186 tprintf("Length of Req matchs not Type %u",
2191 tprintf("OP Class: %u, ", ch_load
->op_class
);
2192 tprintf("Ch Nr: %u, ", ch_load
->ch_nr
);
2193 tprintf("Rand Intv: %fs, ",
2194 le16_to_cpu(ch_load
->rand_intv
) * TU
);
2195 tprintf("Meas Duration: %fs",
2196 le16_to_cpu(ch_load
->dur
) * TU
);
2198 if(!subelements(pkt
,
2199 meas_rep
->len
- 3 - sizeof(*ch_load
)))
2202 else if(meas_rep
->type
== 4) {
2203 struct element_meas_noise
*noise
;
2205 noise
= (struct element_meas_noise
*)
2206 pkt_pull(pkt
, sizeof(*noise
));
2210 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*noise
)) < 0) {
2211 tprintf("Length of Req matchs not Type %u",
2216 tprintf("OP Class: %u, ", noise
->op_class
);
2217 tprintf("Ch Nr: %u, ", noise
->ch_nr
);
2218 tprintf("Rand Intv: %fs, ",
2219 le16_to_cpu(noise
->rand_intv
) * TU
);
2220 tprintf("Meas Duration: %fs",
2221 le16_to_cpu(noise
->dur
) * TU
);
2223 if(!subelements(pkt
,
2224 meas_rep
->len
- 3 - sizeof(*noise
)))
2227 else if(meas_rep
->type
== 5) {
2228 struct element_meas_beacon
*beacon
;
2230 beacon
= (struct element_meas_beacon
*)
2231 pkt_pull(pkt
, sizeof(*beacon
));
2235 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*beacon
)) < 0) {
2236 tprintf("Length of Req matchs not Type %u",
2241 tprintf("OP Class: %u, ", beacon
->op_class
);
2242 tprintf("Ch Nr: %u, ", beacon
->ch_nr
);
2243 tprintf("Rand Intv: %fs, ",
2244 le16_to_cpu(beacon
->rand_intv
) * TU
);
2245 tprintf("Meas Duration: %fs",
2246 le16_to_cpu(beacon
->dur
) * TU
);
2247 tprintf("Mode: %u, ", beacon
->mode
);
2248 tprintf("BSSID: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2249 beacon
->bssid
[0], beacon
->bssid
[1],
2250 beacon
->bssid
[2], beacon
->bssid
[3],
2251 beacon
->bssid
[4], beacon
->bssid
[5]);
2253 if(!subelements(pkt
,
2254 meas_rep
->len
- 3 - sizeof(*beacon
)))
2257 else if(meas_rep
->type
== 6) {
2258 struct element_meas_frame
*frame
;
2260 frame
= (struct element_meas_frame
*)
2261 pkt_pull(pkt
, sizeof(*frame
));
2265 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*frame
)) < 0) {
2266 tprintf("Length of Req matchs not Type %u",
2271 tprintf("OP Class: %u, ", frame
->op_class
);
2272 tprintf("Ch Nr: %u, ", frame
->ch_nr
);
2273 tprintf("Rand Intv: %fs, ",
2274 le16_to_cpu(frame
->rand_intv
) * TU
);
2275 tprintf("Meas Duration: %fs",
2276 le16_to_cpu(frame
->dur
) * TU
);
2277 tprintf("Request Type: %u, ", frame
->frame
);
2278 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2279 frame
->mac
[0], frame
->mac
[1],
2280 frame
->mac
[2], frame
->mac
[3],
2281 frame
->mac
[4], frame
->mac
[5]);
2283 if(!subelements(pkt
,
2284 meas_rep
->len
- 3 - sizeof(*frame
)))
2287 else if(meas_rep
->type
== 7) {
2288 struct element_meas_sta
*sta
;
2290 sta
= (struct element_meas_sta
*)
2291 pkt_pull(pkt
, sizeof(*sta
));
2295 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*sta
)) < 0) {
2296 tprintf("Length of Req matchs not Type %u",
2301 tprintf("Peer MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2302 sta
->peer_mac
[0], sta
->peer_mac
[1],
2303 sta
->peer_mac
[2], sta
->peer_mac
[3],
2304 sta
->peer_mac
[4], sta
->peer_mac
[5]);
2305 tprintf("Rand Intv: %fs, ",
2306 le16_to_cpu(sta
->rand_intv
) * TU
);
2307 tprintf("Meas Duration: %fs",
2308 le16_to_cpu(sta
->dur
) * TU
);
2309 tprintf("Group ID: %u, ", sta
->group_id
);
2311 if(!subelements(pkt
,
2312 meas_rep
->len
- 3 - sizeof(*sta
)))
2315 else if(meas_rep
->type
== 8) {
2316 struct element_meas_lci
*lci
;
2318 lci
= (struct element_meas_lci
*)
2319 pkt_pull(pkt
, sizeof(*lci
));
2323 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*lci
)) < 0) {
2324 tprintf("Length of Req matchs not Type %u",
2329 tprintf("Location Subj: %u, ", lci
->loc_subj
);
2330 tprintf("Latitude Req Res: %udeg",
2331 lci
->latitude_req_res
);
2332 tprintf("Longitude Req Res: %udeg",
2333 lci
->longitude_req_res
);
2334 tprintf("Altitude Req Res: %udeg",
2335 lci
->altitude_req_res
);
2337 if(!subelements(pkt
,
2338 meas_rep
->len
- 3 - sizeof(*lci
)))
2341 else if(meas_rep
->type
== 9) {
2342 struct element_meas_trans_str_cat
*trans
;
2344 trans
= (struct element_meas_trans_str_cat
*)
2345 pkt_pull(pkt
, sizeof(*trans
));
2349 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*trans
)) < 0) {
2350 tprintf("Length of Req matchs not Type %u",
2355 tprintf("Rand Intv: %fs, ",
2356 le16_to_cpu(trans
->rand_intv
) * TU
);
2357 tprintf("Meas Duration: %fs",
2358 le16_to_cpu(trans
->dur
) * TU
);
2359 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2360 trans
->peer_sta_addr
[0], trans
->peer_sta_addr
[1],
2361 trans
->peer_sta_addr
[2], trans
->peer_sta_addr
[3],
2362 trans
->peer_sta_addr
[4], trans
->peer_sta_addr
[5]);
2363 tprintf("Traffic ID: %u, ", trans
->traffic_id
);
2364 tprintf("Bin 0 Range: %u, ", trans
->bin_0_range
);
2366 if(!subelements(pkt
,
2367 meas_rep
->len
- 3 - sizeof(*trans
)))
2370 else if(meas_rep
->type
== 10) {
2371 struct element_meas_mcast_diag
*mcast
;
2373 mcast
= (struct element_meas_mcast_diag
*)
2374 pkt_pull(pkt
, sizeof(*mcast
));
2378 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*mcast
)) < 0) {
2379 tprintf("Length of Req matchs not Type %u",
2384 tprintf("Rand Intv: %fs, ",
2385 le16_to_cpu(mcast
->rand_intv
) * TU
);
2386 tprintf("Meas Duration: %fs",
2387 le16_to_cpu(mcast
->dur
) * TU
);
2388 tprintf("Group MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2389 mcast
->group_mac
[0], mcast
->group_mac
[1],
2390 mcast
->group_mac
[2], mcast
->group_mac
[3],
2391 mcast
->group_mac
[4], mcast
->group_mac
[5]);
2393 if(!subelements(pkt
,
2394 meas_rep
->len
- 3 - sizeof(*mcast
)))
2397 else if(meas_rep
->type
== 11) {
2398 struct element_meas_loc_civic
*civic
;
2400 civic
= (struct element_meas_loc_civic
*)
2401 pkt_pull(pkt
, sizeof(*civic
));
2405 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*civic
)) < 0) {
2406 tprintf("Length of Req matchs not Type %u",
2411 tprintf("Location Subj: %u, ", civic
->loc_subj
);
2412 tprintf("Type: %u, ", civic
->civic_loc
);
2413 tprintf("Srv Intv Units: %u, ",
2414 le16_to_cpu(civic
->loc_srv_intv_unit
));
2415 tprintf("Srv Intv: %u, ", civic
->loc_srv_intv
);
2417 if(!subelements(pkt
,
2418 meas_rep
->len
- 3 - sizeof(*civic
)))
2421 else if(meas_rep
->type
== 12) {
2422 struct element_meas_loc_id
*id
;
2424 id
= (struct element_meas_loc_id
*)
2425 pkt_pull(pkt
, sizeof(*id
));
2429 if ((ssize_t
)(meas_rep
->len
- 3 - sizeof(*id
)) < 0) {
2430 tprintf("Length of Req matchs not Type %u",
2435 tprintf("Location Subj: %u, ", id
->loc_subj
);
2436 tprintf("Srv Intv Units: %u, ",
2437 le16_to_cpu(id
->loc_srv_intv_unit
));
2438 tprintf("Srv Intv: %u", id
->loc_srv_intv
);
2440 if(!subelements(pkt
,
2441 meas_rep
->len
- 3 - sizeof(*id
)))
2445 tprintf("Length field indicates data,"
2446 " but could not interpreted");
2454 static int8_t inf_quiet(struct pkt_buff
*pkt
, u8
*id
)
2456 struct element_quiet
*quiet
;
2458 quiet
= (struct element_quiet
*) pkt_pull(pkt
, sizeof(*quiet
));
2462 tprintf(" Quit (%u, Len(%u)): ", *id
, quiet
->len
);
2463 if (len_neq_error(quiet
->len
, 6))
2466 tprintf("Count: %ud, ", quiet
->cnt
);
2467 tprintf("Period: %u, ", quiet
->period
);
2468 tprintf("Duration: %fs, ", le16_to_cpu(quiet
->dur
) * TU
);
2469 tprintf("Offs: %fs", le16_to_cpu(quiet
->offs
) * TU
);
2475 static int8_t inf_ibss_dfs(struct pkt_buff
*pkt
, u8
*id
)
2477 struct element_ibss_dfs
*ibss_dfs
;
2480 ibss_dfs
= (struct element_ibss_dfs
*) pkt_pull(pkt
, sizeof(*ibss_dfs
));
2481 if (ibss_dfs
== NULL
)
2484 tprintf(" IBSS DFS (%u, Len(%u)): ", *id
, ibss_dfs
->len
);
2485 if (len_lt_error(ibss_dfs
->len
, 7))
2488 tprintf("Owner: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2489 ibss_dfs
->owner
[0], ibss_dfs
->owner
[1],
2490 ibss_dfs
->owner
[2], ibss_dfs
->owner
[3],
2491 ibss_dfs
->owner
[4], ibss_dfs
->owner
[5]);
2492 tprintf("Recovery Intv: %u, ", ibss_dfs
->rec_intv
);
2494 if((ibss_dfs
->len
- sizeof(*ibss_dfs
) + 1) & 1) {
2495 tprintf("Length of Channel Map should be modulo 2");
2499 for (i
= 0; i
< ibss_dfs
->len
; i
+= 2) {
2500 struct element_ibss_dfs_tuple
*ibss_dfs_tuple
;
2502 ibss_dfs_tuple
= (struct element_ibss_dfs_tuple
*)
2503 pkt_pull(pkt
, sizeof(*ibss_dfs_tuple
));
2504 if (ibss_dfs_tuple
== NULL
)
2507 tprintf("Channel Nr: %u, ", ibss_dfs_tuple
->ch_nr
);
2508 tprintf("Map: %u, ", ibss_dfs_tuple
->map
);
2514 static int8_t inf_erp(struct pkt_buff
*pkt
, u8
*id
)
2516 struct element_erp
*erp
;
2518 erp
= (struct element_erp
*) pkt_pull(pkt
, sizeof(*erp
));
2522 tprintf(" ERP (%u, Len(%u)): ", *id
, erp
->len
);
2523 if (len_neq_error(erp
->len
, 1))
2525 tprintf("Non ERP Present (%u), ", erp
->param
& 0x1);
2526 tprintf("Use Protection (%u), ", (erp
->param
>> 1) & 0x1);
2527 tprintf("Barker Preamble Mode (%u), ", (erp
->param
>> 2) & 0x1);
2528 tprintf("Reserved (0x%.5x)", erp
->param
>> 3);
2533 static int8_t inf_ts_del(struct pkt_buff
*pkt
, u8
*id
)
2535 struct element_ts_del
*ts_del
;
2537 ts_del
= (struct element_ts_del
*) pkt_pull(pkt
, sizeof(*ts_del
));
2541 tprintf(" TS Delay (%u, Len(%u)): ", *id
, ts_del
->len
);
2542 if (len_neq_error(ts_del
->len
, 4))
2544 tprintf("Delay (%fs)", le32_to_cpu(ts_del
->delay
) * TU
);
2549 static int8_t inf_tclas_proc(struct pkt_buff
*pkt
, u8
*id
)
2551 struct element_tclas_proc
*tclas_proc
;
2553 tclas_proc
= (struct element_tclas_proc
*)
2554 pkt_pull(pkt
, sizeof(*tclas_proc
));
2555 if (tclas_proc
== NULL
)
2558 tprintf(" TCLAS Procesing (%u, Len(%u)): ", *id
, tclas_proc
->len
);
2559 if (len_neq_error(tclas_proc
->len
, 1))
2561 tprintf("Processing (%u)", tclas_proc
->proc
);
2566 static int8_t inf_ht_cap(struct pkt_buff
*pkt
, u8
*id
)
2568 struct element_ht_cap
*ht_cap
;
2569 u32 tx_param_res
, beam_cap
;
2572 ht_cap
= (struct element_ht_cap
*)
2573 pkt_pull(pkt
, sizeof(*ht_cap
));
2577 tx_param_res
= le32_to_cpu(ht_cap
->tx_param_res
);
2578 beam_cap
= le32_to_cpu(ht_cap
->beam_cap
);
2579 ext_cap
= le16_to_cpu(ht_cap
->ext_cap
);
2581 tprintf(" HT Capabilities (%u, Len(%u)):\n", *id
, ht_cap
->len
);
2582 if (len_neq_error(ht_cap
->len
, 26))
2585 tprintf("\t\t Info:\n");
2586 tprintf("\t\t\t LDCP Cod Cap (%u)\n", ht_cap
->ldpc
);
2587 tprintf("\t\t\t Supp Ch Width Set (%u)\n", ht_cap
->supp_width
);
2588 tprintf("\t\t\t SM Pwr Save(%u)\n", ht_cap
->sm_pwr
);
2589 tprintf("\t\t\t HT-Greenfield (%u)\n", ht_cap
->ht_green
);
2590 tprintf("\t\t\t Short GI for 20/40 MHz (%u/%u)\n", ht_cap
->gi_20mhz
,
2592 tprintf("\t\t\t Tx/Rx STBC (%u/%u)\n", ht_cap
->tx_stbc
,
2594 tprintf("\t\t\t HT-Delayed Block Ack (%u)\n", ht_cap
->ht_ack
);
2595 tprintf("\t\t\t Max A-MSDU Len (%u)\n", ht_cap
->max_msdu_length
);
2596 tprintf("\t\t\t DSSS/CCK Mode in 40 MHz (%u)\n",
2597 ht_cap
->dsss_ck_mode
);
2598 tprintf("\t\t\t Res (0x%x)\n", ht_cap
->res
);
2599 tprintf("\t\t\t Forty MHz Intol (%u)\n", ht_cap
->forty_int
);
2600 tprintf("\t\t\t L-SIG TXOP Protection Supp (%u)\n",
2603 tprintf("\t\t A-MPDU Params:\n");
2604 tprintf("\t\t\t Max Len Exp (%u)\n", ht_cap
->param
>> 6);
2605 tprintf("\t\t\t Min Start Spacing (%u)\n",
2606 (ht_cap
->param
>> 3) & 0x7);
2607 tprintf("\t\t\t Res (0x%x)\n", ht_cap
->param
& 0x07);
2609 tprintf("\t\t Supp MCS Set:\n");
2610 tprintf("\t\t\t Rx MCS Bitmask (0x%x%x%x%x%x%x%x%x%x%x)\n",
2611 ht_cap
->bitmask1
, ht_cap
->bitmask2
, ht_cap
->bitmask3
,
2612 ht_cap
->bitmask4
, ht_cap
->bitmask5
, ht_cap
->bitmask6
,
2613 ht_cap
->bitmask7
, ht_cap
->bitmask8
, ht_cap
->bitmask9
,
2614 ht_cap
->bitmask10_res
>> 3);
2615 tprintf("\t\t\t Res (0x%x)\n", ht_cap
->bitmask10_res
& 0x7);
2616 tprintf("\t\t\t Rx High Supp Data Rate (%u)\n",
2617 le16_to_cpu(ht_cap
->supp_rate_res
) >> 6);
2618 tprintf("\t\t\t Res (0x%x)\n",
2619 le16_to_cpu(ht_cap
->supp_rate_res
) & 0x3F);
2620 tprintf("\t\t\t Tx MCS Set Def (%u)\n", tx_param_res
>> 31);
2621 tprintf("\t\t\t Tx Rx MCS Set Not Eq (%u)\n",
2622 (tx_param_res
>> 30) & 1);
2623 tprintf("\t\t\t Tx Max Number Spat Str Supp (%u)\n",
2624 (tx_param_res
>> 28) & 3);
2625 tprintf("\t\t\t Tx Uneq Mod Supp (%u)\n", (tx_param_res
>> 27) & 1);
2626 tprintf("\t\t\t Res (0x%x)\n", tx_param_res
& 0x7FFFFFF);
2628 tprintf("\t\t Ext Cap:\n");
2629 tprintf("\t\t\t PCO (%u)\n", ext_cap
>> 15);
2630 tprintf("\t\t\t PCO Trans Time (%u)\n", (ext_cap
>> 13) & 3);
2631 tprintf("\t\t\t Res (0x%x)\n", (ext_cap
>> 8) & 0x1F);
2632 tprintf("\t\t\t MCS Feedb (%u)\n", (ext_cap
>> 6) & 3);
2633 tprintf("\t\t\t +HTC Supp (%u)\n", (ext_cap
>> 5) & 1);
2634 tprintf("\t\t\t RD Resp (%u)\n", (ext_cap
>> 4) & 1);
2635 tprintf("\t\t\t Res (0x%x)\n", ext_cap
& 0xF);
2637 tprintf("\t\t Transm Beamf:\n");
2638 tprintf("\t\t\t Impl Transm Beamf Rec Cap (%u)\n", beam_cap
>> 31);
2639 tprintf("\t\t\t Rec/Transm Stagg Sound Cap (%u/%u)\n",
2640 (beam_cap
>> 30) & 1, (beam_cap
>> 29) & 1);
2641 tprintf("\t\t\t Rec/Trans NDP Cap (%u/%u)\n",
2642 (beam_cap
>> 28) & 1, (beam_cap
>> 27) & 1);
2643 tprintf("\t\t\t Impl Transm Beamf Cap (%u)\n", (beam_cap
>> 26) & 1);
2644 tprintf("\t\t\t Cal (%u)\n", (beam_cap
>> 24) & 3);
2645 tprintf("\t\t\t Expl CSI Transm Beamf Cap (%u)\n",
2646 (beam_cap
>> 23) & 1);
2647 tprintf("\t\t\t Expl Noncmpr/Compr Steering Cap (%u/%u)\n",
2648 (beam_cap
>> 22) & 1, (beam_cap
>> 21) & 1);
2649 tprintf("\t\t\t Expl Trans Beamf CSI Feedb (%u)\n",
2650 (beam_cap
>> 19) & 3);
2651 tprintf("\t\t\t Expl Noncmpr/Cmpr Feedb Cap (%u/%u)\n",
2652 (beam_cap
>> 17) & 3, (beam_cap
>> 15) & 3);
2653 tprintf("\t\t\t Min Grpg (%u)\n", (beam_cap
>> 13) & 3);
2654 tprintf("\t\t\t CSI Num Beamf Ant Supp (%u)\n", (beam_cap
>> 11) & 3);
2655 tprintf("\t\t\t Noncmpr/Cmpr Steering Nr Beamf Ant Supp (%u/%u)\n",
2656 (beam_cap
>> 9) & 3, (beam_cap
>> 7) & 3);
2657 tprintf("\t\t\t CSI Max Nr Rows Beamf Supp (%u)\n",
2658 (beam_cap
>> 5) & 3);
2659 tprintf("\t\t\t Ch Estim Cap (%u)\n", (beam_cap
>> 3) & 3);
2660 tprintf("\t\t\t Res (0x%x)\n", beam_cap
& 7);
2662 tprintf("\t\t ASEL:\n");
2663 tprintf("\t\t\t Ant Select Cap (%u)\n", ht_cap
->asel_cap
>> 7);
2664 tprintf("\t\t\t Expl CSI Feedb Based Transm ASEL Cap (%u)\n",
2665 (ht_cap
->asel_cap
>> 6) & 1);
2666 tprintf("\t\t\t Ant Indic Feedb Based Transm ASEL Cap (%u)\n",
2667 (ht_cap
->asel_cap
>> 5) & 1);
2668 tprintf("\t\t\t Expl CSI Feedb Cap (%u)\n",
2669 (ht_cap
->asel_cap
>> 4) & 1);
2670 tprintf("\t\t\t Ant Indic Feedb Cap (%u)\n",
2671 (ht_cap
->asel_cap
>> 3) & 1);
2672 tprintf("\t\t\t Rec ASEL Cap (%u)\n", (ht_cap
->asel_cap
>> 2) & 1);
2673 tprintf("\t\t\t Transm Sound PPDUs Cap (%u)\n",
2674 (ht_cap
->asel_cap
>> 1) & 1);
2675 tprintf("\t\t\t Res (0x%x)", ht_cap
->asel_cap
& 1);
2680 static int8_t inf_qos_cap(struct pkt_buff
*pkt
, u8
*id
)
2682 struct element_qos_cap
*qos_cap
;
2684 qos_cap
= (struct element_qos_cap
*)
2685 pkt_pull(pkt
, sizeof(*qos_cap
));
2686 if (qos_cap
== NULL
)
2689 tprintf(" QoS Capabilities (%u, Len(%u)): ", *id
, qos_cap
->len
);
2690 if (len_neq_error(qos_cap
->len
, 1))
2693 tprintf("Info (0x%x)", qos_cap
->info
);
2698 static int8_t inf_ext_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
2702 struct element_ext_supp_rates
*ext_supp_rates
;
2704 ext_supp_rates
= (struct element_ext_supp_rates
*)
2705 pkt_pull(pkt
, sizeof(*ext_supp_rates
));
2706 if (ext_supp_rates
== NULL
)
2709 tprintf(" Ext Support Rates (%u, Len(%u)): ", *id
, ext_supp_rates
->len
);
2711 if ((ext_supp_rates
->len
- sizeof(*ext_supp_rates
) + 1) > 0) {
2712 rates
= pkt_pull(pkt
, ext_supp_rates
->len
);
2716 for (i
= 0; i
< ext_supp_rates
->len
; i
++)
2717 tprintf("%g ", (rates
[i
] & 0x80) ?
2718 ((rates
[i
] & 0x3f) * 0.5) :
2719 data_rates(rates
[i
]));
2726 static int8_t inf_vend_spec(struct pkt_buff
*pkt
, u8
*id
)
2730 struct element_vend_spec
*vend_spec
;
2732 vend_spec
= (struct element_vend_spec
*)
2733 pkt_pull(pkt
, sizeof(*vend_spec
));
2734 if (vend_spec
== NULL
)
2737 tprintf(" Vendor Specific (%u, Len (%u)): ", *id
, vend_spec
->len
);
2739 data
= pkt_pull(pkt
, vend_spec
->len
);
2744 for (i
= 0; i
< vend_spec
->len
; i
++)
2745 tprintf("%.2x", data
[i
]);
2750 static int8_t inf_unimplemented(struct pkt_buff
*pkt __maybe_unused
,
2751 u8
*id __maybe_unused
)
2756 static int8_t inf_elements(struct pkt_buff
*pkt
)
2758 u8
*id
= pkt_pull(pkt
, 1);
2763 case 0: return inf_ssid(pkt
, id
);
2764 case 1: return inf_supp_rates(pkt
, id
);
2765 case 2: return inf_fh_ps(pkt
, id
);
2766 case 3: return inf_dsss_ps(pkt
, id
);
2767 case 4: return inf_cf_ps(pkt
, id
);
2768 case 5: return inf_tim(pkt
, id
);
2769 case 6: return inf_ibss_ps(pkt
, id
);
2770 case 7: return inf_country(pkt
, id
);
2771 case 8: return inf_hop_pp(pkt
, id
);
2772 case 9: return inf_hop_pt(pkt
, id
);
2773 case 10: return inf_req(pkt
, id
);
2774 case 11: return inf_bss_load(pkt
, id
);
2775 case 12: return inf_edca_ps(pkt
, id
);
2776 case 13: return inf_tspec(pkt
, id
);
2777 case 14: return inf_tclas(pkt
, id
);
2778 case 15: return inf_sched(pkt
, id
);
2779 case 16: return inf_chall_txt(pkt
, id
);
2780 case 17 ... 31: return inf_reserved(pkt
, id
);
2781 case 32: return inf_pwr_constr(pkt
, id
);
2782 case 33: return inf_pwr_cap(pkt
, id
);
2783 case 34: return inf_tpc_req(pkt
, id
);
2784 case 35: return inf_tpc_rep(pkt
, id
);
2785 case 36: return inf_supp_ch(pkt
, id
);
2786 case 37: return inf_ch_sw_ann(pkt
, id
);
2787 case 38: return inf_meas_req(pkt
, id
);
2788 case 39: return inf_meas_rep(pkt
, id
);
2789 case 40: return inf_quiet(pkt
, id
);
2790 case 41: return inf_ibss_dfs(pkt
, id
);
2791 case 42: return inf_erp(pkt
, id
);
2792 case 43: return inf_ts_del(pkt
, id
);
2793 case 44: return inf_tclas_proc(pkt
, id
);
2794 case 45: return inf_ht_cap(pkt
, id
);
2795 case 46: return inf_qos_cap(pkt
, id
);
2796 case 47: return inf_reserved(pkt
, id
);
2797 case 48: return inf_unimplemented(pkt
, id
);
2798 case 49: return inf_unimplemented(pkt
, id
);
2799 case 50: return inf_ext_supp_rates(pkt
, id
);
2800 case 51: return inf_unimplemented(pkt
, id
);
2801 case 52: return inf_unimplemented(pkt
, id
);
2802 case 53: return inf_unimplemented(pkt
, id
);
2803 case 54: return inf_unimplemented(pkt
, id
);
2804 case 55: return inf_unimplemented(pkt
, id
);
2805 case 56: return inf_unimplemented(pkt
, id
);
2806 case 57: return inf_unimplemented(pkt
, id
);
2807 case 58: return inf_unimplemented(pkt
, id
);
2808 case 59: return inf_unimplemented(pkt
, id
);
2809 case 60: return inf_unimplemented(pkt
, id
);
2810 case 61: return inf_unimplemented(pkt
, id
);
2811 case 62: return inf_unimplemented(pkt
, id
);
2812 case 63: return inf_unimplemented(pkt
, id
);
2813 case 64: return inf_unimplemented(pkt
, id
);
2814 case 65: return inf_unimplemented(pkt
, id
);
2815 case 66: return inf_unimplemented(pkt
, id
);
2816 case 67: return inf_unimplemented(pkt
, id
);
2817 case 68: return inf_unimplemented(pkt
, id
);
2818 case 69: return inf_unimplemented(pkt
, id
);
2819 case 70: return inf_unimplemented(pkt
, id
);
2820 case 71: return inf_unimplemented(pkt
, id
);
2821 case 72: return inf_unimplemented(pkt
, id
);
2822 case 73: return inf_unimplemented(pkt
, id
);
2823 case 74: return inf_unimplemented(pkt
, id
);
2824 case 75: return inf_unimplemented(pkt
, id
);
2825 case 76: return inf_unimplemented(pkt
, id
);
2826 case 78: return inf_unimplemented(pkt
, id
);
2827 case 79: return inf_unimplemented(pkt
, id
);
2828 case 80: return inf_unimplemented(pkt
, id
);
2829 case 81: return inf_unimplemented(pkt
, id
);
2830 case 82: return inf_unimplemented(pkt
, id
);
2831 case 83: return inf_unimplemented(pkt
, id
);
2832 case 84: return inf_unimplemented(pkt
, id
);
2833 case 85: return inf_unimplemented(pkt
, id
);
2834 case 86: return inf_unimplemented(pkt
, id
);
2835 case 87: return inf_unimplemented(pkt
, id
);
2836 case 88: return inf_unimplemented(pkt
, id
);
2837 case 89: return inf_unimplemented(pkt
, id
);
2838 case 90: return inf_unimplemented(pkt
, id
);
2839 case 91: return inf_unimplemented(pkt
, id
);
2840 case 92: return inf_unimplemented(pkt
, id
);
2841 case 93: return inf_unimplemented(pkt
, id
);
2842 case 94: return inf_unimplemented(pkt
, id
);
2843 case 95: return inf_unimplemented(pkt
, id
);
2844 case 96: return inf_unimplemented(pkt
, id
);
2845 case 97: return inf_unimplemented(pkt
, id
);
2846 case 98: return inf_unimplemented(pkt
, id
);
2847 case 99: return inf_unimplemented(pkt
, id
);
2848 case 100: return inf_unimplemented(pkt
, id
);
2849 case 101: return inf_unimplemented(pkt
, id
);
2850 case 102: return inf_unimplemented(pkt
, id
);
2851 case 104: return inf_unimplemented(pkt
, id
);
2852 case 105: return inf_unimplemented(pkt
, id
);
2853 case 106: return inf_unimplemented(pkt
, id
);
2854 case 107: return inf_unimplemented(pkt
, id
);
2855 case 108: return inf_unimplemented(pkt
, id
);
2856 case 109: return inf_unimplemented(pkt
, id
);
2857 case 110: return inf_unimplemented(pkt
, id
);
2858 case 111: return inf_unimplemented(pkt
, id
);
2859 case 112: return inf_unimplemented(pkt
, id
);
2860 case 113: return inf_unimplemented(pkt
, id
);
2861 case 114: return inf_unimplemented(pkt
, id
);
2862 case 115: return inf_unimplemented(pkt
, id
);
2863 case 116: return inf_unimplemented(pkt
, id
);
2864 case 117: return inf_unimplemented(pkt
, id
);
2865 case 118: return inf_unimplemented(pkt
, id
);
2866 case 119: return inf_unimplemented(pkt
, id
);
2867 case 120: return inf_unimplemented(pkt
, id
);
2868 case 121: return inf_unimplemented(pkt
, id
);
2869 case 122: return inf_unimplemented(pkt
, id
);
2870 case 123: return inf_unimplemented(pkt
, id
);
2871 case 124: return inf_unimplemented(pkt
, id
);
2872 case 125: return inf_unimplemented(pkt
, id
);
2873 case 126: return inf_unimplemented(pkt
, id
);
2874 case 127: return inf_unimplemented(pkt
, id
);
2875 case 128: return inf_reserved(pkt
, id
);
2876 case 129: return inf_reserved(pkt
, id
);
2877 case 130: return inf_unimplemented(pkt
, id
);
2878 case 131: return inf_unimplemented(pkt
, id
);
2879 case 132: return inf_unimplemented(pkt
, id
);
2880 case 133: return inf_reserved(pkt
, id
);
2881 case 134: return inf_reserved(pkt
, id
);
2882 case 135: return inf_reserved(pkt
, id
);
2883 case 136: return inf_reserved(pkt
, id
);
2884 case 137: return inf_unimplemented(pkt
, id
);
2885 case 138: return inf_unimplemented(pkt
, id
);
2886 case 139: return inf_unimplemented(pkt
, id
);
2887 case 140: return inf_unimplemented(pkt
, id
);
2888 case 141: return inf_unimplemented(pkt
, id
);
2889 case 142: return inf_unimplemented(pkt
, id
);
2890 case 143 ... 173: return inf_reserved(pkt
, id
);
2891 case 174: return inf_unimplemented(pkt
, id
);
2892 case 221: return inf_vend_spec(pkt
, id
);
2900 #define CF_Pollable 0x0004
2901 #define CF_Poll_Req 0x0008
2902 #define Privacy 0x0010
2903 #define Short_Pre 0x0020
2905 #define Ch_Agility 0x0080
2906 #define Spec_Mgmt 0x0100
2908 #define Short_Slot_t 0x0400
2910 #define Radio_Meas 0x1000
2911 #define DSSS_OFDM 0x2000
2912 #define Del_Block_ACK 0x4000
2913 #define Imm_Block_ACK 0x8000
2915 static int8_t cap_field(u16 cap_inf
)
2921 if (CF_Pollable
& cap_inf
)
2922 tprintf(" CF Pollable;");
2923 if (CF_Poll_Req
& cap_inf
)
2924 tprintf(" CF-Poll Request;");
2925 if (Privacy
& cap_inf
)
2926 tprintf(" Privacy;");
2927 if (Short_Pre
& cap_inf
)
2928 tprintf(" Short Preamble;");
2931 if (Ch_Agility
& cap_inf
)
2932 tprintf(" Channel Agility;");
2933 if (Spec_Mgmt
& cap_inf
)
2934 tprintf(" Spectrum Management;");
2937 if (Short_Slot_t
& cap_inf
)
2938 tprintf(" Short Slot Time;");
2941 if (Radio_Meas
& cap_inf
)
2942 tprintf(" Radio Measurement;");
2943 if (DSSS_OFDM
& cap_inf
)
2944 tprintf(" DSSS-OFDM;");
2945 if (Del_Block_ACK
& cap_inf
)
2946 tprintf(" Delayed Block Ack;");
2947 if (Imm_Block_ACK
& cap_inf
)
2948 tprintf(" Immediate Block Ack;");
2953 static void print_inf_elements(struct pkt_buff
*pkt
)
2960 } while (inf_elements(pkt
));
2964 /* Management Dissectors */
2965 static int8_t mgmt_beacon_dissect(struct pkt_buff
*pkt
)
2967 struct ieee80211_mgmt_beacon
*beacon
;
2969 beacon
= (struct ieee80211_mgmt_beacon
*)
2970 pkt_pull(pkt
, sizeof(*beacon
));
2974 tprintf("Timestamp 0x%.16"PRIx64
", ", le64_to_cpu(beacon
->timestamp
));
2975 tprintf("Beacon Interval (%fs), ", le16_to_cpu(beacon
->beacon_int
)*TU
);
2976 tprintf("Capabilities (0x%x <->", le16_to_cpu(beacon
->capab_info
));
2977 cap_field(le16_to_cpu(beacon
->capab_info
));
2980 print_inf_elements(pkt
);
2988 static int8_t mgmt_probe_request_dissect(struct pkt_buff
*pkt
)
2990 print_inf_elements(pkt
);
2998 static int8_t mgmt_unimplemented(struct pkt_buff
*pkt __maybe_unused
)
3002 /* End Management Dissectors */
3004 /* Control Dissectors */
3005 static int8_t ctrl_unimplemented(struct pkt_buff
*pkt __maybe_unused
)
3009 /* End Control Dissectors */
3011 /* Data Dissectors */
3012 static int8_t data_unimplemented(struct pkt_buff
*pkt __maybe_unused
)
3016 /* End Data Dissectors */
3018 static const char *mgt_sub(u8 subtype
, struct pkt_buff
*pkt
,
3019 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3022 struct ieee80211_mgmt
*mgmt
;
3023 const char *dst
, *src
, *bssid
;
3025 mgmt
= (struct ieee80211_mgmt
*) pkt_pull(pkt
, sizeof(*mgmt
));
3029 dst
= lookup_vendor((mgmt
->da
[0] << 16) |
3030 (mgmt
->da
[1] << 8) |
3032 src
= lookup_vendor((mgmt
->sa
[0] << 16) |
3033 (mgmt
->sa
[1] << 8) |
3036 bssid
= lookup_vendor((mgmt
->bssid
[0] << 16) |
3037 (mgmt
->bssid
[1] << 8) |
3039 seq_ctrl
= le16_to_cpu(mgmt
->seq_ctrl
);
3041 tprintf("Duration (%u),", le16_to_cpu(mgmt
->duration
));
3042 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3043 mgmt
->da
[0], mgmt
->da
[1], mgmt
->da
[2],
3044 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
3046 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst
,
3047 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
3050 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3051 mgmt
->sa
[0], mgmt
->sa
[1], mgmt
->sa
[2],
3052 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
3054 tprintf("=> (%s:%.2x:%.2x:%.2x)", src
,
3055 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
3058 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3059 mgmt
->bssid
[0], mgmt
->bssid
[1], mgmt
->bssid
[2],
3060 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
3062 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid
,
3063 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
3066 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ",
3067 seq_ctrl
& 0xf, seq_ctrl
>> 4);
3071 *get_content
= mgmt_unimplemented
;
3072 return "Association Request";
3074 *get_content
= mgmt_unimplemented
;
3075 return "Association Response";
3077 *get_content
= mgmt_unimplemented
;
3078 return "Reassociation Request";
3080 *get_content
= mgmt_unimplemented
;
3081 return "Reassociation Response";
3083 *get_content
= mgmt_probe_request_dissect
;
3084 return "Probe Request";
3086 /* Probe Response is very similar to Beacon except some IEs */
3087 *get_content
= mgmt_beacon_dissect
;
3088 return "Probe Response";
3090 *get_content
= mgmt_beacon_dissect
;
3093 *get_content
= mgmt_unimplemented
;
3096 *get_content
= mgmt_unimplemented
;
3097 return "Disassociation";
3099 *get_content
= mgmt_unimplemented
;
3100 return "Authentication";
3102 *get_content
= mgmt_unimplemented
;
3103 return "Deauthentication";
3105 *get_content
= NULL
;
3110 static const char *ctrl_sub(u8 subtype
, struct pkt_buff
*pkt __maybe_unused
,
3111 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3115 *get_content
= ctrl_unimplemented
;
3118 *get_content
= ctrl_unimplemented
;
3121 *get_content
= ctrl_unimplemented
;
3124 *get_content
= ctrl_unimplemented
;
3127 *get_content
= ctrl_unimplemented
;
3130 *get_content
= ctrl_unimplemented
;
3131 return "CF End + CF-ACK";
3133 *get_content
= NULL
;
3138 static const char *data_sub(u8 subtype
, struct pkt_buff
*pkt __maybe_unused
,
3139 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3143 *get_content
= data_unimplemented
;
3146 *get_content
= data_unimplemented
;
3147 return "Data + CF-ACK";
3149 *get_content
= data_unimplemented
;
3150 return "Data + CF-Poll";
3152 *get_content
= data_unimplemented
;
3153 return "Data + CF-ACK + CF-Poll";
3155 *get_content
= data_unimplemented
;
3158 *get_content
= data_unimplemented
;
3161 *get_content
= data_unimplemented
;
3164 *get_content
= data_unimplemented
;
3165 return "CF-ACK + CF-Poll";
3167 *get_content
= NULL
;
3173 frame_control_type(u8 type
, const char *(**get_subtype
)(u8 subtype
,
3174 struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)))
3178 *get_subtype
= mgt_sub
;
3179 return "Management";
3181 *get_subtype
= ctrl_sub
;
3184 *get_subtype
= data_sub
;
3187 *get_subtype
= NULL
;
3190 *get_subtype
= NULL
;
3191 return "Control Type unknown";
3195 static void ieee80211(struct pkt_buff
*pkt
)
3197 int8_t (*get_content
)(struct pkt_buff
*pkt
) = NULL
;
3198 const char *(*get_subtype
)(u8 subtype
, struct pkt_buff
*pkt
,
3199 int8_t (**get_content
)(struct pkt_buff
*pkt
)) = NULL
;
3200 const char *subtype
= NULL
;
3201 struct ieee80211_frm_ctrl
*frm_ctrl
;
3203 if (pkt
->link_type
== LINKTYPE_IEEE802_11_RADIOTAP
) {
3204 struct ieee80211_radiotap_header
*rtap
;
3206 rtap
= (struct ieee80211_radiotap_header
*)pkt_pull(pkt
,
3211 tprintf(" [ Radiotap ");
3212 tprintf("Version (%u), ", rtap
->version
);
3213 tprintf("Length (%u), ", le16_to_cpu(rtap
->len
));
3214 tprintf("Flags (0x%08x) ]\n", le32_to_cpu(rtap
->present
));
3216 pkt_pull(pkt
, le16_to_cpu(rtap
->len
) - sizeof(*rtap
));
3219 frm_ctrl
= (struct ieee80211_frm_ctrl
*)pkt_pull(pkt
, sizeof(*frm_ctrl
));
3220 if (frm_ctrl
== NULL
)
3223 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
3224 le16_to_cpu(frm_ctrl
->frame_control
));
3226 tprintf(" [ Proto Version (%u), ", frm_ctrl
->proto_version
);
3227 tprintf("Type (%u, %s), ", frm_ctrl
->type
,
3228 frame_control_type(frm_ctrl
->type
, &get_subtype
));
3230 subtype
= (*get_subtype
)(frm_ctrl
->subtype
, pkt
, &get_content
);
3231 tprintf("Subtype (%u, %s)", frm_ctrl
->subtype
, subtype
);
3233 tprintf("%s%s%s", colorize_start_full(black
, red
),
3234 "No SubType Data available", colorize_end());
3237 tprintf("%s%s", frm_ctrl
->to_ds
? ", Frame goes to DS" : "",
3238 frm_ctrl
->from_ds
? ", Frame comes from DS" : "");
3239 tprintf("%s", frm_ctrl
->more_frags
? ", More Fragments" : "");
3240 tprintf("%s", frm_ctrl
->retry
? ", Frame is retransmitted" : "");
3241 tprintf("%s", frm_ctrl
->power_mgmt
? ", In Power Saving Mode" : "");
3242 tprintf("%s", frm_ctrl
->more_data
? ", More Data" : "");
3243 tprintf("%s", frm_ctrl
->wep
? ", Needs WEP" : "");
3244 tprintf("%s", frm_ctrl
->order
? ", Order" : "");
3248 tprintf(" [ Subtype %s: ", subtype
);
3249 if (!((*get_content
) (pkt
)))
3250 tprintf("%s%s%s", colorize_start_full(black
, red
),
3251 "Failed to dissect Subtype", colorize_end());
3254 tprintf("%s%s%s", colorize_start_full(black
, red
),
3255 "No SubType Data available", colorize_end());
3260 // pkt_set_dissector(pkt, &ieee802_lay2, ntohs(eth->h_proto));
3263 static void ieee80211_less(struct pkt_buff
*pkt __maybe_unused
)
3265 tprintf("802.11 frame (more on todo)");
3268 struct protocol ieee80211_ops
= {
3270 .print_full
= ieee80211
,
3271 .print_less
= ieee80211_less
,