2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>
4 * Copyright 2012 Daniel Borkmann <daniel@netsniff-ng.org>
5 * Subject to the GPL, version 2.
10 #include <netinet/in.h> /* for ntohs() */
11 #include <asm/byteorder.h>
12 #include <arpa/inet.h> /* for inet_ntop() */
16 #include "dissector_80211.h"
23 /* Note: Fields are encoded in little-endian! */
24 struct ieee80211_frm_ctrl
{
28 #if defined(__LITTLE_ENDIAN_BITFIELD)
29 /* Correct order here ... */
30 __extension__ u16 proto_version
:2,
41 #elif defined(__BIG_ENDIAN_BITFIELD)
42 __extension__ u16 subtype
:4,
54 # error "Adjust your <asm/byteorder.h> defines"
60 /* Management Frame start */
61 /* Note: Fields are encoded in little-endian! */
62 struct ieee80211_mgmt
{
70 struct ieee80211_mgmt_auth
{
74 /* possibly followed by Challenge text */
78 struct ieee80211_mgmt_deauth
{
82 struct ieee80211_mgmt_assoc_req
{
85 /* followed by SSID and Supported rates */
89 struct ieee80211_mgmt_assoc_resp
{
93 /* followed by Supported rates */
97 struct ieee80211_mgmt_reassoc_resp
{
101 /* followed by Supported rates */
105 struct ieee80211_mgmt_reassoc_req
{
109 /* followed by SSID and Supported rates */
113 struct ieee80211_mgmt_disassoc
{
117 struct ieee80211_mgmt_probe_req
{
120 struct ieee80211_mgmt_beacon
{
124 /* followed by some of SSID, Supported rates,
125 * FH Params, DS Params, CF Params, IBSS Params, TIM */
129 struct ieee80211_mgmt_probe_resp
{
133 /* followed by some of SSID, Supported rates,
134 * FH Params, DS Params, CF Params, IBSS Params, TIM */
137 /* Management Frame end */
139 /* Control Frame start */
140 /* Note: Fields are encoded in little-endian! */
141 struct ieee80211_ctrl
{
144 struct ieee80211_ctrl_rts
{
150 struct ieee80211_ctrl_cts
{
155 struct ieee80211_ctrl_ack
{
160 struct ieee80211_ctrl_ps_poll
{
166 struct ieee80211_ctrl_cf_end
{
172 struct ieee80211_ctrl_cf_end_ack
{
177 /* Control Frame end */
179 /* Data Frame start */
180 /* Note: Fields are encoded in little-endian! */
181 struct ieee80211_data
{
187 /* http://www.sss-mag.com/pdf/802_11tut.pdf
188 * http://www.scribd.com/doc/78443651/111/Management-Frames
189 * http://www.wildpackets.com/resources/compendium/wireless_lan/wlan_packets
190 * http://www.rhyshaden.com/wireless.htm
193 struct element_reserved
{
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_ext_supp_rates
{
682 struct element_vend_spec
{
688 static int8_t len_neq_error(u8 len
, u8 intended
)
690 if(intended
!= len
) {
691 tprintf("Length should be %u Bytes", intended
);
698 static int8_t len_lt_error(u8 len
, u8 intended
)
701 tprintf("Length should be greater %u Bytes", intended
);
708 static float data_rates(u8 id
)
710 /* XXX Why not (id / 2.f)? */
718 case 11: return 5.5f
;
719 case 12: return 6.0f
;
720 case 18: return 9.0f
;
721 case 22: return 11.0f
;
722 case 24: return 12.0f
;
723 case 27: return 13.5f
;
724 case 36: return 18.0f
;
725 case 44: return 22.0f
;
726 case 48: return 24.0f
;
727 case 54: return 27.0f
;
728 case 66: return 33.0f
;
729 case 72: return 36.0f
;
730 case 96: return 48.0f
;
731 case 108: return 54.0f
;
744 static int8_t subelements(struct pkt_buff
*pkt
, u8 len
)
750 struct subelement
*sub
;
752 sub
= (struct subelement
*) pkt_pull(pkt
, sizeof(*sub
));
756 tprintf(", Subelement ID %u, ", sub
->id
);
757 tprintf("Length %u, ", sub
->len
);
759 data
= pkt_pull(pkt
, sub
->len
);
764 for(j
=0; j
< sub
->len
; j
++)
765 tprintf("%.2x ", data
[j
]);
771 tprintf("Length error");
778 static int8_t inf_reserved(struct pkt_buff
*pkt
, u8
*id
)
782 struct element_reserved
*reserved
;
784 reserved
= (struct element_reserved
*) pkt_pull(pkt
, sizeof(*reserved
));
785 if (reserved
== NULL
)
788 tprintf("Reserved (%u, Len (%u)): ", *id
, reserved
->len
);
790 data
= pkt_pull(pkt
, reserved
->len
);
795 for (i
= 0; i
< reserved
->len
; i
++)
796 tprintf("%.2x", data
[i
]);
801 static int8_t inf_ssid(struct pkt_buff
*pkt
, u8
*id
)
804 struct element_ssid
*ssid
;
807 ssid
= (struct element_ssid
*) pkt_pull(pkt
, sizeof(*ssid
));
811 tprintf(" SSID (%u, Len (%u)): ", *id
, ssid
->len
);
813 if ((ssid
->len
- sizeof(*ssid
) + 1) > 0) {
814 ssid_name
= (char *) pkt_pull(pkt
, ssid
->len
);
815 if (ssid_name
== NULL
)
818 for (i
= 0; i
< ssid
->len
; i
++)
819 tprintf("%c",ssid_name
[i
]);
821 tprintf("Wildcard SSID");
827 static int8_t inf_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
831 struct element_supp_rates
*supp_rates
;
833 supp_rates
= (struct element_supp_rates
*)
834 pkt_pull(pkt
, sizeof(*supp_rates
));
835 if (supp_rates
== NULL
)
838 tprintf("Rates (%u, Len (%u)): ", *id
, supp_rates
->len
);
839 if (len_lt_error(supp_rates
->len
, 1))
842 if ((supp_rates
->len
- sizeof(*supp_rates
) + 1) > 0) {
843 rates
= pkt_pull(pkt
, supp_rates
->len
);
847 for (i
= 0; i
< supp_rates
->len
; i
++)
848 tprintf("%g ", (rates
[i
] & 0x80) ?
849 ((rates
[i
] & 0x3f) * 0.5) :
850 data_rates(rates
[i
]));
857 static int8_t inf_fh_ps(struct pkt_buff
*pkt
, u8
*id
)
859 struct element_fh_ps
*fh_ps
;
861 fh_ps
= (struct element_fh_ps
*) pkt_pull(pkt
, sizeof(*fh_ps
));
865 tprintf("FH Param Set (%u, Len(%u)): ", *id
, fh_ps
->len
);
866 if (len_neq_error(fh_ps
->len
, 5))
868 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps
->dwell_time
) * TU
);
869 tprintf("HopSet: %u, ", fh_ps
->hop_set
);
870 tprintf("HopPattern: %u, ", fh_ps
->hop_pattern
);
871 tprintf("HopIndex: %u", fh_ps
->hop_index
);
876 static int8_t inf_dsss_ps(struct pkt_buff
*pkt
, u8
*id
)
878 struct element_dsss_ps
*dsss_ps
;
880 dsss_ps
= (struct element_dsss_ps
*) pkt_pull(pkt
, sizeof(*dsss_ps
));
884 tprintf("DSSS Param Set (%u, Len(%u)): ", *id
, dsss_ps
->len
);
885 if (len_neq_error(dsss_ps
->len
, 1))
887 tprintf("Current Channel: %u", dsss_ps
->curr_ch
);
892 static int8_t inf_cf_ps(struct pkt_buff
*pkt
, u8
*id
)
894 struct element_cf_ps
*cf_ps
;
896 cf_ps
= (struct element_cf_ps
*) pkt_pull(pkt
, sizeof(*cf_ps
));
900 tprintf("CF Param Set (%u, Len(%u)): ", *id
, cf_ps
->len
);
901 if (len_neq_error(cf_ps
->len
, 6))
903 tprintf("CFP Count: %u, ", cf_ps
->cfp_cnt
);
904 tprintf("CFP Period: %u, ", cf_ps
->cfp_period
);
905 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps
->cfp_max_dur
) * TU
);
906 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps
->cfp_dur_rem
) * TU
);
911 static int8_t inf_tim(struct pkt_buff
*pkt
, u8
*id
)
913 struct element_tim
*tim
;
915 tim
= (struct element_tim
*) pkt_pull(pkt
, sizeof(*tim
));
919 tprintf("TIM (%u, Len(%u)): ", *id
, tim
->len
);
920 if (len_lt_error(tim
->len
, 3))
922 tprintf("DTIM Count: %u, ", tim
->dtim_cnt
);
923 tprintf("DTIM Period: %u, ", tim
->dtim_period
);
924 tprintf("Bitmap Control: %u, ", tim
->bmp_cntrl
);
925 if ((tim
->len
- sizeof(*tim
) + 1) > 0) {
926 u8
*bmp
= pkt_pull(pkt
, (tim
->len
- sizeof(*tim
) + 1));
930 tprintf("Partial Virtual Bitmap: 0x");
931 for(u8 i
=0; i
< (tim
->len
- sizeof(*tim
) + 1); i
++)
932 tprintf("%.2x ", bmp
[i
]);
938 static int8_t inf_ibss_ps(struct pkt_buff
*pkt
, u8
*id
)
940 struct element_ibss_ps
*ibss_ps
;
942 ibss_ps
= (struct element_ibss_ps
*) pkt_pull(pkt
, sizeof(*ibss_ps
));
946 tprintf("IBSS Param Set (%u, Len(%u)): ", *id
, ibss_ps
->len
);
947 if (len_neq_error(ibss_ps
->len
, 2))
949 tprintf("ATIM Window: %fs", le16_to_cpu(ibss_ps
->atim_win
) * TU
);
954 static int8_t inf_country(struct pkt_buff
*pkt
, u8
*id
)
958 struct element_country
*country
;
960 country
= (struct element_country
*) pkt_pull(pkt
, sizeof(*country
));
964 tprintf("Country (%u, Len(%u)): ", *id
, country
->len
);
965 if (len_lt_error(country
->len
, 6))
967 tprintf("Country String: %c%c%c", country
->country_first
,
968 country
->country_sec
, country
->country_third
);
970 for (i
= 0; i
< (country
->len
- 3); i
+= 3) {
971 struct element_country_tripled
*country_tripled
;
973 country_tripled
= (struct element_country_tripled
*)
974 pkt_pull(pkt
, sizeof(*country_tripled
));
975 if (country_tripled
== NULL
)
978 if(country_tripled
->frst_ch
>= 201) {
979 tprintf("Oper Ext ID: %u, ", country_tripled
->frst_ch
);
980 tprintf("Operating Class: %u, ", country_tripled
->nr_ch
);
981 tprintf("Coverage Class: %u", country_tripled
->max_trans
);
983 tprintf("First Ch Nr: %u, ", country_tripled
->frst_ch
);
984 tprintf("Nr of Ch: %u, ", country_tripled
->nr_ch
);
985 tprintf("Max Transmit Pwr Lvl: %u", country_tripled
->max_trans
);
989 if(country
->len
% 2) {
990 pad
= pkt_pull(pkt
, 1);
994 tprintf(", Pad: 0x%x", *pad
);
1000 static int8_t inf_hop_pp(struct pkt_buff
*pkt
, u8
*id
)
1002 struct element_hop_pp
*hop_pp
;
1004 hop_pp
= (struct element_hop_pp
*) pkt_pull(pkt
, sizeof(*hop_pp
));
1008 tprintf("Hopping Pattern Param (%u, Len(%u)): ", *id
, hop_pp
->len
);
1009 if (len_neq_error(hop_pp
->len
, 2))
1011 tprintf("Nr of Ch: %u", hop_pp
->nr_ch
);
1016 static int8_t inf_hop_pt(struct pkt_buff
*pkt
, u8
*id
)
1020 struct element_hop_pt
*hop_pt
;
1022 hop_pt
= (struct element_hop_pt
*) pkt_pull(pkt
, sizeof(*hop_pt
));
1026 tprintf("Hopping Pattern Table (%u, Len(%u)): ", *id
, hop_pt
->len
);
1027 if (len_lt_error(hop_pt
->len
, 4))
1029 tprintf("Flag: %u, ", hop_pt
->flag
);
1030 tprintf("Nr of Sets: %u, ", hop_pt
->nr_sets
);
1031 tprintf("Modules: %u, ", hop_pt
->modules
);
1032 tprintf("Offs: %u", hop_pt
->offs
);
1034 if ((hop_pt
->len
- sizeof(*hop_pt
) + 1) > 0) {
1035 rand_tabl
= pkt_pull(pkt
, (hop_pt
->len
- sizeof(*hop_pt
) + 1));
1036 if (rand_tabl
== NULL
)
1039 tprintf(", Rand table: 0x");
1040 for (i
= 0; i
< (hop_pt
->len
- sizeof(*hop_pt
) + 1); i
++)
1041 tprintf("%.2x ", rand_tabl
[i
]);
1047 static int8_t inf_req(struct pkt_buff
*pkt
, u8
*id
)
1050 struct element_req
*req
;
1053 req
= (struct element_req
*) pkt_pull(pkt
, sizeof(*req
));
1057 tprintf("Request Element (%u, Len(%u)): ", *id
, req
->len
);
1058 if ((req
->len
- sizeof(*req
) + 1) > 0) {
1059 req_ids
= pkt_pull(pkt
, (req
->len
- sizeof(*req
) + 1));
1060 if (req_ids
== NULL
)
1063 tprintf(", Requested Element IDs: ");
1064 for (i
= 0; i
< (req
->len
- sizeof(*req
) + 1); i
++)
1065 tprintf("%u ", req_ids
[i
]);
1071 static int8_t inf_bss_load(struct pkt_buff
*pkt
, u8
*id
)
1073 struct element_bss_load
*bss_load
;
1075 bss_load
= (struct element_bss_load
*) pkt_pull(pkt
, sizeof(*bss_load
));
1076 if (bss_load
== NULL
)
1079 tprintf("BSS Load element (%u, Len(%u)): ", *id
, bss_load
->len
);
1080 if (len_neq_error(bss_load
->len
, 5))
1082 tprintf("Station Count: %u, ", le16_to_cpu(bss_load
->station_cnt
));
1083 tprintf("Channel Utilization: %u, ", bss_load
->ch_util
);
1084 tprintf("Available Admission Capacity: %uus",
1085 bss_load
->avlb_adm_cap
* 32);
1090 static int8_t inf_edca_ps(struct pkt_buff
*pkt
, u8
*id
)
1092 u32 ac_be
, ac_bk
, ac_vi
, ac_vo
;
1093 struct element_edca_ps
*edca_ps
;
1095 edca_ps
= (struct element_edca_ps
*) pkt_pull(pkt
, sizeof(*edca_ps
));
1096 if (edca_ps
== NULL
)
1099 ac_be
= le32_to_cpu(edca_ps
->ac_be
);
1100 ac_bk
= le32_to_cpu(edca_ps
->ac_bk
);
1101 ac_vi
= le32_to_cpu(edca_ps
->ac_vi
);
1102 ac_vo
= le32_to_cpu(edca_ps
->ac_vo
);
1104 tprintf("EDCA Param Set (%u, Len(%u)): ", *id
, edca_ps
->len
);
1105 if (len_neq_error(edca_ps
->len
, 18))
1107 tprintf("QoS Info: 0x%x (-> EDCA Param Set Update Count (%u),"
1108 "Q-Ack (%u), Queue Re (%u), TXOP Req(%u), Res(%u)), ",
1109 edca_ps
->qos_inf
, edca_ps
->qos_inf
>> 4,
1110 (edca_ps
->qos_inf
>> 3) & 1, (edca_ps
->qos_inf
>> 2) & 1,
1111 (edca_ps
->qos_inf
>> 1) & 1, edca_ps
->qos_inf
& 1);
1112 tprintf("Reserved: 0x%x, ", edca_ps
->res
);
1113 tprintf("AC_BE Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1114 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_be
,
1115 ac_be
>> 28, (ac_be
>> 27) & 1, (ac_be
>> 25) & 3,
1116 (ac_be
>> 24) & 1, (ac_be
>> 20) & 15, (ac_be
>> 16) & 15,
1117 bswap_16(ac_be
& 0xFFFF) * 32);
1118 tprintf("AC_BK Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1119 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_bk
,
1120 ac_bk
>> 28, (ac_bk
>> 27) & 1, (ac_bk
>> 25) & 3,
1121 (ac_bk
>> 24) & 1, (ac_bk
>> 20) & 15, (ac_bk
>> 16) & 15,
1122 bswap_16(ac_bk
& 0xFFFF) * 32);
1123 tprintf("AC_VI Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1124 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_vi
,
1125 ac_vi
>> 28, (ac_vi
>> 27) & 1, (ac_vi
>> 25) & 3,
1126 (ac_vi
>> 24) & 1, (ac_vi
>> 20) & 15, (ac_vi
>> 16) & 15,
1127 bswap_16(ac_vi
& 0xFFFF) * 32);
1128 tprintf("AC_VO Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
1129 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)", ac_vo
,
1130 ac_vo
>> 28, (ac_vo
>> 27) & 1, (ac_vo
>> 25) & 3,
1131 (ac_vo
>> 24) & 1, (ac_vo
>> 20) & 15, (ac_vo
>> 16) & 15,
1132 bswap_16(ac_vo
& 0xFFFF) * 32);
1137 static int8_t inf_tspec(struct pkt_buff
*pkt
, u8
*id
)
1139 u16 nom_msdu_size
, surplus_bandw_allow
;
1140 struct element_tspec
*tspec
;
1142 tspec
= (struct element_tspec
*) pkt_pull(pkt
, sizeof(*tspec
));
1146 nom_msdu_size
= le16_to_cpu(tspec
->nom_msdu_size
);
1147 surplus_bandw_allow
= le16_to_cpu(tspec
->surplus_bandw_allow
);
1149 tprintf("TSPEC (%u, Len(%u)): ", *id
, tspec
->len
);
1150 if (len_neq_error(tspec
->len
, 55))
1152 tprintf("Traffic Type: %u, ", tspec
->traffic_type
);
1153 tprintf("TSID: %u, ", tspec
->tsid
);
1154 tprintf("Direction: %u, ", tspec
->direction
);
1155 tprintf("Access Policy: %u, ", tspec
->access_policy
);
1156 tprintf("Aggregation: %u, ", tspec
->aggr
);
1157 tprintf("User Priority: %u, ", tspec
->user_prior
);
1158 tprintf("TSinfo Ack Policy: %u, ", tspec
->tsinfo_ack_pol
);
1159 tprintf("Schedule: %u, ", tspec
->schedule
);
1160 tprintf("Reserved: 0x%x, ", tspec
->res
);
1161 tprintf("Nominal MSDU Size: %uB (Fixed (%u)), ",
1162 nom_msdu_size
>> 1, nom_msdu_size
& 1);
1163 tprintf("Maximum MSDU Size: %uB, ", le16_to_cpu(tspec
->max_msdu_size
));
1164 tprintf("Minimum Service Interval: %uus, ",
1165 le32_to_cpu(tspec
->min_srv_intv
));
1166 tprintf("Maximum Service Interval: %uus, ",
1167 le32_to_cpu(tspec
->max_srv_intv
));
1168 tprintf("Inactivity Interval: %uus, ",
1169 le32_to_cpu(tspec
->inactive_intv
));
1170 tprintf("Suspension Interval: %uus, ", le32_to_cpu(tspec
->susp_intv
));
1171 tprintf("Service Start Time: %uus, ",
1172 le32_to_cpu(tspec
->srv_start_time
));
1173 tprintf("Minimum Data Rate: %ub/s, ",le32_to_cpu(tspec
->min_data_rate
));
1174 tprintf("Mean Data Rate: %ub/s, ", le32_to_cpu(tspec
->mean_data_rate
));
1175 tprintf("Peak Data Rate: %ub/s, ",le32_to_cpu(tspec
->peak_data_rate
));
1176 tprintf("Burst Size: %uB, ", le32_to_cpu(tspec
->burst_size
));
1177 tprintf("Delay Bound: %uus, ", le32_to_cpu(tspec
->delay_bound
));
1178 tprintf("Minimum PHY Rate: %ub/s, ", le32_to_cpu(tspec
->min_phy_rate
));
1179 tprintf("Surplus Bandwidth: %u.%u, ", surplus_bandw_allow
>> 13,
1180 surplus_bandw_allow
& 0x1FFF);
1181 tprintf("Medium Time: %uus", le16_to_cpu(tspec
->med_time
) * 32);
1186 static const char *class_type(u8 type
)
1189 case 0: return "Ethernet parameters";
1190 case 1: return "TCP/UDP IP parameters";
1191 case 2: return "IEEE 802.1Q parameters";
1192 case 3: return "Filter Offset parameters";
1193 case 4: return "IP and higher layer parameters";
1194 case 5: return "IEEE 802.1D/Q parameters";
1195 default: return "Reserved";
1199 static int8_t inf_tclas(struct pkt_buff
*pkt
, u8
*id
)
1201 struct element_tclas
*tclas
;
1202 struct element_tclas_frm_class
*frm_class
;
1204 tclas
= (struct element_tclas
*) pkt_pull(pkt
, sizeof(*tclas
));
1208 frm_class
= (struct element_tclas_frm_class
*)
1209 pkt_pull(pkt
, sizeof(*frm_class
));
1210 if (frm_class
== NULL
)
1213 tprintf("TCLAS (%u, Len(%u)): ", *id
, tclas
->len
);
1214 if (len_lt_error(tclas
->len
, 3))
1216 tprintf("User Priority: %u, ", tclas
->user_priority
);
1217 tprintf("Classifier Type: %s (%u), ", class_type(frm_class
->type
),
1219 tprintf("Classifier Mask: 0x%x, ", frm_class
->mask
);
1221 if(frm_class
->type
== 0) {
1222 struct element_tclas_type0
*type0
;
1224 type0
= (struct element_tclas_type0
*)
1225 pkt_pull(pkt
, sizeof(*type0
));
1229 /* I think little endian, like the rest */
1230 tprintf("Src Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1231 type0
->sa
[5], type0
->sa
[4], type0
->sa
[3],
1232 type0
->sa
[2], type0
->sa
[1], type0
->sa
[0]);
1233 tprintf("Dst Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1234 type0
->da
[5], type0
->da
[4], type0
->da
[3],
1235 type0
->da
[2], type0
->da
[1], type0
->da
[0]);
1236 tprintf("Type: 0x%x", le16_to_cpu(type0
->type
));
1238 else if(frm_class
->type
== 1) {
1239 struct element_tclas_type1
*type1
;
1241 type1
= (struct element_tclas_type1
*)
1242 pkt_pull(pkt
, sizeof(*type1
));
1246 tprintf("Version: %u, ", type1
->version
);
1247 /* big endian format follows */
1248 if(type1
->version
== 4) {
1249 struct element_tclas_type1_ip4
*type1_ip4
;
1250 char src_ip
[INET_ADDRSTRLEN
];
1251 char dst_ip
[INET_ADDRSTRLEN
];
1253 type1_ip4
= (struct element_tclas_type1_ip4
*)
1254 pkt_pull(pkt
, sizeof(*type1_ip4
));
1255 if (type1_ip4
== NULL
)
1258 inet_ntop(AF_INET
, &type1_ip4
->sa
, src_ip
, sizeof(src_ip
));
1259 inet_ntop(AF_INET
, &type1_ip4
->da
, dst_ip
, sizeof(dst_ip
));
1261 tprintf("Src IP: %s, ", src_ip
);
1262 tprintf("Dst IP: %s, ", dst_ip
);
1263 tprintf("Src Port: %u, ", ntohs(type1_ip4
->sp
));
1264 tprintf("Dst Port: %u, ", ntohs(type1_ip4
->dp
));
1265 tprintf("DSCP: 0x%x, ", type1_ip4
->dscp
);
1266 tprintf("Proto: %u, ", type1_ip4
->proto
);
1267 tprintf("Res: 0x%x", type1_ip4
->reserved
);
1269 else if(type1
->version
== 6) {
1270 struct element_tclas_type1_ip6
*type1_ip6
;
1271 char src_ip
[INET6_ADDRSTRLEN
];
1272 char dst_ip
[INET6_ADDRSTRLEN
];
1274 type1_ip6
= (struct element_tclas_type1_ip6
*)
1275 pkt_pull(pkt
, sizeof(*type1_ip6
));
1276 if (type1_ip6
== NULL
)
1279 inet_ntop(AF_INET6
, &type1_ip6
->sa
,
1280 src_ip
, sizeof(src_ip
));
1281 inet_ntop(AF_INET6
, &type1_ip6
->da
,
1282 dst_ip
, sizeof(dst_ip
));
1284 tprintf("Src IP: %s, ", src_ip
);
1285 tprintf("Dst IP: %s, ", dst_ip
);
1286 tprintf("Src Port: %u, ", ntohs(type1_ip6
->sp
));
1287 tprintf("Dst Port: %u, ", ntohs(type1_ip6
->dp
));
1288 tprintf("Flow Label: 0x%x%x%x", type1_ip6
->flow_label1
,
1289 type1_ip6
->flow_label2
, type1_ip6
->flow_label3
);
1292 tprintf("Version (%u) not supported", type1
->version
);
1297 else if(frm_class
->type
== 2) {
1298 struct element_tclas_type2
*type2
;
1300 type2
= (struct element_tclas_type2
*)
1301 pkt_pull(pkt
, sizeof(*type2
));
1305 tprintf("802.1Q VLAN TCI: 0x%x", ntohs(type2
->vlan_tci
));
1307 else if(frm_class
->type
== 3) {
1308 struct element_tclas_type3
*type3
;
1312 type3
= (struct element_tclas_type3
*)
1313 pkt_pull(pkt
, sizeof(*type3
));
1317 len
= (tclas
->len
- 5) / 2;
1319 tprintf("Filter Offset: %u, ", type3
->offs
);
1321 if((len
& 1) || (len_lt_error(tclas
->len
, 5))) {
1322 tprintf("Length of TCLAS (%u) not correct", tclas
->len
);
1326 val
= pkt_pull(pkt
, len
);
1330 tprintf("Filter Value: 0x");
1331 for (i
= 0; i
< len
/ 2; i
++)
1332 tprintf("%x ", val
[i
]);
1334 tprintf("Filter Mask: 0x");
1335 for (i
= len
/ 2; i
< len
; i
++)
1336 tprintf("%x ", val
[i
]);
1340 else if(frm_class
->type
== 4) {
1341 struct element_tclas_type4
*type4
;
1343 type4
= (struct element_tclas_type4
*)
1344 pkt_pull(pkt
, sizeof(*type4
));
1348 tprintf("Version: %u, ", type4
->version
);
1349 /* big endian format follows */
1350 if(type4
->version
== 4) {
1351 struct element_tclas_type4_ip4
*type4_ip4
;
1352 char src_ip
[INET_ADDRSTRLEN
];
1353 char dst_ip
[INET_ADDRSTRLEN
];
1355 type4_ip4
= (struct element_tclas_type4_ip4
*)
1356 pkt_pull(pkt
, sizeof(*type4_ip4
));
1357 if (type4_ip4
== NULL
)
1360 inet_ntop(AF_INET
, &type4_ip4
->sa
, src_ip
, sizeof(src_ip
));
1361 inet_ntop(AF_INET
, &type4_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(type4_ip4
->sp
));
1366 tprintf("Dst Port: %u, ", ntohs(type4_ip4
->dp
));
1367 tprintf("DSCP: 0x%x, ", type4_ip4
->dscp
);
1368 tprintf("Proto: %u, ", type4_ip4
->proto
);
1369 tprintf("Res: 0x%x", type4_ip4
->reserved
);
1371 else if(type4
->version
== 6) {
1372 struct element_tclas_type4_ip6
*type4_ip6
;
1373 char src_ip
[INET6_ADDRSTRLEN
];
1374 char dst_ip
[INET6_ADDRSTRLEN
];
1376 type4_ip6
= (struct element_tclas_type4_ip6
*)
1377 pkt_pull(pkt
, sizeof(*type4_ip6
));
1378 if (type4_ip6
== NULL
)
1381 inet_ntop(AF_INET6
, &type4_ip6
->sa
,
1382 src_ip
, sizeof(src_ip
));
1383 inet_ntop(AF_INET6
, &type4_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(type4_ip6
->sp
));
1389 tprintf("Dst Port: %u, ", ntohs(type4_ip6
->dp
));
1390 tprintf("DSCP: 0x%x, ", type4_ip6
->dscp
);
1391 tprintf("Nxt Hdr: %u, ", type4_ip6
->nxt_hdr
);
1392 tprintf("Flow Label: 0x%x%x%x", type4_ip6
->flow_label1
,
1393 type4_ip6
->flow_label2
, type4_ip6
->flow_label3
);
1396 tprintf("Version (%u) not supported", type4
->version
);
1400 else if(frm_class
->type
== 5) {
1401 struct element_tclas_type5
*type5
;
1403 type5
= (struct element_tclas_type5
*)
1404 pkt_pull(pkt
, sizeof(*type5
));
1408 tprintf("802.1Q PCP: 0x%x, ", type5
->pcp
);
1409 tprintf("802.1Q CFI: 0x%x, ", type5
->cfi
);
1410 tprintf("802.1Q VID: 0x%x", type5
->vid
);
1413 tprintf("Classifier Type (%u) not supported", frm_class
->type
);
1420 static int8_t inf_sched(struct pkt_buff
*pkt
, u8
*id
)
1422 struct element_schedule
*schedule
;
1425 schedule
= (struct element_schedule
*) pkt_pull(pkt
, sizeof(*schedule
));
1426 if (schedule
== NULL
)
1429 info
= le16_to_cpu(schedule
->inf
);
1431 tprintf("Schedule (%u, Len(%u)): ", *id
, schedule
->len
);
1432 if (len_neq_error(schedule
->len
, 12))
1435 tprintf("Aggregation: %u, ", info
>> 15);
1436 tprintf("TSID: %u, ", (info
>> 11) & 0xF);
1437 tprintf("Direction: %u, ", (info
>> 9) & 0x3);
1438 tprintf("Res: %u, ", info
& 0x1FF);
1439 tprintf("Serv Start Time: %uus, ", le32_to_cpu(schedule
->start
));
1440 tprintf("Serv Interval: %uus, ", le32_to_cpu(schedule
->serv_intv
));
1441 tprintf("Spec Interval: %fs", le32_to_cpu(schedule
->spec_intv
) * TU
);
1446 static int8_t inf_chall_txt(struct pkt_buff
*pkt
, u8
*id
)
1448 struct element_chall_txt
*chall_txt
;
1452 chall_txt
= (struct element_chall_txt
*)
1453 pkt_pull(pkt
, sizeof(*chall_txt
));
1454 if (chall_txt
== NULL
)
1457 tprintf("Challenge Text (%u, Len(%u)): ", *id
, chall_txt
->len
);
1458 if ((chall_txt
->len
- sizeof(*chall_txt
) + 1) > 0) {
1459 txt
= pkt_pull(pkt
, (chall_txt
->len
- sizeof(*chall_txt
) + 1));
1464 for (i
= 0; i
< (chall_txt
->len
- sizeof(*chall_txt
) + 1); i
++)
1465 tprintf("%x ", txt
[i
]);
1471 static int8_t inf_pwr_constr(struct pkt_buff
*pkt
, u8
*id
)
1473 struct element_pwr_constr
*pwr_constr
;
1475 pwr_constr
= (struct element_pwr_constr
*) pkt_pull(pkt
, sizeof(*pwr_constr
));
1476 if (pwr_constr
== NULL
)
1479 tprintf("Power Constraint (%u, Len(%u)): ", *id
, pwr_constr
->len
);
1480 if (len_neq_error(pwr_constr
->len
, 1))
1483 tprintf("Local Power Constraint: %udB", pwr_constr
->local_pwr_constr
);
1488 static int8_t inf_pwr_cap(struct pkt_buff
*pkt
, u8
*id
)
1490 struct element_pwr_cap
*pwr_cap
;
1492 pwr_cap
= (struct element_pwr_cap
*) pkt_pull(pkt
, sizeof(*pwr_cap
));
1493 if (pwr_cap
== NULL
)
1496 tprintf("Power Capability (%u, Len(%u)): ", *id
, pwr_cap
->len
);
1497 if (len_neq_error(pwr_cap
->len
, 2))
1500 tprintf("Min. Transm. Pwr Cap.: %ddBm, ", (int8_t)pwr_cap
->min_pwr_cap
);
1501 tprintf("Max. Transm. Pwr Cap.: %ddBm", (int8_t)pwr_cap
->max_pwr_cap
);
1506 static int8_t inf_tpc_req(struct pkt_buff
*pkt
, u8
*id
)
1508 struct element_tpc_req
*tpc_req
;
1510 tpc_req
= (struct element_tpc_req
*) pkt_pull(pkt
, sizeof(*tpc_req
));
1511 if (tpc_req
== NULL
)
1514 tprintf("TPC Request (%u, Len(%u))", *id
, tpc_req
->len
);
1515 if (len_neq_error(tpc_req
->len
, 0))
1521 static int8_t inf_tpc_rep(struct pkt_buff
*pkt
, u8
*id
)
1523 struct element_tpc_rep
*tpc_rep
;
1525 tpc_rep
= (struct element_tpc_rep
*) pkt_pull(pkt
, sizeof(*tpc_rep
));
1526 if (tpc_rep
== NULL
)
1529 tprintf("TPC Report (%u, Len(%u)): ", *id
, tpc_rep
->len
);
1530 if (len_neq_error(tpc_rep
->len
, 2))
1533 tprintf("Transmit Power: %udBm, ", (int8_t)tpc_rep
->trans_pwr
);
1534 tprintf("Link Margin: %udB", (int8_t)tpc_rep
->trans_pwr
);
1539 static int8_t inf_supp_ch(struct pkt_buff
*pkt
, u8
*id
)
1541 struct element_supp_ch
*supp_ch
;
1544 supp_ch
= (struct element_supp_ch
*) pkt_pull(pkt
, sizeof(*supp_ch
));
1545 if (supp_ch
== NULL
)
1548 tprintf("Supp Channels (%u, Len(%u)): ", *id
, supp_ch
->len
);
1549 if (len_lt_error(supp_ch
->len
, 2))
1552 if(supp_ch
->len
& 1) {
1553 tprintf("Length should be modulo 2");
1557 for (i
= 0; i
< supp_ch
->len
; i
+= 2) {
1558 struct element_supp_ch_tuple
*supp_ch_tuple
;
1560 supp_ch_tuple
= (struct element_supp_ch_tuple
*)
1561 pkt_pull(pkt
, sizeof(*supp_ch_tuple
));
1562 if (supp_ch_tuple
== NULL
)
1565 tprintf("First Channel Nr: %u, ", supp_ch_tuple
->first_ch_nr
);
1566 tprintf("Nr of Channels: %u, ", supp_ch_tuple
->nr_ch
);
1572 static int8_t inf_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
)
1574 struct element_ch_sw_ann
*ch_sw_ann
;
1576 ch_sw_ann
= (struct element_ch_sw_ann
*)
1577 pkt_pull(pkt
, sizeof(*ch_sw_ann
));
1578 if (ch_sw_ann
== NULL
)
1581 tprintf("Channel Switch Announc (%u, Len(%u)): ", *id
, ch_sw_ann
->len
);
1582 if (len_neq_error(ch_sw_ann
->len
, 3))
1585 tprintf("Switch Mode: %u, ", ch_sw_ann
->switch_mode
);
1586 tprintf("New Nr: %u, ", ch_sw_ann
->new_nr
);
1587 tprintf("Switch Count: %u", ch_sw_ann
->switch_cnt
);
1592 static const char *meas_type(u8 type
)
1595 case 0: return "Basic";
1596 case 1: return "Clear Channel assesment (CCA)";
1597 case 2: return "Receive power indication (RPI) histogram";
1598 case 3: return "Channel load";
1599 case 4: return "Noise histogram";
1600 case 5: return "Beacon";
1601 case 6: return "Frame";
1602 case 7: return "STA statistics";
1603 case 8: return "LCI";
1604 case 9: return "Transmit stream/category measurement";
1605 case 10: return "Multicast diagnostics";
1606 case 11: return "Location Civic";
1607 case 12: return "Location Identifier";
1608 case 13 ... 255: return "Reserved";
1612 static int8_t inf_meas_req(struct pkt_buff
*pkt
, u8
*id
)
1614 struct element_meas_req
*meas_req
;
1616 meas_req
= (struct element_meas_req
*) pkt_pull(pkt
, sizeof(*meas_req
));
1617 if (meas_req
== NULL
)
1620 tprintf("Measurement Req (%u, Len(%u)): ", *id
, meas_req
->len
);
1621 if (len_lt_error(meas_req
->len
, 3))
1624 tprintf("Token: %u, ", meas_req
->token
);
1625 tprintf("Req Mode: 0x%x (Parallel (%u), Enable(%u), Request(%u), "
1626 "Report(%u), Dur Mand(%u)), ", meas_req
->req_mode
,
1627 meas_req
->req_mode
>> 7, (meas_req
->req_mode
>> 6) & 0x1,
1628 (meas_req
->req_mode
>> 5) & 0x1, (meas_req
->req_mode
>> 4) & 0x1,
1629 (meas_req
->req_mode
>> 3) & 0x1);
1630 tprintf("Type: %s (%u), ", meas_type(meas_req
->type
), meas_req
->type
);
1632 if(meas_req
->len
> 3) {
1633 if(meas_req
->type
== 0) {
1634 struct element_meas_basic
*basic
;
1636 basic
= (struct element_meas_basic
*)
1637 pkt_pull(pkt
, sizeof(*basic
));
1641 if (!(meas_req
->len
- 3 - sizeof(*basic
))) {
1642 tprintf("Length of Req matchs not Type %u",
1647 tprintf("Ch Nr: %uus, ", basic
->ch_nr
);
1648 tprintf("Meas Start Time: %lu, ",
1649 le64_to_cpu(basic
->start
));
1650 tprintf("Meas Duration: %fs",
1651 le16_to_cpu(basic
->dur
) * TU
);
1654 else if(meas_req
->type
== 1) {
1655 struct element_meas_cca
*cca
;
1657 cca
= (struct element_meas_cca
*)
1658 pkt_pull(pkt
, sizeof(*cca
));
1662 if (!(meas_req
->len
- 3 - sizeof(*cca
))) {
1663 tprintf("Length of Req matchs not Type %u",
1668 tprintf("Ch Nr: %uus, ", cca
->ch_nr
);
1669 tprintf("Meas Start Time: %lu, ",
1670 le64_to_cpu(cca
->start
));
1671 tprintf("Meas Duration: %fs",
1672 le16_to_cpu(cca
->dur
) * TU
);
1674 else if(meas_req
->type
== 2) {
1675 struct element_meas_rpi
*rpi
;
1677 rpi
= (struct element_meas_rpi
*)
1678 pkt_pull(pkt
, sizeof(*rpi
));
1682 if (!(meas_req
->len
- 3 - sizeof(*rpi
))) {
1683 tprintf("Length of Req matchs not Type %u",
1688 tprintf("Ch Nr: %uus, ", rpi
->ch_nr
);
1689 tprintf("Meas Start Time: %lu, ",
1690 le64_to_cpu(rpi
->start
));
1691 tprintf("Meas Duration: %fs",
1692 le16_to_cpu(rpi
->dur
) * TU
);
1694 else if(meas_req
->type
== 3) {
1695 struct element_meas_ch_load
*ch_load
;
1697 ch_load
= (struct element_meas_ch_load
*)
1698 pkt_pull(pkt
, sizeof(*ch_load
));
1699 if (ch_load
== NULL
)
1702 if ((meas_req
->len
- 3 - sizeof(*ch_load
)) >= 0) {
1703 tprintf("Length of Req matchs not Type %u",
1708 tprintf("OP Class: %u, ", ch_load
->op_class
);
1709 tprintf("Ch Nr: %u, ", ch_load
->ch_nr
);
1710 tprintf("Rand Intv: %fs, ",
1711 le16_to_cpu(ch_load
->rand_intv
) * TU
);
1712 tprintf("Meas Duration: %fs",
1713 le16_to_cpu(ch_load
->dur
) * TU
);
1715 if(!subelements(pkt
,
1716 meas_req
->len
- 3 - sizeof(*ch_load
)))
1719 else if(meas_req
->type
== 4) {
1720 struct element_meas_noise
*noise
;
1722 noise
= (struct element_meas_noise
*)
1723 pkt_pull(pkt
, sizeof(*noise
));
1727 if ((meas_req
->len
- 3 - sizeof(*noise
)) >= 0) {
1728 tprintf("Length of Req matchs not Type %u",
1733 tprintf("OP Class: %u, ", noise
->op_class
);
1734 tprintf("Ch Nr: %u, ", noise
->ch_nr
);
1735 tprintf("Rand Intv: %fs, ",
1736 le16_to_cpu(noise
->rand_intv
) * TU
);
1737 tprintf("Meas Duration: %fs",
1738 le16_to_cpu(noise
->dur
) * TU
);
1740 if(!subelements(pkt
,
1741 meas_req
->len
- 3 - sizeof(*noise
)))
1744 else if(meas_req
->type
== 5) {
1745 struct element_meas_beacon
*beacon
;
1747 beacon
= (struct element_meas_beacon
*)
1748 pkt_pull(pkt
, sizeof(*beacon
));
1752 if ((meas_req
->len
- 3 - sizeof(*beacon
)) >= 0) {
1753 tprintf("Length of Req matchs not Type %u",
1758 tprintf("OP Class: %u, ", beacon
->op_class
);
1759 tprintf("Ch Nr: %u, ", beacon
->ch_nr
);
1760 tprintf("Rand Intv: %fs, ",
1761 le16_to_cpu(beacon
->rand_intv
) * TU
);
1762 tprintf("Meas Duration: %fs",
1763 le16_to_cpu(beacon
->dur
) * TU
);
1764 tprintf("Mode: %u, ", beacon
->mode
);
1765 tprintf("BSSID: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1766 beacon
->bssid
[0], beacon
->bssid
[1],
1767 beacon
->bssid
[2], beacon
->bssid
[3],
1768 beacon
->bssid
[4], beacon
->bssid
[5]);
1770 if(!subelements(pkt
,
1771 meas_req
->len
- 3 - sizeof(*beacon
)))
1774 else if(meas_req
->type
== 6) {
1775 struct element_meas_frame
*frame
;
1777 frame
= (struct element_meas_frame
*)
1778 pkt_pull(pkt
, sizeof(*frame
));
1782 if ((meas_req
->len
- 3 - sizeof(*frame
)) >= 0) {
1783 tprintf("Length of Req matchs not Type %u",
1788 tprintf("OP Class: %u, ", frame
->op_class
);
1789 tprintf("Ch Nr: %u, ", frame
->ch_nr
);
1790 tprintf("Rand Intv: %fs, ",
1791 le16_to_cpu(frame
->rand_intv
) * TU
);
1792 tprintf("Meas Duration: %fs",
1793 le16_to_cpu(frame
->dur
) * TU
);
1794 tprintf("Request Type: %u, ", frame
->frame
);
1795 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1796 frame
->mac
[0], frame
->mac
[1],
1797 frame
->mac
[2], frame
->mac
[3],
1798 frame
->mac
[4], frame
->mac
[5]);
1800 if(!subelements(pkt
,
1801 meas_req
->len
- 3 - sizeof(*frame
)))
1804 else if(meas_req
->type
== 7) {
1805 struct element_meas_sta
*sta
;
1807 sta
= (struct element_meas_sta
*)
1808 pkt_pull(pkt
, sizeof(*sta
));
1812 if ((meas_req
->len
- 3 - sizeof(*sta
)) >= 0) {
1813 tprintf("Length of Req matchs not Type %u",
1818 tprintf("Peer MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1819 sta
->peer_mac
[0], sta
->peer_mac
[1],
1820 sta
->peer_mac
[2], sta
->peer_mac
[3],
1821 sta
->peer_mac
[4], sta
->peer_mac
[5]);
1822 tprintf("Rand Intv: %fs, ",
1823 le16_to_cpu(sta
->rand_intv
) * TU
);
1824 tprintf("Meas Duration: %fs",
1825 le16_to_cpu(sta
->dur
) * TU
);
1826 tprintf("Group ID: %u, ", sta
->group_id
);
1828 if(!subelements(pkt
,
1829 meas_req
->len
- 3 - sizeof(*sta
)))
1832 else if(meas_req
->type
== 8) {
1833 struct element_meas_lci
*lci
;
1835 lci
= (struct element_meas_lci
*)
1836 pkt_pull(pkt
, sizeof(*lci
));
1840 if ((meas_req
->len
- 3 - sizeof(*lci
)) >= 0) {
1841 tprintf("Length of Req matchs not Type %u",
1846 tprintf("Location Subj: %u, ", lci
->loc_subj
);
1847 tprintf("Latitude Req Res: %udeg",
1848 lci
->latitude_req_res
);
1849 tprintf("Longitude Req Res: %udeg",
1850 lci
->longitude_req_res
);
1851 tprintf("Altitude Req Res: %udeg",
1852 lci
->altitude_req_res
);
1854 if(!subelements(pkt
,
1855 meas_req
->len
- 3 - sizeof(*lci
)))
1858 else if(meas_req
->type
== 9) {
1859 struct element_meas_trans_str_cat
*trans
;
1861 trans
= (struct element_meas_trans_str_cat
*)
1862 pkt_pull(pkt
, sizeof(*trans
));
1866 if ((meas_req
->len
- 3 - sizeof(*trans
)) >= 0) {
1867 tprintf("Length of Req matchs not Type %u",
1872 tprintf("Rand Intv: %fs, ",
1873 le16_to_cpu(trans
->rand_intv
) * TU
);
1874 tprintf("Meas Duration: %fs",
1875 le16_to_cpu(trans
->dur
) * TU
);
1876 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1877 trans
->peer_sta_addr
[0], trans
->peer_sta_addr
[1],
1878 trans
->peer_sta_addr
[2], trans
->peer_sta_addr
[3],
1879 trans
->peer_sta_addr
[4], trans
->peer_sta_addr
[5]);
1880 tprintf("Traffic ID: %u, ", trans
->traffic_id
);
1881 tprintf("Bin 0 Range: %u, ", trans
->bin_0_range
);
1883 if(!subelements(pkt
,
1884 meas_req
->len
- 3 - sizeof(*trans
)))
1887 else if(meas_req
->type
== 10) {
1888 struct element_meas_mcast_diag
*mcast
;
1890 mcast
= (struct element_meas_mcast_diag
*)
1891 pkt_pull(pkt
, sizeof(*mcast
));
1895 if ((meas_req
->len
- 3 - sizeof(*mcast
)) >= 0) {
1896 tprintf("Length of Req matchs not Type %u",
1901 tprintf("Rand Intv: %fs, ",
1902 le16_to_cpu(mcast
->rand_intv
) * TU
);
1903 tprintf("Meas Duration: %fs",
1904 le16_to_cpu(mcast
->dur
) * TU
);
1905 tprintf("Group MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
1906 mcast
->group_mac
[0], mcast
->group_mac
[1],
1907 mcast
->group_mac
[2], mcast
->group_mac
[3],
1908 mcast
->group_mac
[4], mcast
->group_mac
[5]);
1910 if(!subelements(pkt
,
1911 meas_req
->len
- 3 - sizeof(*mcast
)))
1914 else if(meas_req
->type
== 11) {
1915 struct element_meas_loc_civic
*civic
;
1917 civic
= (struct element_meas_loc_civic
*)
1918 pkt_pull(pkt
, sizeof(*civic
));
1922 if ((meas_req
->len
- 3 - sizeof(*civic
)) >= 0) {
1923 tprintf("Length of Req matchs not Type %u",
1928 tprintf("Location Subj: %u, ", civic
->loc_subj
);
1929 tprintf("Type: %u, ", civic
->civic_loc
);
1930 tprintf("Srv Intv Units: %u, ",
1931 le16_to_cpu(civic
->loc_srv_intv_unit
));
1932 tprintf("Srv Intv: %u, ", civic
->loc_srv_intv
);
1934 if(!subelements(pkt
,
1935 meas_req
->len
- 3 - sizeof(*civic
)))
1938 else if(meas_req
->type
== 12) {
1939 struct element_meas_loc_id
*id
;
1941 id
= (struct element_meas_loc_id
*)
1942 pkt_pull(pkt
, sizeof(*id
));
1946 if ((meas_req
->len
- 3 - sizeof(*id
)) >= 0) {
1947 tprintf("Length of Req matchs not Type %u",
1952 tprintf("Location Subj: %u, ", id
->loc_subj
);
1953 tprintf("Srv Intv Units: %u, ",
1954 le16_to_cpu(id
->loc_srv_intv_unit
));
1955 tprintf("Srv Intv: %u", id
->loc_srv_intv
);
1957 if(!subelements(pkt
,
1958 meas_req
->len
- 3 - sizeof(*id
)))
1961 else if(meas_req
->type
== 255) {
1962 struct element_meas_pause
*pause
;
1964 pause
= (struct element_meas_pause
*)
1965 pkt_pull(pkt
, sizeof(*pause
));
1969 if ((meas_req
->len
- 3 - sizeof(*pause
)) >= 0) {
1970 tprintf("Length of Req matchs not Type %u",
1975 tprintf("Pause Time: %fs, ", pause
->time
* 10 * TU
);
1977 if(!subelements(pkt
,
1978 meas_req
->len
- 3 - sizeof(*pause
)))
1982 tprintf("Length field indicates data,"
1983 " but could not interpreted");
1991 static int8_t inf_meas_rep(struct pkt_buff
*pkt
, u8
*id
)
1993 struct element_meas_rep
*meas_rep
;
1995 meas_rep
= (struct element_meas_rep
*) pkt_pull(pkt
, sizeof(*meas_rep
));
1996 if (meas_rep
== NULL
)
1999 tprintf("Measurement Rep (%u, Len(%u)): ", *id
, meas_rep
->len
);
2000 if (len_lt_error(meas_rep
->len
, 3))
2003 tprintf("Token: %u, ", meas_rep
->token
);
2004 tprintf("Rep Mode: 0x%x (Late (%u), Incapable(%u), Refused(%u), ",
2005 meas_rep
->rep_mode
, meas_rep
->rep_mode
>> 7,
2006 (meas_rep
->rep_mode
>> 6) & 0x1,
2007 (meas_rep
->rep_mode
>> 5) & 0x1);
2008 tprintf("Type: %s (%u), ", meas_type(meas_rep
->type
), meas_rep
->type
);
2010 if(meas_rep
->len
> 3) {
2011 if(meas_rep
->type
== 0) {
2012 struct element_meas_basic
*basic
;
2014 basic
= (struct element_meas_basic
*)
2015 pkt_pull(pkt
, sizeof(*basic
));
2019 if (!(meas_rep
->len
- 3 - sizeof(*basic
))) {
2020 tprintf("Length of Req matchs not Type %u",
2025 tprintf("Ch Nr: %uus, ", basic
->ch_nr
);
2026 tprintf("Meas Start Time: %lu, ",
2027 le64_to_cpu(basic
->start
));
2028 tprintf("Meas Duration: %fs",
2029 le16_to_cpu(basic
->dur
) * TU
);
2032 else if(meas_rep
->type
== 1) {
2033 struct element_meas_cca
*cca
;
2035 cca
= (struct element_meas_cca
*)
2036 pkt_pull(pkt
, sizeof(*cca
));
2040 if (!(meas_rep
->len
- 3 - sizeof(*cca
))) {
2041 tprintf("Length of Req matchs not Type %u",
2046 tprintf("Ch Nr: %uus, ", cca
->ch_nr
);
2047 tprintf("Meas Start Time: %lu, ",
2048 le64_to_cpu(cca
->start
));
2049 tprintf("Meas Duration: %fs",
2050 le16_to_cpu(cca
->dur
) * TU
);
2052 else if(meas_rep
->type
== 2) {
2053 struct element_meas_rpi
*rpi
;
2055 rpi
= (struct element_meas_rpi
*)
2056 pkt_pull(pkt
, sizeof(*rpi
));
2060 if (!(meas_rep
->len
- 3 - sizeof(*rpi
))) {
2061 tprintf("Length of Req matchs not Type %u",
2066 tprintf("Ch Nr: %uus, ", rpi
->ch_nr
);
2067 tprintf("Meas Start Time: %lu, ",
2068 le64_to_cpu(rpi
->start
));
2069 tprintf("Meas Duration: %fs",
2070 le16_to_cpu(rpi
->dur
) * TU
);
2072 else if(meas_rep
->type
== 3) {
2073 struct element_meas_ch_load
*ch_load
;
2075 ch_load
= (struct element_meas_ch_load
*)
2076 pkt_pull(pkt
, sizeof(*ch_load
));
2077 if (ch_load
== NULL
)
2080 if ((meas_rep
->len
- 3 - sizeof(*ch_load
)) >= 0) {
2081 tprintf("Length of Req matchs not Type %u",
2086 tprintf("OP Class: %u, ", ch_load
->op_class
);
2087 tprintf("Ch Nr: %u, ", ch_load
->ch_nr
);
2088 tprintf("Rand Intv: %fs, ",
2089 le16_to_cpu(ch_load
->rand_intv
) * TU
);
2090 tprintf("Meas Duration: %fs",
2091 le16_to_cpu(ch_load
->dur
) * TU
);
2093 if(!subelements(pkt
,
2094 meas_rep
->len
- 3 - sizeof(*ch_load
)))
2097 else if(meas_rep
->type
== 4) {
2098 struct element_meas_noise
*noise
;
2100 noise
= (struct element_meas_noise
*)
2101 pkt_pull(pkt
, sizeof(*noise
));
2105 if ((meas_rep
->len
- 3 - sizeof(*noise
)) >= 0) {
2106 tprintf("Length of Req matchs not Type %u",
2111 tprintf("OP Class: %u, ", noise
->op_class
);
2112 tprintf("Ch Nr: %u, ", noise
->ch_nr
);
2113 tprintf("Rand Intv: %fs, ",
2114 le16_to_cpu(noise
->rand_intv
) * TU
);
2115 tprintf("Meas Duration: %fs",
2116 le16_to_cpu(noise
->dur
) * TU
);
2118 if(!subelements(pkt
,
2119 meas_rep
->len
- 3 - sizeof(*noise
)))
2122 else if(meas_rep
->type
== 5) {
2123 struct element_meas_beacon
*beacon
;
2125 beacon
= (struct element_meas_beacon
*)
2126 pkt_pull(pkt
, sizeof(*beacon
));
2130 if ((meas_rep
->len
- 3 - sizeof(*beacon
)) >= 0) {
2131 tprintf("Length of Req matchs not Type %u",
2136 tprintf("OP Class: %u, ", beacon
->op_class
);
2137 tprintf("Ch Nr: %u, ", beacon
->ch_nr
);
2138 tprintf("Rand Intv: %fs, ",
2139 le16_to_cpu(beacon
->rand_intv
) * TU
);
2140 tprintf("Meas Duration: %fs",
2141 le16_to_cpu(beacon
->dur
) * TU
);
2142 tprintf("Mode: %u, ", beacon
->mode
);
2143 tprintf("BSSID: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2144 beacon
->bssid
[0], beacon
->bssid
[1],
2145 beacon
->bssid
[2], beacon
->bssid
[3],
2146 beacon
->bssid
[4], beacon
->bssid
[5]);
2148 if(!subelements(pkt
,
2149 meas_rep
->len
- 3 - sizeof(*beacon
)))
2152 else if(meas_rep
->type
== 6) {
2153 struct element_meas_frame
*frame
;
2155 frame
= (struct element_meas_frame
*)
2156 pkt_pull(pkt
, sizeof(*frame
));
2160 if ((meas_rep
->len
- 3 - sizeof(*frame
)) >= 0) {
2161 tprintf("Length of Req matchs not Type %u",
2166 tprintf("OP Class: %u, ", frame
->op_class
);
2167 tprintf("Ch Nr: %u, ", frame
->ch_nr
);
2168 tprintf("Rand Intv: %fs, ",
2169 le16_to_cpu(frame
->rand_intv
) * TU
);
2170 tprintf("Meas Duration: %fs",
2171 le16_to_cpu(frame
->dur
) * TU
);
2172 tprintf("Request Type: %u, ", frame
->frame
);
2173 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2174 frame
->mac
[0], frame
->mac
[1],
2175 frame
->mac
[2], frame
->mac
[3],
2176 frame
->mac
[4], frame
->mac
[5]);
2178 if(!subelements(pkt
,
2179 meas_rep
->len
- 3 - sizeof(*frame
)))
2182 else if(meas_rep
->type
== 7) {
2183 struct element_meas_sta
*sta
;
2185 sta
= (struct element_meas_sta
*)
2186 pkt_pull(pkt
, sizeof(*sta
));
2190 if ((meas_rep
->len
- 3 - sizeof(*sta
)) >= 0) {
2191 tprintf("Length of Req matchs not Type %u",
2196 tprintf("Peer MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2197 sta
->peer_mac
[0], sta
->peer_mac
[1],
2198 sta
->peer_mac
[2], sta
->peer_mac
[3],
2199 sta
->peer_mac
[4], sta
->peer_mac
[5]);
2200 tprintf("Rand Intv: %fs, ",
2201 le16_to_cpu(sta
->rand_intv
) * TU
);
2202 tprintf("Meas Duration: %fs",
2203 le16_to_cpu(sta
->dur
) * TU
);
2204 tprintf("Group ID: %u, ", sta
->group_id
);
2206 if(!subelements(pkt
,
2207 meas_rep
->len
- 3 - sizeof(*sta
)))
2210 else if(meas_rep
->type
== 8) {
2211 struct element_meas_lci
*lci
;
2213 lci
= (struct element_meas_lci
*)
2214 pkt_pull(pkt
, sizeof(*lci
));
2218 if ((meas_rep
->len
- 3 - sizeof(*lci
)) >= 0) {
2219 tprintf("Length of Req matchs not Type %u",
2224 tprintf("Location Subj: %u, ", lci
->loc_subj
);
2225 tprintf("Latitude Req Res: %udeg",
2226 lci
->latitude_req_res
);
2227 tprintf("Longitude Req Res: %udeg",
2228 lci
->longitude_req_res
);
2229 tprintf("Altitude Req Res: %udeg",
2230 lci
->altitude_req_res
);
2232 if(!subelements(pkt
,
2233 meas_rep
->len
- 3 - sizeof(*lci
)))
2236 else if(meas_rep
->type
== 9) {
2237 struct element_meas_trans_str_cat
*trans
;
2239 trans
= (struct element_meas_trans_str_cat
*)
2240 pkt_pull(pkt
, sizeof(*trans
));
2244 if ((meas_rep
->len
- 3 - sizeof(*trans
)) >= 0) {
2245 tprintf("Length of Req matchs not Type %u",
2250 tprintf("Rand Intv: %fs, ",
2251 le16_to_cpu(trans
->rand_intv
) * TU
);
2252 tprintf("Meas Duration: %fs",
2253 le16_to_cpu(trans
->dur
) * TU
);
2254 tprintf("MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2255 trans
->peer_sta_addr
[0], trans
->peer_sta_addr
[1],
2256 trans
->peer_sta_addr
[2], trans
->peer_sta_addr
[3],
2257 trans
->peer_sta_addr
[4], trans
->peer_sta_addr
[5]);
2258 tprintf("Traffic ID: %u, ", trans
->traffic_id
);
2259 tprintf("Bin 0 Range: %u, ", trans
->bin_0_range
);
2261 if(!subelements(pkt
,
2262 meas_rep
->len
- 3 - sizeof(*trans
)))
2265 else if(meas_rep
->type
== 10) {
2266 struct element_meas_mcast_diag
*mcast
;
2268 mcast
= (struct element_meas_mcast_diag
*)
2269 pkt_pull(pkt
, sizeof(*mcast
));
2273 if ((meas_rep
->len
- 3 - sizeof(*mcast
)) >= 0) {
2274 tprintf("Length of Req matchs not Type %u",
2279 tprintf("Rand Intv: %fs, ",
2280 le16_to_cpu(mcast
->rand_intv
) * TU
);
2281 tprintf("Meas Duration: %fs",
2282 le16_to_cpu(mcast
->dur
) * TU
);
2283 tprintf("Group MAC Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
2284 mcast
->group_mac
[0], mcast
->group_mac
[1],
2285 mcast
->group_mac
[2], mcast
->group_mac
[3],
2286 mcast
->group_mac
[4], mcast
->group_mac
[5]);
2288 if(!subelements(pkt
,
2289 meas_rep
->len
- 3 - sizeof(*mcast
)))
2292 else if(meas_rep
->type
== 11) {
2293 struct element_meas_loc_civic
*civic
;
2295 civic
= (struct element_meas_loc_civic
*)
2296 pkt_pull(pkt
, sizeof(*civic
));
2300 if ((meas_rep
->len
- 3 - sizeof(*civic
)) >= 0) {
2301 tprintf("Length of Req matchs not Type %u",
2306 tprintf("Location Subj: %u, ", civic
->loc_subj
);
2307 tprintf("Type: %u, ", civic
->civic_loc
);
2308 tprintf("Srv Intv Units: %u, ",
2309 le16_to_cpu(civic
->loc_srv_intv_unit
));
2310 tprintf("Srv Intv: %u, ", civic
->loc_srv_intv
);
2312 if(!subelements(pkt
,
2313 meas_rep
->len
- 3 - sizeof(*civic
)))
2316 else if(meas_rep
->type
== 12) {
2317 struct element_meas_loc_id
*id
;
2319 id
= (struct element_meas_loc_id
*)
2320 pkt_pull(pkt
, sizeof(*id
));
2324 if ((meas_rep
->len
- 3 - sizeof(*id
)) >= 0) {
2325 tprintf("Length of Req matchs not Type %u",
2330 tprintf("Location Subj: %u, ", id
->loc_subj
);
2331 tprintf("Srv Intv Units: %u, ",
2332 le16_to_cpu(id
->loc_srv_intv_unit
));
2333 tprintf("Srv Intv: %u", id
->loc_srv_intv
);
2335 if(!subelements(pkt
,
2336 meas_rep
->len
- 3 - sizeof(*id
)))
2340 tprintf("Length field indicates data,"
2341 " but could not interpreted");
2349 static int8_t inf_quiet(struct pkt_buff
*pkt
, u8
*id
)
2351 struct element_quiet
*quiet
;
2353 quiet
= (struct element_quiet
*) pkt_pull(pkt
, sizeof(*quiet
));
2357 tprintf("Quit (%u, Len(%u)): ", *id
, quiet
->len
);
2358 if (len_neq_error(quiet
->len
, 6))
2361 tprintf("Count: %ud, ", quiet
->cnt
);
2362 tprintf("Period: %u, ", quiet
->period
);
2363 tprintf("Duration: %fs, ", le16_to_cpu(quiet
->dur
) * TU
);
2364 tprintf("Offs: %fs", le16_to_cpu(quiet
->offs
) * TU
);
2370 static int8_t inf_ibss_dfs(struct pkt_buff
*pkt
, u8
*id
)
2372 struct element_ibss_dfs
*ibss_dfs
;
2375 ibss_dfs
= (struct element_ibss_dfs
*) pkt_pull(pkt
, sizeof(*ibss_dfs
));
2376 if (ibss_dfs
== NULL
)
2379 tprintf("IBSS DFS (%u, Len(%u)): ", *id
, ibss_dfs
->len
);
2380 if (len_lt_error(ibss_dfs
->len
, 7))
2383 tprintf("Owner: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
2384 ibss_dfs
->owner
[0], ibss_dfs
->owner
[1],
2385 ibss_dfs
->owner
[2], ibss_dfs
->owner
[3],
2386 ibss_dfs
->owner
[4], ibss_dfs
->owner
[5]);
2387 tprintf("Recovery Intv: %u, ", ibss_dfs
->rec_intv
);
2389 if((ibss_dfs
->len
- sizeof(*ibss_dfs
) + 1) & 1) {
2390 tprintf("Length of Channel Map should be modulo 2");
2394 for (i
= 0; i
< ibss_dfs
->len
; i
+= 2) {
2395 struct element_ibss_dfs_tuple
*ibss_dfs_tuple
;
2397 ibss_dfs_tuple
= (struct element_ibss_dfs_tuple
*)
2398 pkt_pull(pkt
, sizeof(*ibss_dfs_tuple
));
2399 if (ibss_dfs_tuple
== NULL
)
2402 tprintf("Channel Nr: %u, ", ibss_dfs_tuple
->ch_nr
);
2403 tprintf("Map: %u, ", ibss_dfs_tuple
->map
);
2409 static int8_t inf_erp(struct pkt_buff
*pkt
, u8
*id
)
2411 struct element_erp
*erp
;
2413 erp
= (struct element_erp
*) pkt_pull(pkt
, sizeof(*erp
));
2417 tprintf("ERP (%u, Len(%u)): ", *id
, erp
->len
);
2418 if (len_neq_error(erp
->len
, 1))
2420 tprintf("Non ERP Present (%u), ", erp
->param
& 0x1);
2421 tprintf("Use Protection (%u), ", (erp
->param
>> 1) & 0x1);
2422 tprintf("Barker Preamble Mode (%u), ", (erp
->param
>> 2) & 0x1);
2423 tprintf("Reserved (0x%.5x)", erp
->param
>> 3);
2428 static int8_t inf_ts_del(struct pkt_buff
*pkt
, u8
*id
)
2430 struct element_ts_del
*ts_del
;
2432 ts_del
= (struct element_ts_del
*) pkt_pull(pkt
, sizeof(*ts_del
));
2436 tprintf("TS Delay (%u, Len(%u)): ", *id
, ts_del
->len
);
2437 if (len_neq_error(ts_del
->len
, 4))
2439 tprintf("Delay (%fs)", le32_to_cpu(ts_del
->delay
) * TU
);
2444 static int8_t inf_tclas_proc(struct pkt_buff
*pkt
, u8
*id
)
2446 struct element_tclas_proc
*tclas_proc
;
2448 tclas_proc
= (struct element_tclas_proc
*)
2449 pkt_pull(pkt
, sizeof(*tclas_proc
));
2450 if (tclas_proc
== NULL
)
2453 tprintf("TCLAS Procesing (%u, Len(%u)): ", *id
, tclas_proc
->len
);
2454 if (len_neq_error(tclas_proc
->len
, 1))
2456 tprintf("Processing (%u)", tclas_proc
->proc
);
2461 static int8_t inf_ht_cap(struct pkt_buff
*pkt
, u8
*id
)
2466 static int8_t inf_qos_cap(struct pkt_buff
*pkt
, u8
*id
)
2471 static int8_t inf_rsn(struct pkt_buff
*pkt
, u8
*id
)
2476 static int8_t inf_ext_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
2480 struct element_ext_supp_rates
*ext_supp_rates
;
2482 ext_supp_rates
= (struct element_ext_supp_rates
*)
2483 pkt_pull(pkt
, sizeof(*ext_supp_rates
));
2484 if (ext_supp_rates
== NULL
)
2487 tprintf("Ext Support Rates (%u, Len(%u)): ", *id
, ext_supp_rates
->len
);
2489 if ((ext_supp_rates
->len
- sizeof(*ext_supp_rates
) + 1) > 0) {
2490 rates
= pkt_pull(pkt
, ext_supp_rates
->len
);
2494 for (i
= 0; i
< ext_supp_rates
->len
; i
++)
2495 tprintf("%g ", (rates
[i
] & 0x80) ?
2496 ((rates
[i
] & 0x3f) * 0.5) :
2497 data_rates(rates
[i
]));
2504 static int8_t inf_ap_ch_exp(struct pkt_buff
*pkt
, u8
*id
) {
2508 static int8_t inf_neighb_rep(struct pkt_buff
*pkt
, u8
*id
) {
2512 static int8_t inf_rcpi(struct pkt_buff
*pkt
, u8
*id
) {
2516 static int8_t inf_mde(struct pkt_buff
*pkt
, u8
*id
) {
2520 static int8_t inf_fte(struct pkt_buff
*pkt
, u8
*id
) {
2524 static int8_t inf_time_out_int(struct pkt_buff
*pkt
, u8
*id
) {
2528 static int8_t inf_rde(struct pkt_buff
*pkt
, u8
*id
) {
2532 static int8_t inf_dse_reg_loc(struct pkt_buff
*pkt
, u8
*id
) {
2536 static int8_t inf_supp_op_class(struct pkt_buff
*pkt
, u8
*id
) {
2540 static int8_t inf_ext_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
) {
2544 static int8_t inf_ht_op(struct pkt_buff
*pkt
, u8
*id
) {
2548 static int8_t inf_sec_ch_offs(struct pkt_buff
*pkt
, u8
*id
) {
2552 static int8_t inf_bss_avg_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
2556 static int8_t inf_ant(struct pkt_buff
*pkt
, u8
*id
) {
2560 static int8_t inf_rsni(struct pkt_buff
*pkt
, u8
*id
) {
2564 static int8_t inf_meas_pilot_trans(struct pkt_buff
*pkt
, u8
*id
) {
2568 static int8_t inf_bss_avl_adm_cap(struct pkt_buff
*pkt
, u8
*id
) {
2572 static int8_t inf_bss_ac_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
2576 static int8_t inf_time_adv(struct pkt_buff
*pkt
, u8
*id
) {
2580 static int8_t inf_rm_ena_cap(struct pkt_buff
*pkt
, u8
*id
) {
2584 static int8_t inf_mult_bssid(struct pkt_buff
*pkt
, u8
*id
) {
2588 static int8_t inf_20_40_bss_coex(struct pkt_buff
*pkt
, u8
*id
) {
2592 static int8_t inf_20_40_bss_int_ch_rep(struct pkt_buff
*pkt
, u8
*id
) {
2596 static int8_t inf_overl_bss_scan_para(struct pkt_buff
*pkt
, u8
*id
) {
2600 static int8_t inf_ric_desc(struct pkt_buff
*pkt
, u8
*id
) {
2604 static int8_t inf_mgmt_mic(struct pkt_buff
*pkt
, u8
*id
) {
2608 static int8_t inf_ev_req(struct pkt_buff
*pkt
, u8
*id
) {
2612 static int8_t inf_ev_rep(struct pkt_buff
*pkt
, u8
*id
) {
2616 static int8_t inf_diagn_req(struct pkt_buff
*pkt
, u8
*id
) {
2620 static int8_t inf_diagn_rep(struct pkt_buff
*pkt
, u8
*id
) {
2624 static int8_t inf_loc_para(struct pkt_buff
*pkt
, u8
*id
) {
2628 static int8_t inf_nontr_bssid_cap(struct pkt_buff
*pkt
, u8
*id
) {
2632 static int8_t inf_ssid_list(struct pkt_buff
*pkt
, u8
*id
) {
2636 static int8_t inf_mult_bssid_index(struct pkt_buff
*pkt
, u8
*id
) {
2640 static int8_t inf_fms_desc(struct pkt_buff
*pkt
, u8
*id
) {
2644 static int8_t inf_fms_req(struct pkt_buff
*pkt
, u8
*id
) {
2648 static int8_t inf_fms_resp(struct pkt_buff
*pkt
, u8
*id
) {
2652 static int8_t inf_qos_tfc_cap(struct pkt_buff
*pkt
, u8
*id
) {
2656 static int8_t inf_bss_max_idle_per(struct pkt_buff
*pkt
, u8
*id
) {
2660 static int8_t inf_tfs_req(struct pkt_buff
*pkt
, u8
*id
) {
2664 static int8_t inf_tfs_resp(struct pkt_buff
*pkt
, u8
*id
) {
2668 static int8_t inf_wnm_sleep_mod(struct pkt_buff
*pkt
, u8
*id
) {
2672 static int8_t inf_tim_bcst_req(struct pkt_buff
*pkt
, u8
*id
) {
2676 static int8_t inf_tim_bcst_resp(struct pkt_buff
*pkt
, u8
*id
) {
2680 static int8_t inf_coll_interf_rep(struct pkt_buff
*pkt
, u8
*id
) {
2684 static int8_t inf_ch_usage(struct pkt_buff
*pkt
, u8
*id
) {
2688 static int8_t inf_time_zone(struct pkt_buff
*pkt
, u8
*id
) {
2692 static int8_t inf_dms_req(struct pkt_buff
*pkt
, u8
*id
) {
2696 static int8_t inf_dms_resp(struct pkt_buff
*pkt
, u8
*id
) {
2700 static int8_t inf_link_id(struct pkt_buff
*pkt
, u8
*id
) {
2704 static int8_t inf_wakeup_sched(struct pkt_buff
*pkt
, u8
*id
) {
2708 static int8_t inf_ch_sw_timing(struct pkt_buff
*pkt
, u8
*id
) {
2712 static int8_t inf_pti_ctrl(struct pkt_buff
*pkt
, u8
*id
) {
2716 static int8_t inf_tpu_buff_status(struct pkt_buff
*pkt
, u8
*id
) {
2720 static int8_t inf_interw(struct pkt_buff
*pkt
, u8
*id
) {
2724 static int8_t inf_adv_proto(struct pkt_buff
*pkt
, u8
*id
) {
2728 static int8_t inf_exp_bandw_req(struct pkt_buff
*pkt
, u8
*id
) {
2732 static int8_t inf_qos_map_set(struct pkt_buff
*pkt
, u8
*id
) {
2736 static int8_t inf_roam_cons(struct pkt_buff
*pkt
, u8
*id
) {
2740 static int8_t inf_emer_alert_id(struct pkt_buff
*pkt
, u8
*id
) {
2744 static int8_t inf_mesh_conf(struct pkt_buff
*pkt
, u8
*id
) {
2748 static int8_t inf_mesh_id(struct pkt_buff
*pkt
, u8
*id
) {
2752 static int8_t inf_mesh_link_metr_rep(struct pkt_buff
*pkt
, u8
*id
) {
2756 static int8_t inf_cong_notif(struct pkt_buff
*pkt
, u8
*id
) {
2760 static int8_t inf_mesh_peer_mgmt(struct pkt_buff
*pkt
, u8
*id
) {
2764 static int8_t inf_mesh_ch_sw_para(struct pkt_buff
*pkt
, u8
*id
) {
2768 static int8_t inf_mesh_awake_win(struct pkt_buff
*pkt
, u8
*id
) {
2772 static int8_t inf_beacon_timing(struct pkt_buff
*pkt
, u8
*id
) {
2776 static int8_t inf_mccaop_setup_req(struct pkt_buff
*pkt
, u8
*id
) {
2780 static int8_t inf_mccaop_setup_rep(struct pkt_buff
*pkt
, u8
*id
) {
2784 static int8_t inf_mccaop_adv(struct pkt_buff
*pkt
, u8
*id
) {
2788 static int8_t inf_mccaop_teardwn(struct pkt_buff
*pkt
, u8
*id
) {
2792 static int8_t inf_gann(struct pkt_buff
*pkt
, u8
*id
) {
2796 static int8_t inf_rann(struct pkt_buff
*pkt
, u8
*id
) {
2800 static int8_t inf_ext_cap(struct pkt_buff
*pkt
, u8
*id
) {
2804 static int8_t inf_preq(struct pkt_buff
*pkt
, u8
*id
) {
2808 static int8_t inf_prep(struct pkt_buff
*pkt
, u8
*id
) {
2812 static int8_t inf_perr(struct pkt_buff
*pkt
, u8
*id
) {
2816 static int8_t inf_pxu(struct pkt_buff
*pkt
, u8
*id
) {
2820 static int8_t inf_pxuc(struct pkt_buff
*pkt
, u8
*id
) {
2824 static int8_t inf_auth_mesh_peer_exch(struct pkt_buff
*pkt
, u8
*id
) {
2828 static int8_t inf_mic(struct pkt_buff
*pkt
, u8
*id
) {
2832 static int8_t inf_dest_uri(struct pkt_buff
*pkt
, u8
*id
) {
2836 static int8_t inf_u_apsd_coex(struct pkt_buff
*pkt
, u8
*id
) {
2840 static int8_t inf_mccaop_adv_overv(struct pkt_buff
*pkt
, u8
*id
) {
2844 static int8_t inf_vend_spec(struct pkt_buff
*pkt
, u8
*id
)
2848 struct element_vend_spec
*vend_spec
;
2850 vend_spec
= (struct element_vend_spec
*)
2851 pkt_pull(pkt
, sizeof(*vend_spec
));
2852 if (vend_spec
== NULL
)
2855 tprintf("Vendor Specific (%u, Len (%u)): ", *id
, vend_spec
->len
);
2857 data
= pkt_pull(pkt
, vend_spec
->len
);
2862 for (i
= 0; i
< vend_spec
->len
; i
++)
2863 tprintf("%.2x", data
[i
]);
2868 static int8_t inf_elements(struct pkt_buff
*pkt
)
2870 u8
*id
= pkt_pull(pkt
, 1);
2875 case 0: return inf_ssid(pkt
, id
);
2876 case 1: return inf_supp_rates(pkt
, id
);
2877 case 2: return inf_fh_ps(pkt
, id
);
2878 case 3: return inf_dsss_ps(pkt
, id
);
2879 case 4: return inf_cf_ps(pkt
, id
);
2880 case 5: return inf_tim(pkt
, id
);
2881 case 6: return inf_ibss_ps(pkt
, id
);
2882 case 7: return inf_country(pkt
, id
);
2883 case 8: return inf_hop_pp(pkt
, id
);
2884 case 9: return inf_hop_pt(pkt
, id
);
2885 case 10: return inf_req(pkt
, id
);
2886 case 11: return inf_bss_load(pkt
, id
);
2887 case 12: return inf_edca_ps(pkt
, id
);
2888 case 13: return inf_tspec(pkt
, id
);
2889 case 14: return inf_tclas(pkt
, id
);
2890 case 15: return inf_sched(pkt
, id
);
2891 case 16: return inf_chall_txt(pkt
, id
);
2892 case 17 ... 31: return inf_reserved(pkt
, id
);
2893 case 32: return inf_pwr_constr(pkt
, id
);
2894 case 33: return inf_pwr_cap(pkt
, id
);
2895 case 34: return inf_tpc_req(pkt
, id
);
2896 case 35: return inf_tpc_rep(pkt
, id
);
2897 case 36: return inf_supp_ch(pkt
, id
);
2898 case 37: return inf_ch_sw_ann(pkt
, id
);
2899 case 38: return inf_meas_req(pkt
, id
);
2900 case 39: return inf_meas_rep(pkt
, id
);
2901 case 40: return inf_quiet(pkt
, id
);
2902 case 41: return inf_ibss_dfs(pkt
, id
);
2903 case 42: return inf_erp(pkt
, id
);
2904 case 43: return inf_ts_del(pkt
, id
);
2905 case 44: return inf_tclas_proc(pkt
, id
);
2906 case 45: return inf_ht_cap(pkt
, id
);
2907 case 46: return inf_qos_cap(pkt
, id
);
2908 case 47: return inf_reserved(pkt
, id
);
2909 case 48: return inf_rsn(pkt
, id
);
2910 case 49: return inf_rsn(pkt
, id
);
2911 case 50: return inf_ext_supp_rates(pkt
, id
);
2912 case 51: return inf_ap_ch_exp(pkt
, id
);
2913 case 52: return inf_neighb_rep(pkt
, id
);
2914 case 53: return inf_rcpi(pkt
, id
);
2915 case 54: return inf_mde(pkt
, id
);
2916 case 55: return inf_fte(pkt
, id
);
2917 case 56: return inf_time_out_int(pkt
, id
);
2918 case 57: return inf_rde(pkt
, id
);
2919 case 58: return inf_dse_reg_loc(pkt
, id
);
2920 case 59: return inf_supp_op_class(pkt
, id
);
2921 case 60: return inf_ext_ch_sw_ann(pkt
, id
);
2922 case 61: return inf_ht_op(pkt
, id
);
2923 case 62: return inf_sec_ch_offs(pkt
, id
);
2924 case 63: return inf_bss_avg_acc_del(pkt
, id
);
2925 case 64: return inf_ant(pkt
, id
);
2926 case 65: return inf_rsni(pkt
, id
);
2927 case 66: return inf_meas_pilot_trans(pkt
, id
);
2928 case 67: return inf_bss_avl_adm_cap(pkt
, id
);
2929 case 68: return inf_bss_ac_acc_del(pkt
, id
);
2930 case 69: return inf_time_adv(pkt
, id
);
2931 case 70: return inf_rm_ena_cap(pkt
, id
);
2932 case 71: return inf_mult_bssid(pkt
, id
);
2933 case 72: return inf_20_40_bss_coex(pkt
, id
);
2934 case 73: return inf_20_40_bss_int_ch_rep(pkt
, id
);
2935 case 74: return inf_overl_bss_scan_para(pkt
, id
);
2936 case 75: return inf_ric_desc(pkt
, id
);
2937 case 76: return inf_mgmt_mic(pkt
, id
);
2938 case 78: return inf_ev_req(pkt
, id
);
2939 case 79: return inf_ev_rep(pkt
, id
);
2940 case 80: return inf_diagn_req(pkt
, id
);
2941 case 81: return inf_diagn_rep(pkt
, id
);
2942 case 82: return inf_loc_para(pkt
, id
);
2943 case 83: return inf_nontr_bssid_cap(pkt
, id
);
2944 case 84: return inf_ssid_list(pkt
, id
);
2945 case 85: return inf_mult_bssid_index(pkt
, id
);
2946 case 86: return inf_fms_desc(pkt
, id
);
2947 case 87: return inf_fms_req(pkt
, id
);
2948 case 88: return inf_fms_resp(pkt
, id
);
2949 case 89: return inf_qos_tfc_cap(pkt
, id
);
2950 case 90: return inf_bss_max_idle_per(pkt
, id
);
2951 case 91: return inf_tfs_req(pkt
, id
);
2952 case 92: return inf_tfs_resp(pkt
, id
);
2953 case 93: return inf_wnm_sleep_mod(pkt
, id
);
2954 case 94: return inf_tim_bcst_req(pkt
, id
);
2955 case 95: return inf_tim_bcst_resp(pkt
, id
);
2956 case 96: return inf_coll_interf_rep(pkt
, id
);
2957 case 97: return inf_ch_usage(pkt
, id
);
2958 case 98: return inf_time_zone(pkt
, id
);
2959 case 99: return inf_dms_req(pkt
, id
);
2960 case 100: return inf_dms_resp(pkt
, id
);
2961 case 101: return inf_link_id(pkt
, id
);
2962 case 102: return inf_wakeup_sched(pkt
, id
);
2963 case 104: return inf_ch_sw_timing(pkt
, id
);
2964 case 105: return inf_pti_ctrl(pkt
, id
);
2965 case 106: return inf_tpu_buff_status(pkt
, id
);
2966 case 107: return inf_interw(pkt
, id
);
2967 case 108: return inf_adv_proto(pkt
, id
);
2968 case 109: return inf_exp_bandw_req(pkt
, id
);
2969 case 110: return inf_qos_map_set(pkt
, id
);
2970 case 111: return inf_roam_cons(pkt
, id
);
2971 case 112: return inf_emer_alert_id(pkt
, id
);
2972 case 113: return inf_mesh_conf(pkt
, id
);
2973 case 114: return inf_mesh_id(pkt
, id
);
2974 case 115: return inf_mesh_link_metr_rep(pkt
, id
);
2975 case 116: return inf_cong_notif(pkt
, id
);
2976 case 117: return inf_mesh_peer_mgmt(pkt
, id
);
2977 case 118: return inf_mesh_ch_sw_para(pkt
, id
);
2978 case 119: return inf_mesh_awake_win(pkt
, id
);
2979 case 120: return inf_beacon_timing(pkt
, id
);
2980 case 121: return inf_mccaop_setup_req(pkt
, id
);
2981 case 122: return inf_mccaop_setup_rep(pkt
, id
);
2982 case 123: return inf_mccaop_adv(pkt
, id
);
2983 case 124: return inf_mccaop_teardwn(pkt
, id
);
2984 case 125: return inf_gann(pkt
, id
);
2985 case 126: return inf_rann(pkt
, id
);
2986 case 127: return inf_ext_cap(pkt
, id
);
2987 case 128: return inf_reserved(pkt
, id
);
2988 case 129: return inf_reserved(pkt
, id
);
2989 case 130: return inf_preq(pkt
, id
);
2990 case 131: return inf_prep(pkt
, id
);
2991 case 132: return inf_perr(pkt
, id
);
2992 case 133: return inf_reserved(pkt
, id
);
2993 case 134: return inf_reserved(pkt
, id
);
2994 case 135: return inf_reserved(pkt
, id
);
2995 case 136: return inf_reserved(pkt
, id
);
2996 case 137: return inf_pxu(pkt
, id
);
2997 case 138: return inf_pxuc(pkt
, id
);
2998 case 139: return inf_auth_mesh_peer_exch(pkt
, id
);
2999 case 140: return inf_mic(pkt
, id
);
3000 case 141: return inf_dest_uri(pkt
, id
);
3001 case 142: return inf_u_apsd_coex(pkt
, id
);
3002 case 143 ... 173: return inf_reserved(pkt
, id
);
3003 case 174: return inf_mccaop_adv_overv(pkt
, id
);
3004 case 221: return inf_vend_spec(pkt
, id
);
3010 #define ESS 0b0000000000000001
3011 #define IBSS 0b0000000000000010
3012 #define CF_Pollable 0b0000000000000100
3013 #define CF_Poll_Req 0b0000000000001000
3014 #define Privacy 0b0000000000010000
3015 #define Short_Pre 0b0000000000100000
3016 #define PBCC 0b0000000001000000
3017 #define Ch_Agility 0b0000000010000000
3018 #define Spec_Mgmt 0b0000000100000000
3019 #define QoS 0b0000001000000000
3020 #define Short_Slot_t 0b0000010000000000
3021 #define APSD 0b0000100000000000
3022 #define Radio_Meas 0b0001000000000000
3023 #define DSSS_OFDM 0b0010000000000000
3024 #define Del_Block_ACK 0b0100000000000000
3025 #define Imm_Block_ACK 0b1000000000000000
3027 static int8_t cap_field(u16 cap_inf
)
3033 if (CF_Pollable
& cap_inf
)
3034 tprintf(" CF Pollable;");
3035 if (CF_Poll_Req
& cap_inf
)
3036 tprintf(" CF-Poll Request;");
3037 if (Privacy
& cap_inf
)
3038 tprintf(" Privacy;");
3039 if (Short_Pre
& cap_inf
)
3040 tprintf(" Short Preamble;");
3043 if (Ch_Agility
& cap_inf
)
3044 tprintf(" Channel Agility;");
3045 if (Spec_Mgmt
& cap_inf
)
3046 tprintf(" Spectrum Management;");
3049 if (Short_Slot_t
& cap_inf
)
3050 tprintf(" Short Slot Time;");
3053 if (Radio_Meas
& cap_inf
)
3054 tprintf(" Radio Measurement;");
3055 if (DSSS_OFDM
& cap_inf
)
3056 tprintf(" DSSS-OFDM;");
3057 if (Del_Block_ACK
& cap_inf
)
3058 tprintf(" Delayed Block Ack;");
3059 if (Imm_Block_ACK
& cap_inf
)
3060 tprintf(" Immediate Block Ack;");
3065 /* Management Dissectors */
3066 static int8_t assoc_req(struct pkt_buff
*pkt
) {
3070 static int8_t assoc_resp(struct pkt_buff
*pkt
) {
3074 static int8_t reassoc_req(struct pkt_buff
*pkt
) {
3078 static int8_t reassoc_resp(struct pkt_buff
*pkt
) {
3082 static int8_t probe_req(struct pkt_buff
*pkt
) {
3086 static int8_t probe_resp(struct pkt_buff
*pkt
) {
3090 static int8_t beacon(struct pkt_buff
*pkt
)
3092 struct ieee80211_mgmt_beacon
*beacon
;
3094 beacon
= (struct ieee80211_mgmt_beacon
*)
3095 pkt_pull(pkt
, sizeof(*beacon
));
3099 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon
->timestamp
));
3100 tprintf("Beacon Interval (%fs), ", le16_to_cpu(beacon
->beacon_int
)*TU
);
3101 tprintf("Capabilities (0x%x <->", le16_to_cpu(beacon
->capab_info
));
3102 cap_field(le16_to_cpu(beacon
->capab_info
));
3106 tprintf("\n\tParameters:");
3107 while (inf_elements(pkt
)) {
3117 static int8_t atim(struct pkt_buff
*pkt
) {
3121 static int8_t disassoc(struct pkt_buff
*pkt
) {
3125 static int8_t auth(struct pkt_buff
*pkt
) {
3129 static int8_t deauth(struct pkt_buff
*pkt
) {
3132 /* End Management Dissectors */
3134 /* Control Dissectors */
3135 static int8_t ps_poll(struct pkt_buff
*pkt
) {
3139 static int8_t rts(struct pkt_buff
*pkt
) {
3143 static int8_t cts(struct pkt_buff
*pkt
) {
3147 static int8_t ack(struct pkt_buff
*pkt
) {
3151 static int8_t cf_end(struct pkt_buff
*pkt
) {
3155 static int8_t cf_end_ack(struct pkt_buff
*pkt
) {
3158 /* End Control Dissectors */
3160 /* Data Dissectors */
3161 static int8_t data(struct pkt_buff
*pkt
) {
3165 static int8_t data_cf_ack(struct pkt_buff
*pkt
) {
3169 static int8_t data_cf_poll(struct pkt_buff
*pkt
) {
3173 static int8_t data_cf_ack_poll(struct pkt_buff
*pkt
) {
3177 static int8_t null(struct pkt_buff
*pkt
) {
3181 static int8_t cf_ack(struct pkt_buff
*pkt
) {
3185 static int8_t cf_poll(struct pkt_buff
*pkt
) {
3189 static int8_t cf_ack_poll(struct pkt_buff
*pkt
) {
3192 /* End Data Dissectors */
3194 static const char *mgt_sub(u8 subtype
, struct pkt_buff
*pkt
,
3195 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3198 struct ieee80211_mgmt
*mgmt
;
3199 const char *dst
, *src
, *bssid
;
3201 mgmt
= (struct ieee80211_mgmt
*) pkt_pull(pkt
, sizeof(*mgmt
));
3205 dst
= lookup_vendor((mgmt
->da
[0] << 16) |
3206 (mgmt
->da
[1] << 8) |
3208 src
= lookup_vendor((mgmt
->sa
[0] << 16) |
3209 (mgmt
->sa
[1] << 8) |
3212 bssid
= lookup_vendor((mgmt
->bssid
[0] << 16) |
3213 (mgmt
->bssid
[1] << 8) |
3215 seq_ctrl
= le16_to_cpu(mgmt
->seq_ctrl
);
3217 tprintf("Duration (%u),", le16_to_cpu(mgmt
->duration
));
3218 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3219 mgmt
->da
[0], mgmt
->da
[1], mgmt
->da
[2],
3220 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
3222 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst
,
3223 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
3226 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3227 mgmt
->sa
[0], mgmt
->sa
[1], mgmt
->sa
[2],
3228 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
3230 tprintf("=> (%s:%.2x:%.2x:%.2x)", src
,
3231 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
3234 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
3235 mgmt
->bssid
[0], mgmt
->bssid
[1], mgmt
->bssid
[2],
3236 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
3238 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid
,
3239 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
3242 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ",
3243 seq_ctrl
& 0xf, seq_ctrl
>> 4);
3247 *get_content
= assoc_req
;
3248 return "Association Request";
3250 *get_content
= assoc_resp
;
3251 return "Association Response";
3253 *get_content
= reassoc_req
;
3254 return "Reassociation Request";
3256 *get_content
= reassoc_resp
;
3257 return "Reassociation Response";
3259 *get_content
= probe_req
;
3260 return "Probe Request";
3262 *get_content
= probe_resp
;
3263 return "Probe Response";
3265 *get_content
= beacon
;
3268 *get_content
= atim
;
3271 *get_content
= disassoc
;
3272 return "Disassociation";
3274 *get_content
= auth
;
3275 return "Authentication";
3277 *get_content
= deauth
;
3278 return "Deauthentication";
3279 case 0b0110 ... 0b0111:
3280 case 0b1101 ... 0b1111:
3281 *get_content
= NULL
;
3284 *get_content
= NULL
;
3285 return "Management SubType unknown";
3289 static const char *ctrl_sub(u8 subtype
, struct pkt_buff
*pkt
,
3290 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3294 *get_content
= ps_poll
;
3306 *get_content
= cf_end
;
3309 *get_content
= cf_end_ack
;
3310 return "CF End + CF-ACK";
3311 case 0b0000 ... 0b1001:
3312 *get_content
= NULL
;
3315 return "Control SubType unkown";
3319 static const char *data_sub(u8 subtype
, struct pkt_buff
*pkt
,
3320 int8_t (**get_content
)(struct pkt_buff
*pkt
))
3324 *get_content
= data
;
3327 *get_content
= data_cf_ack
;
3328 return "Data + CF-ACK";
3330 *get_content
= data_cf_poll
;
3331 return "Data + CF-Poll";
3333 *get_content
= data_cf_ack_poll
;
3334 return "Data + CF-ACK + CF-Poll";
3336 *get_content
= null
;
3339 *get_content
= cf_ack
;
3342 *get_content
= cf_poll
;
3345 *get_content
= cf_ack_poll
;
3346 return "CF-ACK + CF-Poll";
3347 case 0b1000 ... 0b1111:
3348 *get_content
= NULL
;
3351 *get_content
= NULL
;
3352 return "Data SubType unkown";
3357 frame_control_type(u8 type
, const char *(**get_subtype
)(u8 subtype
,
3358 struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)))
3362 *get_subtype
= mgt_sub
;
3363 return "Management";
3365 *get_subtype
= ctrl_sub
;
3368 *get_subtype
= data_sub
;
3371 *get_subtype
= NULL
;
3374 *get_subtype
= NULL
;
3375 return "Control Type unkown";
3379 static void ieee80211(struct pkt_buff
*pkt
)
3381 int8_t (*get_content
)(struct pkt_buff
*pkt
) = NULL
;
3382 const char *(*get_subtype
)(u8 subtype
, struct pkt_buff
*pkt
,
3383 int8_t (**get_content
)(struct pkt_buff
*pkt
)) = NULL
;
3384 const char *subtype
= NULL
;
3385 struct ieee80211_frm_ctrl
*frm_ctrl
;
3387 frm_ctrl
= (struct ieee80211_frm_ctrl
*)
3388 pkt_pull(pkt
, sizeof(*frm_ctrl
));
3389 if (frm_ctrl
== NULL
)
3392 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
3393 le16_to_cpu(frm_ctrl
->frame_control
));
3395 tprintf(" [ Proto Version (%u), ", frm_ctrl
->proto_version
);
3396 tprintf("Type (%u, %s), ", frm_ctrl
->type
,
3397 frame_control_type(frm_ctrl
->type
, &get_subtype
));
3399 subtype
= (*get_subtype
)(frm_ctrl
->subtype
, pkt
, &get_content
);
3400 tprintf("Subtype (%u, %s)", frm_ctrl
->subtype
, subtype
);
3402 tprintf("%s%s%s", colorize_start_full(black
, red
),
3403 "No SubType Data available", colorize_end());
3406 tprintf("%s%s", frm_ctrl
->to_ds
? ", Frame goes to DS" : "",
3407 frm_ctrl
->from_ds
? ", Frame comes from DS" : "");
3408 tprintf("%s", frm_ctrl
->more_frags
? ", More Fragments" : "");
3409 tprintf("%s", frm_ctrl
->retry
? ", Frame is retransmitted" : "");
3410 tprintf("%s", frm_ctrl
->power_mgmt
? ", In Power Saving Mode" : "");
3411 tprintf("%s", frm_ctrl
->more_data
? ", More Data" : "");
3412 tprintf("%s", frm_ctrl
->wep
? ", Needs WEP" : "");
3413 tprintf("%s", frm_ctrl
->order
? ", Order" : "");
3417 tprintf(" [ Subtype %s: ", subtype
);
3418 if (!((*get_content
) (pkt
)))
3419 tprintf("%s%s%s", colorize_start_full(black
, red
),
3420 "Failed to dissect Subtype", colorize_end());
3423 tprintf("%s%s%s", colorize_start_full(black
, red
),
3424 "No SubType Data available", colorize_end());
3429 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
3432 static void ieee80211_less(struct pkt_buff
*pkt
)
3434 tprintf("802.11 frame (more on todo)");
3437 struct protocol ieee80211_ops
= {
3439 .print_full
= ieee80211
,
3440 .print_less
= ieee80211_less
,
3443 EXPORT_SYMBOL(ieee80211_ops
);