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
{
524 struct element_ext_supp_rates
{
529 struct element_vend_spec
{
535 static int8_t len_neq_error(u8 len
, u8 intended
)
537 if(intended
!= len
) {
538 tprintf("Length should be %u Bytes", intended
);
545 static int8_t len_lt_error(u8 len
, u8 intended
)
548 tprintf("Length should be greater %u Bytes", intended
);
555 static float data_rates(u8 id
)
557 /* XXX Why not (id / 2.f)? */
565 case 11: return 5.5f
;
566 case 12: return 6.0f
;
567 case 18: return 9.0f
;
568 case 22: return 11.0f
;
569 case 24: return 12.0f
;
570 case 27: return 13.5f
;
571 case 36: return 18.0f
;
572 case 44: return 22.0f
;
573 case 48: return 24.0f
;
574 case 54: return 27.0f
;
575 case 66: return 33.0f
;
576 case 72: return 36.0f
;
577 case 96: return 48.0f
;
578 case 108: return 54.0f
;
584 static int8_t inf_reserved(struct pkt_buff
*pkt
, u8
*id
)
588 struct element_reserved
*reserved
;
590 reserved
= (struct element_reserved
*) pkt_pull(pkt
, sizeof(*reserved
));
591 if (reserved
== NULL
)
594 tprintf("Reserved (%u, Len (%u)): ", *id
, reserved
->len
);
596 data
= pkt_pull(pkt
, reserved
->len
);
601 for (i
= 0; i
< reserved
->len
; i
++)
602 tprintf("%.2x", data
[i
]);
607 static int8_t inf_ssid(struct pkt_buff
*pkt
, u8
*id
)
610 struct element_ssid
*ssid
;
613 ssid
= (struct element_ssid
*) pkt_pull(pkt
, sizeof(*ssid
));
617 tprintf(" SSID (%u, Len (%u)): ", *id
, ssid
->len
);
619 if ((ssid
->len
- sizeof(*ssid
) + 1) > 0) {
620 ssid_name
= (char *) pkt_pull(pkt
, ssid
->len
);
621 if (ssid_name
== NULL
)
624 for (i
= 0; i
< ssid
->len
; i
++)
625 tprintf("%c",ssid_name
[i
]);
627 tprintf("Wildcard SSID");
633 static int8_t inf_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
637 struct element_supp_rates
*supp_rates
;
639 supp_rates
= (struct element_supp_rates
*)
640 pkt_pull(pkt
, sizeof(*supp_rates
));
641 if (supp_rates
== NULL
)
644 tprintf("Rates (%u, Len (%u)): ", *id
, supp_rates
->len
);
645 if (len_lt_error(supp_rates
->len
, 1))
648 if ((supp_rates
->len
- sizeof(*supp_rates
) + 1) > 0) {
649 rates
= pkt_pull(pkt
, supp_rates
->len
);
653 for (i
= 0; i
< supp_rates
->len
; i
++)
654 tprintf("%g ", (rates
[i
] & 0x80) ?
655 ((rates
[i
] & 0x3f) * 0.5) :
656 data_rates(rates
[i
]));
663 static int8_t inf_fh_ps(struct pkt_buff
*pkt
, u8
*id
)
665 struct element_fh_ps
*fh_ps
;
667 fh_ps
= (struct element_fh_ps
*) pkt_pull(pkt
, sizeof(*fh_ps
));
671 tprintf("FH Param Set (%u, Len(%u)): ", *id
, fh_ps
->len
);
672 if (len_neq_error(fh_ps
->len
, 5))
674 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps
->dwell_time
) * TU
);
675 tprintf("HopSet: %u, ", fh_ps
->hop_set
);
676 tprintf("HopPattern: %u, ", fh_ps
->hop_pattern
);
677 tprintf("HopIndex: %u", fh_ps
->hop_index
);
682 static int8_t inf_dsss_ps(struct pkt_buff
*pkt
, u8
*id
)
684 struct element_dsss_ps
*dsss_ps
;
686 dsss_ps
= (struct element_dsss_ps
*) pkt_pull(pkt
, sizeof(*dsss_ps
));
690 tprintf("DSSS Param Set (%u, Len(%u)): ", *id
, dsss_ps
->len
);
691 if (len_neq_error(dsss_ps
->len
, 1))
693 tprintf("Current Channel: %u", dsss_ps
->curr_ch
);
698 static int8_t inf_cf_ps(struct pkt_buff
*pkt
, u8
*id
)
700 struct element_cf_ps
*cf_ps
;
702 cf_ps
= (struct element_cf_ps
*) pkt_pull(pkt
, sizeof(*cf_ps
));
706 tprintf("CF Param Set (%u, Len(%u)): ", *id
, cf_ps
->len
);
707 if (len_neq_error(cf_ps
->len
, 6))
709 tprintf("CFP Count: %u, ", cf_ps
->cfp_cnt
);
710 tprintf("CFP Period: %u, ", cf_ps
->cfp_period
);
711 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps
->cfp_max_dur
) * TU
);
712 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps
->cfp_dur_rem
) * TU
);
717 static int8_t inf_tim(struct pkt_buff
*pkt
, u8
*id
)
719 struct element_tim
*tim
;
721 tim
= (struct element_tim
*) pkt_pull(pkt
, sizeof(*tim
));
725 tprintf("TIM (%u, Len(%u)): ", *id
, tim
->len
);
726 if (len_lt_error(tim
->len
, 3))
728 tprintf("DTIM Count: %u, ", tim
->dtim_cnt
);
729 tprintf("DTIM Period: %u, ", tim
->dtim_period
);
730 tprintf("Bitmap Control: %u, ", tim
->bmp_cntrl
);
731 if ((tim
->len
- sizeof(*tim
) + 1) > 0) {
732 u8
*bmp
= pkt_pull(pkt
, (tim
->len
- sizeof(*tim
) + 1));
736 tprintf("Partial Virtual Bitmap: 0x");
737 for(u8 i
=0; i
< (tim
->len
- sizeof(*tim
) + 1); i
++)
738 tprintf("%.2x ", bmp
[i
]);
744 static int8_t inf_ibss_ps(struct pkt_buff
*pkt
, u8
*id
)
746 struct element_ibss_ps
*ibss_ps
;
748 ibss_ps
= (struct element_ibss_ps
*) pkt_pull(pkt
, sizeof(*ibss_ps
));
752 tprintf("IBSS Param Set (%u, Len(%u)): ", *id
, ibss_ps
->len
);
753 if (len_neq_error(ibss_ps
->len
, 2))
755 tprintf("ATIM Window: %fs", le16_to_cpu(ibss_ps
->atim_win
) * TU
);
760 static int8_t inf_country(struct pkt_buff
*pkt
, u8
*id
)
764 struct element_country
*country
;
766 country
= (struct element_country
*) pkt_pull(pkt
, sizeof(*country
));
770 tprintf("Country (%u, Len(%u)): ", *id
, country
->len
);
771 if (len_lt_error(country
->len
, 6))
773 tprintf("Country String: %c%c%c", country
->country_first
,
774 country
->country_sec
, country
->country_third
);
776 for (i
= 0; i
< (country
->len
- 3); i
+= 3) {
777 struct element_country_tripled
*country_tripled
;
779 country_tripled
= (struct element_country_tripled
*)
780 pkt_pull(pkt
, sizeof(*country_tripled
));
781 if (country_tripled
== NULL
)
784 if(country_tripled
->frst_ch
>= 201) {
785 tprintf("Oper Ext ID: %u, ", country_tripled
->frst_ch
);
786 tprintf("Operating Class: %u, ", country_tripled
->nr_ch
);
787 tprintf("Coverage Class: %u", country_tripled
->max_trans
);
789 tprintf("First Ch Nr: %u, ", country_tripled
->frst_ch
);
790 tprintf("Nr of Ch: %u, ", country_tripled
->nr_ch
);
791 tprintf("Max Transmit Pwr Lvl: %u", country_tripled
->max_trans
);
795 if(country
->len
% 2) {
796 pad
= pkt_pull(pkt
, 1);
800 tprintf(", Pad: 0x%x", *pad
);
806 static int8_t inf_hop_pp(struct pkt_buff
*pkt
, u8
*id
)
808 struct element_hop_pp
*hop_pp
;
810 hop_pp
= (struct element_hop_pp
*) pkt_pull(pkt
, sizeof(*hop_pp
));
814 tprintf("Hopping Pattern Param (%u, Len(%u)): ", *id
, hop_pp
->len
);
815 if (len_neq_error(hop_pp
->len
, 2))
817 tprintf("Nr of Ch: %u", hop_pp
->nr_ch
);
822 static int8_t inf_hop_pt(struct pkt_buff
*pkt
, u8
*id
)
826 struct element_hop_pt
*hop_pt
;
828 hop_pt
= (struct element_hop_pt
*) pkt_pull(pkt
, sizeof(*hop_pt
));
832 tprintf("Hopping Pattern Table (%u, Len(%u)): ", *id
, hop_pt
->len
);
833 if (len_lt_error(hop_pt
->len
, 4))
835 tprintf("Flag: %u, ", hop_pt
->flag
);
836 tprintf("Nr of Sets: %u, ", hop_pt
->nr_sets
);
837 tprintf("Modules: %u, ", hop_pt
->modules
);
838 tprintf("Offs: %u", hop_pt
->offs
);
840 if ((hop_pt
->len
- sizeof(*hop_pt
) + 1) > 0) {
841 rand_tabl
= pkt_pull(pkt
, (hop_pt
->len
- sizeof(*hop_pt
) + 1));
842 if (rand_tabl
== NULL
)
845 tprintf(", Rand table: 0x");
846 for (i
= 0; i
< (hop_pt
->len
- sizeof(*hop_pt
) + 1); i
++)
847 tprintf("%.2x ", rand_tabl
[i
]);
853 static int8_t inf_req(struct pkt_buff
*pkt
, u8
*id
)
856 struct element_req
*req
;
859 req
= (struct element_req
*) pkt_pull(pkt
, sizeof(*req
));
863 tprintf("Request Element (%u, Len(%u)): ", *id
, req
->len
);
864 if ((req
->len
- sizeof(*req
) + 1) > 0) {
865 req_ids
= pkt_pull(pkt
, (req
->len
- sizeof(*req
) + 1));
869 tprintf(", Requested Element IDs: ");
870 for (i
= 0; i
< (req
->len
- sizeof(*req
) + 1); i
++)
871 tprintf("%u ", req_ids
[i
]);
877 static int8_t inf_bss_load(struct pkt_buff
*pkt
, u8
*id
)
879 struct element_bss_load
*bss_load
;
881 bss_load
= (struct element_bss_load
*) pkt_pull(pkt
, sizeof(*bss_load
));
882 if (bss_load
== NULL
)
885 tprintf("BSS Load element (%u, Len(%u)): ", *id
, bss_load
->len
);
886 if (len_neq_error(bss_load
->len
, 5))
888 tprintf("Station Count: %u, ", le16_to_cpu(bss_load
->station_cnt
));
889 tprintf("Channel Utilization: %u, ", bss_load
->ch_util
);
890 tprintf("Available Admission Capacity: %uus",
891 bss_load
->avlb_adm_cap
* 32);
896 static int8_t inf_edca_ps(struct pkt_buff
*pkt
, u8
*id
)
898 u32 ac_be
, ac_bk
, ac_vi
, ac_vo
;
899 struct element_edca_ps
*edca_ps
;
901 edca_ps
= (struct element_edca_ps
*) pkt_pull(pkt
, sizeof(*edca_ps
));
905 ac_be
= le32_to_cpu(edca_ps
->ac_be
);
906 ac_bk
= le32_to_cpu(edca_ps
->ac_bk
);
907 ac_vi
= le32_to_cpu(edca_ps
->ac_vi
);
908 ac_vo
= le32_to_cpu(edca_ps
->ac_vo
);
910 tprintf("EDCA Param Set (%u, Len(%u)): ", *id
, edca_ps
->len
);
911 if (len_neq_error(edca_ps
->len
, 18))
913 tprintf("QoS Info: 0x%x (-> EDCA Param Set Update Count (%u),"
914 "Q-Ack (%u), Queue Re (%u), TXOP Req(%u), Res(%u)), ",
915 edca_ps
->qos_inf
, edca_ps
->qos_inf
>> 4,
916 (edca_ps
->qos_inf
>> 3) & 1, (edca_ps
->qos_inf
>> 2) & 1,
917 (edca_ps
->qos_inf
>> 1) & 1, edca_ps
->qos_inf
& 1);
918 tprintf("Reserved: 0x%x, ", edca_ps
->res
);
919 tprintf("AC_BE Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
920 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_be
,
921 ac_be
>> 28, (ac_be
>> 27) & 1, (ac_be
>> 25) & 3,
922 (ac_be
>> 24) & 1, (ac_be
>> 20) & 15, (ac_be
>> 16) & 15,
923 bswap_16(ac_be
& 0xFFFF) * 32);
924 tprintf("AC_BK Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
925 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_bk
,
926 ac_bk
>> 28, (ac_bk
>> 27) & 1, (ac_bk
>> 25) & 3,
927 (ac_bk
>> 24) & 1, (ac_bk
>> 20) & 15, (ac_bk
>> 16) & 15,
928 bswap_16(ac_bk
& 0xFFFF) * 32);
929 tprintf("AC_VI Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
930 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)), ", ac_vi
,
931 ac_vi
>> 28, (ac_vi
>> 27) & 1, (ac_vi
>> 25) & 3,
932 (ac_vi
>> 24) & 1, (ac_vi
>> 20) & 15, (ac_vi
>> 16) & 15,
933 bswap_16(ac_vi
& 0xFFFF) * 32);
934 tprintf("AC_VO Param Rec: 0x%x (-> AIFSN (%u), ACM (%u), ACI (%u),"
935 "Res (%u), ECWmin (%u), ECWmax(%u)), TXOP Limit (%uus)", ac_vo
,
936 ac_vo
>> 28, (ac_vo
>> 27) & 1, (ac_vo
>> 25) & 3,
937 (ac_vo
>> 24) & 1, (ac_vo
>> 20) & 15, (ac_vo
>> 16) & 15,
938 bswap_16(ac_vo
& 0xFFFF) * 32);
943 static int8_t inf_tspec(struct pkt_buff
*pkt
, u8
*id
)
945 u16 nom_msdu_size
, surplus_bandw_allow
;
946 struct element_tspec
*tspec
;
948 tspec
= (struct element_tspec
*) pkt_pull(pkt
, sizeof(*tspec
));
952 nom_msdu_size
= le16_to_cpu(tspec
->nom_msdu_size
);
953 surplus_bandw_allow
= le16_to_cpu(tspec
->surplus_bandw_allow
);
955 tprintf("TSPEC (%u, Len(%u)): ", *id
, tspec
->len
);
956 if (len_neq_error(tspec
->len
, 55))
958 tprintf("Traffic Type: %u, ", tspec
->traffic_type
);
959 tprintf("TSID: %u, ", tspec
->tsid
);
960 tprintf("Direction: %u, ", tspec
->direction
);
961 tprintf("Access Policy: %u, ", tspec
->access_policy
);
962 tprintf("Aggregation: %u, ", tspec
->aggr
);
963 tprintf("User Priority: %u, ", tspec
->user_prior
);
964 tprintf("TSinfo Ack Policy: %u, ", tspec
->tsinfo_ack_pol
);
965 tprintf("Schedule: %u, ", tspec
->schedule
);
966 tprintf("Reserved: 0x%x, ", tspec
->res
);
967 tprintf("Nominal MSDU Size: %uB (Fixed (%u)), ",
968 nom_msdu_size
>> 1, nom_msdu_size
& 1);
969 tprintf("Maximum MSDU Size: %uB, ", le16_to_cpu(tspec
->max_msdu_size
));
970 tprintf("Minimum Service Interval: %uus, ",
971 le32_to_cpu(tspec
->min_srv_intv
));
972 tprintf("Maximum Service Interval: %uus, ",
973 le32_to_cpu(tspec
->max_srv_intv
));
974 tprintf("Inactivity Interval: %uus, ",
975 le32_to_cpu(tspec
->inactive_intv
));
976 tprintf("Suspension Interval: %uus, ", le32_to_cpu(tspec
->susp_intv
));
977 tprintf("Service Start Time: %uus, ",
978 le32_to_cpu(tspec
->srv_start_time
));
979 tprintf("Minimum Data Rate: %ub/s, ",le32_to_cpu(tspec
->min_data_rate
));
980 tprintf("Mean Data Rate: %ub/s, ", le32_to_cpu(tspec
->mean_data_rate
));
981 tprintf("Peak Data Rate: %ub/s, ",le32_to_cpu(tspec
->peak_data_rate
));
982 tprintf("Burst Size: %uB, ", le32_to_cpu(tspec
->burst_size
));
983 tprintf("Delay Bound: %uus, ", le32_to_cpu(tspec
->delay_bound
));
984 tprintf("Minimum PHY Rate: %ub/s, ", le32_to_cpu(tspec
->min_phy_rate
));
985 tprintf("Surplus Bandwidth: %u.%u, ", surplus_bandw_allow
>> 13,
986 surplus_bandw_allow
& 0x1FFF);
987 tprintf("Medium Time: %uus", le16_to_cpu(tspec
->med_time
) * 32);
992 static const char *class_type(u8 type
)
995 case 0: return "Ethernet parameters";
996 case 1: return "TCP/UDP IP parameters";
997 case 2: return "IEEE 802.1Q parameters";
998 case 3: return "Filter Offset parameters";
999 case 4: return "IP and higher layer parameters";
1000 case 5: return "IEEE 802.1D/Q parameters";
1001 default: return "Reserved";
1005 static int8_t inf_tclas(struct pkt_buff
*pkt
, u8
*id
)
1007 struct element_tclas
*tclas
;
1008 struct element_tclas_frm_class
*frm_class
;
1010 tclas
= (struct element_tclas
*) pkt_pull(pkt
, sizeof(*tclas
));
1014 frm_class
= (struct element_tclas_frm_class
*)
1015 pkt_pull(pkt
, sizeof(*frm_class
));
1016 if (frm_class
== NULL
)
1019 tprintf("TCLAS (%u, Len(%u)): ", *id
, tclas
->len
);
1020 if (len_lt_error(tclas
->len
, 3))
1022 tprintf("User Priority: %u, ", tclas
->user_priority
);
1023 tprintf("Classifier Type: %s (%u), ", class_type(frm_class
->type
),
1025 tprintf("Classifier Mask: 0x%x, ", frm_class
->mask
);
1027 if(frm_class
->type
== 0) {
1028 struct element_tclas_type0
*type0
;
1030 type0
= (struct element_tclas_type0
*)
1031 pkt_pull(pkt
, sizeof(*type0
));
1035 /* I think little endian, like the rest */
1036 tprintf("Src Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1037 type0
->sa
[5], type0
->sa
[4], type0
->sa
[3],
1038 type0
->sa
[2], type0
->sa
[1], type0
->sa
[0]);
1039 tprintf("Dst Addr: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, ",
1040 type0
->da
[5], type0
->da
[4], type0
->da
[3],
1041 type0
->da
[2], type0
->da
[1], type0
->da
[0]);
1042 tprintf("Type: 0x%x", le16_to_cpu(type0
->type
));
1044 else if(frm_class
->type
== 1) {
1045 struct element_tclas_type1
*type1
;
1047 type1
= (struct element_tclas_type1
*)
1048 pkt_pull(pkt
, sizeof(*type1
));
1052 tprintf("Version: %u, ", type1
->version
);
1053 /* big endian format follows */
1054 if(type1
->version
== 4) {
1055 struct element_tclas_type1_ip4
*type1_ip4
;
1056 char src_ip
[INET_ADDRSTRLEN
];
1057 char dst_ip
[INET_ADDRSTRLEN
];
1059 type1_ip4
= (struct element_tclas_type1_ip4
*)
1060 pkt_pull(pkt
, sizeof(*type1_ip4
));
1061 if (type1_ip4
== NULL
)
1064 inet_ntop(AF_INET
, &type1_ip4
->sa
, src_ip
, sizeof(src_ip
));
1065 inet_ntop(AF_INET
, &type1_ip4
->da
, dst_ip
, sizeof(dst_ip
));
1067 tprintf("Src IP: %s, ", src_ip
);
1068 tprintf("Dst IP: %s, ", dst_ip
);
1069 tprintf("Src Port: %u, ", ntohs(type1_ip4
->sp
));
1070 tprintf("Dst Port: %u, ", ntohs(type1_ip4
->dp
));
1071 tprintf("DSCP: 0x%x, ", type1_ip4
->dscp
);
1072 tprintf("Proto: %u, ", type1_ip4
->proto
);
1073 tprintf("Res: 0x%x", type1_ip4
->reserved
);
1075 else if(type1
->version
== 6) {
1076 struct element_tclas_type1_ip6
*type1_ip6
;
1077 char src_ip
[INET6_ADDRSTRLEN
];
1078 char dst_ip
[INET6_ADDRSTRLEN
];
1080 type1_ip6
= (struct element_tclas_type1_ip6
*)
1081 pkt_pull(pkt
, sizeof(*type1_ip6
));
1082 if (type1_ip6
== NULL
)
1085 inet_ntop(AF_INET6
, &type1_ip6
->sa
,
1086 src_ip
, sizeof(src_ip
));
1087 inet_ntop(AF_INET6
, &type1_ip6
->da
,
1088 dst_ip
, sizeof(dst_ip
));
1090 tprintf("Src IP: %s, ", src_ip
);
1091 tprintf("Dst IP: %s, ", dst_ip
);
1092 tprintf("Src Port: %u, ", ntohs(type1_ip6
->sp
));
1093 tprintf("Dst Port: %u, ", ntohs(type1_ip6
->dp
));
1094 tprintf("Flow Label: 0x%x%x%x", type1_ip6
->flow_label1
,
1095 type1_ip6
->flow_label2
, type1_ip6
->flow_label3
);
1098 tprintf("Version (%u) not supported", type1
->version
);
1103 else if(frm_class
->type
== 2) {
1104 struct element_tclas_type2
*type2
;
1106 type2
= (struct element_tclas_type2
*)
1107 pkt_pull(pkt
, sizeof(*type2
));
1111 tprintf("802.1Q VLAN TCI: 0x%x", ntohs(type2
->vlan_tci
));
1113 else if(frm_class
->type
== 3) {
1114 struct element_tclas_type3
*type3
;
1118 type3
= (struct element_tclas_type3
*)
1119 pkt_pull(pkt
, sizeof(*type3
));
1123 len
= (tclas
->len
- 5) / 2;
1125 tprintf("Filter Offset: %u, ", type3
->offs
);
1127 if((len
& 1) || (len_lt_error(tclas
->len
, 5))) {
1128 tprintf("Length of TCLAS (%u) not correct", tclas
->len
);
1132 val
= pkt_pull(pkt
, len
);
1136 tprintf("Filter Value: 0x");
1137 for (i
= 0; i
< len
/ 2; i
++)
1138 tprintf("%x ", val
[i
]);
1140 tprintf("Filter Mask: 0x");
1141 for (i
= len
/ 2; i
< len
; i
++)
1142 tprintf("%x ", val
[i
]);
1146 else if(frm_class
->type
== 4) {
1147 struct element_tclas_type4
*type4
;
1149 type4
= (struct element_tclas_type4
*)
1150 pkt_pull(pkt
, sizeof(*type4
));
1154 tprintf("Version: %u, ", type4
->version
);
1155 /* big endian format follows */
1156 if(type4
->version
== 4) {
1157 struct element_tclas_type4_ip4
*type4_ip4
;
1158 char src_ip
[INET_ADDRSTRLEN
];
1159 char dst_ip
[INET_ADDRSTRLEN
];
1161 type4_ip4
= (struct element_tclas_type4_ip4
*)
1162 pkt_pull(pkt
, sizeof(*type4_ip4
));
1163 if (type4_ip4
== NULL
)
1166 inet_ntop(AF_INET
, &type4_ip4
->sa
, src_ip
, sizeof(src_ip
));
1167 inet_ntop(AF_INET
, &type4_ip4
->da
, dst_ip
, sizeof(dst_ip
));
1169 tprintf("Src IP: %s, ", src_ip
);
1170 tprintf("Dst IP: %s, ", dst_ip
);
1171 tprintf("Src Port: %u, ", ntohs(type4_ip4
->sp
));
1172 tprintf("Dst Port: %u, ", ntohs(type4_ip4
->dp
));
1173 tprintf("DSCP: 0x%x, ", type4_ip4
->dscp
);
1174 tprintf("Proto: %u, ", type4_ip4
->proto
);
1175 tprintf("Res: 0x%x", type4_ip4
->reserved
);
1177 else if(type4
->version
== 6) {
1178 struct element_tclas_type4_ip6
*type4_ip6
;
1179 char src_ip
[INET6_ADDRSTRLEN
];
1180 char dst_ip
[INET6_ADDRSTRLEN
];
1182 type4_ip6
= (struct element_tclas_type4_ip6
*)
1183 pkt_pull(pkt
, sizeof(*type4_ip6
));
1184 if (type4_ip6
== NULL
)
1187 inet_ntop(AF_INET6
, &type4_ip6
->sa
,
1188 src_ip
, sizeof(src_ip
));
1189 inet_ntop(AF_INET6
, &type4_ip6
->da
,
1190 dst_ip
, sizeof(dst_ip
));
1192 tprintf("Src IP: %s, ", src_ip
);
1193 tprintf("Dst IP: %s, ", dst_ip
);
1194 tprintf("Src Port: %u, ", ntohs(type4_ip6
->sp
));
1195 tprintf("Dst Port: %u, ", ntohs(type4_ip6
->dp
));
1196 tprintf("DSCP: 0x%x, ", type4_ip6
->dscp
);
1197 tprintf("Nxt Hdr: %u, ", type4_ip6
->nxt_hdr
);
1198 tprintf("Flow Label: 0x%x%x%x", type4_ip6
->flow_label1
,
1199 type4_ip6
->flow_label2
, type4_ip6
->flow_label3
);
1202 tprintf("Version (%u) not supported", type4
->version
);
1206 else if(frm_class
->type
== 5) {
1207 struct element_tclas_type5
*type5
;
1209 type5
= (struct element_tclas_type5
*)
1210 pkt_pull(pkt
, sizeof(*type5
));
1214 tprintf("802.1Q PCP: 0x%x, ", type5
->pcp
);
1215 tprintf("802.1Q CFI: 0x%x, ", type5
->cfi
);
1216 tprintf("802.1Q VID: 0x%x", type5
->vid
);
1219 tprintf("Classifier Type (%u) not supported", frm_class
->type
);
1226 static int8_t inf_sched(struct pkt_buff
*pkt
, u8
*id
)
1228 struct element_schedule
*schedule
;
1231 schedule
= (struct element_schedule
*) pkt_pull(pkt
, sizeof(*schedule
));
1232 if (schedule
== NULL
)
1235 info
= le16_to_cpu(schedule
->inf
);
1237 tprintf("Schedule (%u, Len(%u)): ", *id
, schedule
->len
);
1238 if (len_neq_error(schedule
->len
, 12))
1241 tprintf("Aggregation: %u, ", info
>> 15);
1242 tprintf("TSID: %u, ", (info
>> 11) & 0xF);
1243 tprintf("Direction: %u, ", (info
>> 9) & 0x3);
1244 tprintf("Res: %u, ", info
& 0x1FF);
1245 tprintf("Serv Start Time: %uus, ", le32_to_cpu(schedule
->start
));
1246 tprintf("Serv Interval: %uus, ", le32_to_cpu(schedule
->serv_intv
));
1247 tprintf("Spec Interval: %fs", le32_to_cpu(schedule
->spec_intv
) * TU
);
1252 static int8_t inf_chall_txt(struct pkt_buff
*pkt
, u8
*id
)
1254 struct element_chall_txt
*chall_txt
;
1258 chall_txt
= (struct element_chall_txt
*)
1259 pkt_pull(pkt
, sizeof(*chall_txt
));
1260 if (chall_txt
== NULL
)
1263 tprintf("Challenge Text (%u, Len(%u)): ", *id
, chall_txt
->len
);
1264 if ((chall_txt
->len
- sizeof(*chall_txt
) + 1) > 0) {
1265 txt
= pkt_pull(pkt
, (chall_txt
->len
- sizeof(*chall_txt
) + 1));
1270 for (i
= 0; i
< (chall_txt
->len
- sizeof(*chall_txt
) + 1); i
++)
1271 tprintf("%x ", txt
[i
]);
1277 static int8_t inf_pwr_constr(struct pkt_buff
*pkt
, u8
*id
)
1279 struct element_pwr_constr
*pwr_constr
;
1281 pwr_constr
= (struct element_pwr_constr
*) pkt_pull(pkt
, sizeof(*pwr_constr
));
1282 if (pwr_constr
== NULL
)
1285 tprintf("Power Constraint (%u, Len(%u)): ", *id
, pwr_constr
->len
);
1286 if (len_neq_error(pwr_constr
->len
, 1))
1289 tprintf("Local Power Constraint: %udB", pwr_constr
->local_pwr_constr
);
1294 static int8_t inf_pwr_cap(struct pkt_buff
*pkt
, u8
*id
)
1296 struct element_pwr_cap
*pwr_cap
;
1298 pwr_cap
= (struct element_pwr_cap
*) pkt_pull(pkt
, sizeof(*pwr_cap
));
1299 if (pwr_cap
== NULL
)
1302 tprintf("Power Capability (%u, Len(%u)): ", *id
, pwr_cap
->len
);
1303 if (len_neq_error(pwr_cap
->len
, 2))
1306 tprintf("Min. Transm. Pwr Cap.: %ddBm, ", (int8_t)pwr_cap
->min_pwr_cap
);
1307 tprintf("Max. Transm. Pwr Cap.: %ddBm", (int8_t)pwr_cap
->max_pwr_cap
);
1312 static int8_t inf_tpc_req(struct pkt_buff
*pkt
, u8
*id
)
1314 struct element_tpc_req
*tpc_req
;
1316 tpc_req
= (struct element_tpc_req
*) pkt_pull(pkt
, sizeof(*tpc_req
));
1317 if (tpc_req
== NULL
)
1320 tprintf("TPC Request (%u, Len(%u))", *id
, tpc_req
->len
);
1321 if (len_neq_error(tpc_req
->len
, 0))
1327 static int8_t inf_tpc_rep(struct pkt_buff
*pkt
, u8
*id
)
1329 struct element_tpc_rep
*tpc_rep
;
1331 tpc_rep
= (struct element_tpc_rep
*) pkt_pull(pkt
, sizeof(*tpc_rep
));
1332 if (tpc_rep
== NULL
)
1335 tprintf("TPC Report (%u, Len(%u)): ", *id
, tpc_rep
->len
);
1336 if (len_neq_error(tpc_rep
->len
, 2))
1339 tprintf("Transmit Power: %udBm, ", (int8_t)tpc_rep
->trans_pwr
);
1340 tprintf("Link Margin: %udB", (int8_t)tpc_rep
->trans_pwr
);
1345 static int8_t inf_supp_ch(struct pkt_buff
*pkt
, u8
*id
)
1347 struct element_supp_ch
*supp_ch
;
1350 supp_ch
= (struct element_supp_ch
*) pkt_pull(pkt
, sizeof(*supp_ch
));
1351 if (supp_ch
== NULL
)
1354 tprintf("Supp Channels (%u, Len(%u)): ", *id
, supp_ch
->len
);
1355 if (len_lt_error(supp_ch
->len
, 2))
1358 if(supp_ch
->len
& 1) {
1359 tprintf("Length should be modulo 2");
1363 for (i
= 0; i
< supp_ch
->len
; i
+= 2) {
1364 struct element_supp_ch_tuple
*supp_ch_tuple
;
1366 supp_ch_tuple
= (struct element_supp_ch_tuple
*)
1367 pkt_pull(pkt
, sizeof(*supp_ch_tuple
));
1368 if (supp_ch_tuple
== NULL
)
1371 tprintf("First Channel Nr: %u, ", supp_ch_tuple
->first_ch_nr
);
1372 tprintf("Nr of Channels: %u, ", supp_ch_tuple
->nr_ch
);
1378 static int8_t inf_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
)
1380 struct element_ch_sw_ann
*ch_sw_ann
;
1382 ch_sw_ann
= (struct element_ch_sw_ann
*)
1383 pkt_pull(pkt
, sizeof(*ch_sw_ann
));
1384 if (ch_sw_ann
== NULL
)
1387 tprintf("Channel Switch Announc (%u, Len(%u)): ", *id
, ch_sw_ann
->len
);
1388 if (len_neq_error(ch_sw_ann
->len
, 3))
1391 tprintf("Switch Mode: %ud, ", ch_sw_ann
->switch_mode
);
1392 tprintf("New Nr: %u, ", ch_sw_ann
->new_nr
);
1393 tprintf("Switch Count: %u", ch_sw_ann
->switch_cnt
);
1398 static int8_t inf_meas_req(struct pkt_buff
*pkt
, u8
*id
)
1403 static int8_t inf_meas_rep(struct pkt_buff
*pkt
, u8
*id
)
1408 static int8_t inf_quiet(struct pkt_buff
*pkt
, u8
*id
)
1413 static int8_t inf_ibss_dfs(struct pkt_buff
*pkt
, u8
*id
)
1418 static int8_t inf_erp(struct pkt_buff
*pkt
, u8
*id
)
1420 struct element_erp
*erp
;
1422 erp
= (struct element_erp
*) pkt_pull(pkt
, sizeof(*erp
));
1426 tprintf("ERP (%u, Len(%u)): ", *id
, erp
->len
);
1427 if (len_neq_error(erp
->len
, 1))
1429 tprintf("Non ERP Present (%u), ", erp
->param
& 0x1);
1430 tprintf("Use Protection (%u), ", (erp
->param
>> 1) & 0x1);
1431 tprintf("Barker Preamble Mode (%u), ", (erp
->param
>> 2) & 0x1);
1432 tprintf("Reserved (0x%.5x)", erp
->param
>> 3);
1437 static int8_t inf_ts_del(struct pkt_buff
*pkt
, u8
*id
)
1442 static int8_t inf_tclas_proc(struct pkt_buff
*pkt
, u8
*id
)
1447 static int8_t inf_ht_cap(struct pkt_buff
*pkt
, u8
*id
)
1452 static int8_t inf_qos_cap(struct pkt_buff
*pkt
, u8
*id
)
1457 static int8_t inf_rsn(struct pkt_buff
*pkt
, u8
*id
)
1462 static int8_t inf_ext_supp_rates(struct pkt_buff
*pkt
, u8
*id
)
1466 struct element_ext_supp_rates
*ext_supp_rates
;
1468 ext_supp_rates
= (struct element_ext_supp_rates
*)
1469 pkt_pull(pkt
, sizeof(*ext_supp_rates
));
1470 if (ext_supp_rates
== NULL
)
1473 tprintf("Ext Support Rates (%u, Len(%u)): ", *id
, ext_supp_rates
->len
);
1475 if ((ext_supp_rates
->len
- sizeof(*ext_supp_rates
) + 1) > 0) {
1476 rates
= pkt_pull(pkt
, ext_supp_rates
->len
);
1480 for (i
= 0; i
< ext_supp_rates
->len
; i
++)
1481 tprintf("%g ", (rates
[i
] & 0x80) ?
1482 ((rates
[i
] & 0x3f) * 0.5) :
1483 data_rates(rates
[i
]));
1490 static int8_t inf_ap_ch_exp(struct pkt_buff
*pkt
, u8
*id
) {
1494 static int8_t inf_neighb_rep(struct pkt_buff
*pkt
, u8
*id
) {
1498 static int8_t inf_rcpi(struct pkt_buff
*pkt
, u8
*id
) {
1502 static int8_t inf_mde(struct pkt_buff
*pkt
, u8
*id
) {
1506 static int8_t inf_fte(struct pkt_buff
*pkt
, u8
*id
) {
1510 static int8_t inf_time_out_int(struct pkt_buff
*pkt
, u8
*id
) {
1514 static int8_t inf_rde(struct pkt_buff
*pkt
, u8
*id
) {
1518 static int8_t inf_dse_reg_loc(struct pkt_buff
*pkt
, u8
*id
) {
1522 static int8_t inf_supp_op_class(struct pkt_buff
*pkt
, u8
*id
) {
1526 static int8_t inf_ext_ch_sw_ann(struct pkt_buff
*pkt
, u8
*id
) {
1530 static int8_t inf_ht_op(struct pkt_buff
*pkt
, u8
*id
) {
1534 static int8_t inf_sec_ch_offs(struct pkt_buff
*pkt
, u8
*id
) {
1538 static int8_t inf_bss_avg_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
1542 static int8_t inf_ant(struct pkt_buff
*pkt
, u8
*id
) {
1546 static int8_t inf_rsni(struct pkt_buff
*pkt
, u8
*id
) {
1550 static int8_t inf_meas_pilot_trans(struct pkt_buff
*pkt
, u8
*id
) {
1554 static int8_t inf_bss_avl_adm_cap(struct pkt_buff
*pkt
, u8
*id
) {
1558 static int8_t inf_bss_ac_acc_del(struct pkt_buff
*pkt
, u8
*id
) {
1562 static int8_t inf_time_adv(struct pkt_buff
*pkt
, u8
*id
) {
1566 static int8_t inf_rm_ena_cap(struct pkt_buff
*pkt
, u8
*id
) {
1570 static int8_t inf_mult_bssid(struct pkt_buff
*pkt
, u8
*id
) {
1574 static int8_t inf_20_40_bss_coex(struct pkt_buff
*pkt
, u8
*id
) {
1578 static int8_t inf_20_40_bss_int_ch_rep(struct pkt_buff
*pkt
, u8
*id
) {
1582 static int8_t inf_overl_bss_scan_para(struct pkt_buff
*pkt
, u8
*id
) {
1586 static int8_t inf_ric_desc(struct pkt_buff
*pkt
, u8
*id
) {
1590 static int8_t inf_mgmt_mic(struct pkt_buff
*pkt
, u8
*id
) {
1594 static int8_t inf_ev_req(struct pkt_buff
*pkt
, u8
*id
) {
1598 static int8_t inf_ev_rep(struct pkt_buff
*pkt
, u8
*id
) {
1602 static int8_t inf_diagn_req(struct pkt_buff
*pkt
, u8
*id
) {
1606 static int8_t inf_diagn_rep(struct pkt_buff
*pkt
, u8
*id
) {
1610 static int8_t inf_loc_para(struct pkt_buff
*pkt
, u8
*id
) {
1614 static int8_t inf_nontr_bssid_cap(struct pkt_buff
*pkt
, u8
*id
) {
1618 static int8_t inf_ssid_list(struct pkt_buff
*pkt
, u8
*id
) {
1622 static int8_t inf_mult_bssid_index(struct pkt_buff
*pkt
, u8
*id
) {
1626 static int8_t inf_fms_desc(struct pkt_buff
*pkt
, u8
*id
) {
1630 static int8_t inf_fms_req(struct pkt_buff
*pkt
, u8
*id
) {
1634 static int8_t inf_fms_resp(struct pkt_buff
*pkt
, u8
*id
) {
1638 static int8_t inf_qos_tfc_cap(struct pkt_buff
*pkt
, u8
*id
) {
1642 static int8_t inf_bss_max_idle_per(struct pkt_buff
*pkt
, u8
*id
) {
1646 static int8_t inf_tfs_req(struct pkt_buff
*pkt
, u8
*id
) {
1650 static int8_t inf_tfs_resp(struct pkt_buff
*pkt
, u8
*id
) {
1654 static int8_t inf_wnm_sleep_mod(struct pkt_buff
*pkt
, u8
*id
) {
1658 static int8_t inf_tim_bcst_req(struct pkt_buff
*pkt
, u8
*id
) {
1662 static int8_t inf_tim_bcst_resp(struct pkt_buff
*pkt
, u8
*id
) {
1666 static int8_t inf_coll_interf_rep(struct pkt_buff
*pkt
, u8
*id
) {
1670 static int8_t inf_ch_usage(struct pkt_buff
*pkt
, u8
*id
) {
1674 static int8_t inf_time_zone(struct pkt_buff
*pkt
, u8
*id
) {
1678 static int8_t inf_dms_req(struct pkt_buff
*pkt
, u8
*id
) {
1682 static int8_t inf_dms_resp(struct pkt_buff
*pkt
, u8
*id
) {
1686 static int8_t inf_link_id(struct pkt_buff
*pkt
, u8
*id
) {
1690 static int8_t inf_wakeup_sched(struct pkt_buff
*pkt
, u8
*id
) {
1694 static int8_t inf_ch_sw_timing(struct pkt_buff
*pkt
, u8
*id
) {
1698 static int8_t inf_pti_ctrl(struct pkt_buff
*pkt
, u8
*id
) {
1702 static int8_t inf_tpu_buff_status(struct pkt_buff
*pkt
, u8
*id
) {
1706 static int8_t inf_interw(struct pkt_buff
*pkt
, u8
*id
) {
1710 static int8_t inf_adv_proto(struct pkt_buff
*pkt
, u8
*id
) {
1714 static int8_t inf_exp_bandw_req(struct pkt_buff
*pkt
, u8
*id
) {
1718 static int8_t inf_qos_map_set(struct pkt_buff
*pkt
, u8
*id
) {
1722 static int8_t inf_roam_cons(struct pkt_buff
*pkt
, u8
*id
) {
1726 static int8_t inf_emer_alert_id(struct pkt_buff
*pkt
, u8
*id
) {
1730 static int8_t inf_mesh_conf(struct pkt_buff
*pkt
, u8
*id
) {
1734 static int8_t inf_mesh_id(struct pkt_buff
*pkt
, u8
*id
) {
1738 static int8_t inf_mesh_link_metr_rep(struct pkt_buff
*pkt
, u8
*id
) {
1742 static int8_t inf_cong_notif(struct pkt_buff
*pkt
, u8
*id
) {
1746 static int8_t inf_mesh_peer_mgmt(struct pkt_buff
*pkt
, u8
*id
) {
1750 static int8_t inf_mesh_ch_sw_para(struct pkt_buff
*pkt
, u8
*id
) {
1754 static int8_t inf_mesh_awake_win(struct pkt_buff
*pkt
, u8
*id
) {
1758 static int8_t inf_beacon_timing(struct pkt_buff
*pkt
, u8
*id
) {
1762 static int8_t inf_mccaop_setup_req(struct pkt_buff
*pkt
, u8
*id
) {
1766 static int8_t inf_mccaop_setup_rep(struct pkt_buff
*pkt
, u8
*id
) {
1770 static int8_t inf_mccaop_adv(struct pkt_buff
*pkt
, u8
*id
) {
1774 static int8_t inf_mccaop_teardwn(struct pkt_buff
*pkt
, u8
*id
) {
1778 static int8_t inf_gann(struct pkt_buff
*pkt
, u8
*id
) {
1782 static int8_t inf_rann(struct pkt_buff
*pkt
, u8
*id
) {
1786 static int8_t inf_ext_cap(struct pkt_buff
*pkt
, u8
*id
) {
1790 static int8_t inf_preq(struct pkt_buff
*pkt
, u8
*id
) {
1794 static int8_t inf_prep(struct pkt_buff
*pkt
, u8
*id
) {
1798 static int8_t inf_perr(struct pkt_buff
*pkt
, u8
*id
) {
1802 static int8_t inf_pxu(struct pkt_buff
*pkt
, u8
*id
) {
1806 static int8_t inf_pxuc(struct pkt_buff
*pkt
, u8
*id
) {
1810 static int8_t inf_auth_mesh_peer_exch(struct pkt_buff
*pkt
, u8
*id
) {
1814 static int8_t inf_mic(struct pkt_buff
*pkt
, u8
*id
) {
1818 static int8_t inf_dest_uri(struct pkt_buff
*pkt
, u8
*id
) {
1822 static int8_t inf_u_apsd_coex(struct pkt_buff
*pkt
, u8
*id
) {
1826 static int8_t inf_mccaop_adv_overv(struct pkt_buff
*pkt
, u8
*id
) {
1830 static int8_t inf_vend_spec(struct pkt_buff
*pkt
, u8
*id
)
1834 struct element_vend_spec
*vend_spec
;
1836 vend_spec
= (struct element_vend_spec
*)
1837 pkt_pull(pkt
, sizeof(*vend_spec
));
1838 if (vend_spec
== NULL
)
1841 tprintf("Vendor Specific (%u, Len (%u)): ", *id
, vend_spec
->len
);
1843 data
= pkt_pull(pkt
, vend_spec
->len
);
1848 for (i
= 0; i
< vend_spec
->len
; i
++)
1849 tprintf("%.2x", data
[i
]);
1854 static int8_t inf_elements(struct pkt_buff
*pkt
)
1856 u8
*id
= pkt_pull(pkt
, 1);
1861 case 0: return inf_ssid(pkt
, id
);
1862 case 1: return inf_supp_rates(pkt
, id
);
1863 case 2: return inf_fh_ps(pkt
, id
);
1864 case 3: return inf_dsss_ps(pkt
, id
);
1865 case 4: return inf_cf_ps(pkt
, id
);
1866 case 5: return inf_tim(pkt
, id
);
1867 case 6: return inf_ibss_ps(pkt
, id
);
1868 case 7: return inf_country(pkt
, id
);
1869 case 8: return inf_hop_pp(pkt
, id
);
1870 case 9: return inf_hop_pt(pkt
, id
);
1871 case 10: return inf_req(pkt
, id
);
1872 case 11: return inf_bss_load(pkt
, id
);
1873 case 12: return inf_edca_ps(pkt
, id
);
1874 case 13: return inf_tspec(pkt
, id
);
1875 case 14: return inf_tclas(pkt
, id
);
1876 case 15: return inf_sched(pkt
, id
);
1877 case 16: return inf_chall_txt(pkt
, id
);
1878 case 17 ... 31: return inf_reserved(pkt
, id
);
1879 case 32: return inf_pwr_constr(pkt
, id
);
1880 case 33: return inf_pwr_cap(pkt
, id
);
1881 case 34: return inf_tpc_req(pkt
, id
);
1882 case 35: return inf_tpc_rep(pkt
, id
);
1883 case 36: return inf_supp_ch(pkt
, id
);
1884 case 37: return inf_ch_sw_ann(pkt
, id
);
1885 case 38: return inf_meas_req(pkt
, id
);
1886 case 39: return inf_meas_rep(pkt
, id
);
1887 case 40: return inf_quiet(pkt
, id
);
1888 case 41: return inf_ibss_dfs(pkt
, id
);
1889 case 42: return inf_erp(pkt
, id
);
1890 case 43: return inf_ts_del(pkt
, id
);
1891 case 44: return inf_tclas_proc(pkt
, id
);
1892 case 45: return inf_ht_cap(pkt
, id
);
1893 case 46: return inf_qos_cap(pkt
, id
);
1894 case 47: return inf_reserved(pkt
, id
);
1895 case 48: return inf_rsn(pkt
, id
);
1896 case 49: return inf_rsn(pkt
, id
);
1897 case 50: return inf_ext_supp_rates(pkt
, id
);
1898 case 51: return inf_ap_ch_exp(pkt
, id
);
1899 case 52: return inf_neighb_rep(pkt
, id
);
1900 case 53: return inf_rcpi(pkt
, id
);
1901 case 54: return inf_mde(pkt
, id
);
1902 case 55: return inf_fte(pkt
, id
);
1903 case 56: return inf_time_out_int(pkt
, id
);
1904 case 57: return inf_rde(pkt
, id
);
1905 case 58: return inf_dse_reg_loc(pkt
, id
);
1906 case 59: return inf_supp_op_class(pkt
, id
);
1907 case 60: return inf_ext_ch_sw_ann(pkt
, id
);
1908 case 61: return inf_ht_op(pkt
, id
);
1909 case 62: return inf_sec_ch_offs(pkt
, id
);
1910 case 63: return inf_bss_avg_acc_del(pkt
, id
);
1911 case 64: return inf_ant(pkt
, id
);
1912 case 65: return inf_rsni(pkt
, id
);
1913 case 66: return inf_meas_pilot_trans(pkt
, id
);
1914 case 67: return inf_bss_avl_adm_cap(pkt
, id
);
1915 case 68: return inf_bss_ac_acc_del(pkt
, id
);
1916 case 69: return inf_time_adv(pkt
, id
);
1917 case 70: return inf_rm_ena_cap(pkt
, id
);
1918 case 71: return inf_mult_bssid(pkt
, id
);
1919 case 72: return inf_20_40_bss_coex(pkt
, id
);
1920 case 73: return inf_20_40_bss_int_ch_rep(pkt
, id
);
1921 case 74: return inf_overl_bss_scan_para(pkt
, id
);
1922 case 75: return inf_ric_desc(pkt
, id
);
1923 case 76: return inf_mgmt_mic(pkt
, id
);
1924 case 78: return inf_ev_req(pkt
, id
);
1925 case 79: return inf_ev_rep(pkt
, id
);
1926 case 80: return inf_diagn_req(pkt
, id
);
1927 case 81: return inf_diagn_rep(pkt
, id
);
1928 case 82: return inf_loc_para(pkt
, id
);
1929 case 83: return inf_nontr_bssid_cap(pkt
, id
);
1930 case 84: return inf_ssid_list(pkt
, id
);
1931 case 85: return inf_mult_bssid_index(pkt
, id
);
1932 case 86: return inf_fms_desc(pkt
, id
);
1933 case 87: return inf_fms_req(pkt
, id
);
1934 case 88: return inf_fms_resp(pkt
, id
);
1935 case 89: return inf_qos_tfc_cap(pkt
, id
);
1936 case 90: return inf_bss_max_idle_per(pkt
, id
);
1937 case 91: return inf_tfs_req(pkt
, id
);
1938 case 92: return inf_tfs_resp(pkt
, id
);
1939 case 93: return inf_wnm_sleep_mod(pkt
, id
);
1940 case 94: return inf_tim_bcst_req(pkt
, id
);
1941 case 95: return inf_tim_bcst_resp(pkt
, id
);
1942 case 96: return inf_coll_interf_rep(pkt
, id
);
1943 case 97: return inf_ch_usage(pkt
, id
);
1944 case 98: return inf_time_zone(pkt
, id
);
1945 case 99: return inf_dms_req(pkt
, id
);
1946 case 100: return inf_dms_resp(pkt
, id
);
1947 case 101: return inf_link_id(pkt
, id
);
1948 case 102: return inf_wakeup_sched(pkt
, id
);
1949 case 104: return inf_ch_sw_timing(pkt
, id
);
1950 case 105: return inf_pti_ctrl(pkt
, id
);
1951 case 106: return inf_tpu_buff_status(pkt
, id
);
1952 case 107: return inf_interw(pkt
, id
);
1953 case 108: return inf_adv_proto(pkt
, id
);
1954 case 109: return inf_exp_bandw_req(pkt
, id
);
1955 case 110: return inf_qos_map_set(pkt
, id
);
1956 case 111: return inf_roam_cons(pkt
, id
);
1957 case 112: return inf_emer_alert_id(pkt
, id
);
1958 case 113: return inf_mesh_conf(pkt
, id
);
1959 case 114: return inf_mesh_id(pkt
, id
);
1960 case 115: return inf_mesh_link_metr_rep(pkt
, id
);
1961 case 116: return inf_cong_notif(pkt
, id
);
1962 case 117: return inf_mesh_peer_mgmt(pkt
, id
);
1963 case 118: return inf_mesh_ch_sw_para(pkt
, id
);
1964 case 119: return inf_mesh_awake_win(pkt
, id
);
1965 case 120: return inf_beacon_timing(pkt
, id
);
1966 case 121: return inf_mccaop_setup_req(pkt
, id
);
1967 case 122: return inf_mccaop_setup_rep(pkt
, id
);
1968 case 123: return inf_mccaop_adv(pkt
, id
);
1969 case 124: return inf_mccaop_teardwn(pkt
, id
);
1970 case 125: return inf_gann(pkt
, id
);
1971 case 126: return inf_rann(pkt
, id
);
1972 case 127: return inf_ext_cap(pkt
, id
);
1973 case 128: return inf_reserved(pkt
, id
);
1974 case 129: return inf_reserved(pkt
, id
);
1975 case 130: return inf_preq(pkt
, id
);
1976 case 131: return inf_prep(pkt
, id
);
1977 case 132: return inf_perr(pkt
, id
);
1978 case 133: return inf_reserved(pkt
, id
);
1979 case 134: return inf_reserved(pkt
, id
);
1980 case 135: return inf_reserved(pkt
, id
);
1981 case 136: return inf_reserved(pkt
, id
);
1982 case 137: return inf_pxu(pkt
, id
);
1983 case 138: return inf_pxuc(pkt
, id
);
1984 case 139: return inf_auth_mesh_peer_exch(pkt
, id
);
1985 case 140: return inf_mic(pkt
, id
);
1986 case 141: return inf_dest_uri(pkt
, id
);
1987 case 142: return inf_u_apsd_coex(pkt
, id
);
1988 case 143 ... 173: return inf_reserved(pkt
, id
);
1989 case 174: return inf_mccaop_adv_overv(pkt
, id
);
1990 case 221: return inf_vend_spec(pkt
, id
);
1996 #define ESS 0b0000000000000001
1997 #define IBSS 0b0000000000000010
1998 #define CF_Pollable 0b0000000000000100
1999 #define CF_Poll_Req 0b0000000000001000
2000 #define Privacy 0b0000000000010000
2001 #define Short_Pre 0b0000000000100000
2002 #define PBCC 0b0000000001000000
2003 #define Ch_Agility 0b0000000010000000
2004 #define Spec_Mgmt 0b0000000100000000
2005 #define QoS 0b0000001000000000
2006 #define Short_Slot_t 0b0000010000000000
2007 #define APSD 0b0000100000000000
2008 #define Radio_Meas 0b0001000000000000
2009 #define DSSS_OFDM 0b0010000000000000
2010 #define Del_Block_ACK 0b0100000000000000
2011 #define Imm_Block_ACK 0b1000000000000000
2013 static int8_t cap_field(u16 cap_inf
)
2019 if (CF_Pollable
& cap_inf
)
2020 tprintf(" CF Pollable;");
2021 if (CF_Poll_Req
& cap_inf
)
2022 tprintf(" CF-Poll Request;");
2023 if (Privacy
& cap_inf
)
2024 tprintf(" Privacy;");
2025 if (Short_Pre
& cap_inf
)
2026 tprintf(" Short Preamble;");
2029 if (Ch_Agility
& cap_inf
)
2030 tprintf(" Channel Agility;");
2031 if (Spec_Mgmt
& cap_inf
)
2032 tprintf(" Spectrum Management;");
2035 if (Short_Slot_t
& cap_inf
)
2036 tprintf(" Short Slot Time;");
2039 if (Radio_Meas
& cap_inf
)
2040 tprintf(" Radio Measurement;");
2041 if (DSSS_OFDM
& cap_inf
)
2042 tprintf(" DSSS-OFDM;");
2043 if (Del_Block_ACK
& cap_inf
)
2044 tprintf(" Delayed Block Ack;");
2045 if (Imm_Block_ACK
& cap_inf
)
2046 tprintf(" Immediate Block Ack;");
2051 /* Management Dissectors */
2052 static int8_t assoc_req(struct pkt_buff
*pkt
) {
2056 static int8_t assoc_resp(struct pkt_buff
*pkt
) {
2060 static int8_t reassoc_req(struct pkt_buff
*pkt
) {
2064 static int8_t reassoc_resp(struct pkt_buff
*pkt
) {
2068 static int8_t probe_req(struct pkt_buff
*pkt
) {
2072 static int8_t probe_resp(struct pkt_buff
*pkt
) {
2076 static int8_t beacon(struct pkt_buff
*pkt
)
2078 struct ieee80211_mgmt_beacon
*beacon
;
2080 beacon
= (struct ieee80211_mgmt_beacon
*)
2081 pkt_pull(pkt
, sizeof(*beacon
));
2085 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon
->timestamp
));
2086 tprintf("Beacon Interval (%fs), ", le16_to_cpu(beacon
->beacon_int
)*TU
);
2087 tprintf("Capabilities (0x%x <->", le16_to_cpu(beacon
->capab_info
));
2088 cap_field(le16_to_cpu(beacon
->capab_info
));
2092 tprintf("\n\tParameters:");
2093 while (inf_elements(pkt
)) {
2103 static int8_t atim(struct pkt_buff
*pkt
) {
2107 static int8_t disassoc(struct pkt_buff
*pkt
) {
2111 static int8_t auth(struct pkt_buff
*pkt
) {
2115 static int8_t deauth(struct pkt_buff
*pkt
) {
2118 /* End Management Dissectors */
2120 /* Control Dissectors */
2121 static int8_t ps_poll(struct pkt_buff
*pkt
) {
2125 static int8_t rts(struct pkt_buff
*pkt
) {
2129 static int8_t cts(struct pkt_buff
*pkt
) {
2133 static int8_t ack(struct pkt_buff
*pkt
) {
2137 static int8_t cf_end(struct pkt_buff
*pkt
) {
2141 static int8_t cf_end_ack(struct pkt_buff
*pkt
) {
2144 /* End Control Dissectors */
2146 /* Data Dissectors */
2147 static int8_t data(struct pkt_buff
*pkt
) {
2151 static int8_t data_cf_ack(struct pkt_buff
*pkt
) {
2155 static int8_t data_cf_poll(struct pkt_buff
*pkt
) {
2159 static int8_t data_cf_ack_poll(struct pkt_buff
*pkt
) {
2163 static int8_t null(struct pkt_buff
*pkt
) {
2167 static int8_t cf_ack(struct pkt_buff
*pkt
) {
2171 static int8_t cf_poll(struct pkt_buff
*pkt
) {
2175 static int8_t cf_ack_poll(struct pkt_buff
*pkt
) {
2178 /* End Data Dissectors */
2180 static const char *mgt_sub(u8 subtype
, struct pkt_buff
*pkt
,
2181 int8_t (**get_content
)(struct pkt_buff
*pkt
))
2184 struct ieee80211_mgmt
*mgmt
;
2185 const char *dst
, *src
, *bssid
;
2187 mgmt
= (struct ieee80211_mgmt
*) pkt_pull(pkt
, sizeof(*mgmt
));
2191 dst
= lookup_vendor((mgmt
->da
[0] << 16) |
2192 (mgmt
->da
[1] << 8) |
2194 src
= lookup_vendor((mgmt
->sa
[0] << 16) |
2195 (mgmt
->sa
[1] << 8) |
2198 bssid
= lookup_vendor((mgmt
->bssid
[0] << 16) |
2199 (mgmt
->bssid
[1] << 8) |
2201 seq_ctrl
= le16_to_cpu(mgmt
->seq_ctrl
);
2203 tprintf("Duration (%u),", le16_to_cpu(mgmt
->duration
));
2204 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
2205 mgmt
->da
[0], mgmt
->da
[1], mgmt
->da
[2],
2206 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
2208 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst
,
2209 mgmt
->da
[3], mgmt
->da
[4], mgmt
->da
[5]);
2212 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
2213 mgmt
->sa
[0], mgmt
->sa
[1], mgmt
->sa
[2],
2214 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
2216 tprintf("=> (%s:%.2x:%.2x:%.2x)", src
,
2217 mgmt
->sa
[3], mgmt
->sa
[4], mgmt
->sa
[5]);
2220 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
2221 mgmt
->bssid
[0], mgmt
->bssid
[1], mgmt
->bssid
[2],
2222 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
2224 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid
,
2225 mgmt
->bssid
[3], mgmt
->bssid
[4], mgmt
->bssid
[5]);
2228 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ",
2229 seq_ctrl
& 0xf, seq_ctrl
>> 4);
2233 *get_content
= assoc_req
;
2234 return "Association Request";
2236 *get_content
= assoc_resp
;
2237 return "Association Response";
2239 *get_content
= reassoc_req
;
2240 return "Reassociation Request";
2242 *get_content
= reassoc_resp
;
2243 return "Reassociation Response";
2245 *get_content
= probe_req
;
2246 return "Probe Request";
2248 *get_content
= probe_resp
;
2249 return "Probe Response";
2251 *get_content
= beacon
;
2254 *get_content
= atim
;
2257 *get_content
= disassoc
;
2258 return "Disassociation";
2260 *get_content
= auth
;
2261 return "Authentication";
2263 *get_content
= deauth
;
2264 return "Deauthentication";
2265 case 0b0110 ... 0b0111:
2266 case 0b1101 ... 0b1111:
2267 *get_content
= NULL
;
2270 *get_content
= NULL
;
2271 return "Management SubType unknown";
2275 static const char *ctrl_sub(u8 subtype
, struct pkt_buff
*pkt
,
2276 int8_t (**get_content
)(struct pkt_buff
*pkt
))
2280 *get_content
= ps_poll
;
2292 *get_content
= cf_end
;
2295 *get_content
= cf_end_ack
;
2296 return "CF End + CF-ACK";
2297 case 0b0000 ... 0b1001:
2298 *get_content
= NULL
;
2301 return "Control SubType unkown";
2305 static const char *data_sub(u8 subtype
, struct pkt_buff
*pkt
,
2306 int8_t (**get_content
)(struct pkt_buff
*pkt
))
2310 *get_content
= data
;
2313 *get_content
= data_cf_ack
;
2314 return "Data + CF-ACK";
2316 *get_content
= data_cf_poll
;
2317 return "Data + CF-Poll";
2319 *get_content
= data_cf_ack_poll
;
2320 return "Data + CF-ACK + CF-Poll";
2322 *get_content
= null
;
2325 *get_content
= cf_ack
;
2328 *get_content
= cf_poll
;
2331 *get_content
= cf_ack_poll
;
2332 return "CF-ACK + CF-Poll";
2333 case 0b1000 ... 0b1111:
2334 *get_content
= NULL
;
2337 *get_content
= NULL
;
2338 return "Data SubType unkown";
2343 frame_control_type(u8 type
, const char *(**get_subtype
)(u8 subtype
,
2344 struct pkt_buff
*pkt
, int8_t (**get_content
)(struct pkt_buff
*pkt
)))
2348 *get_subtype
= mgt_sub
;
2349 return "Management";
2351 *get_subtype
= ctrl_sub
;
2354 *get_subtype
= data_sub
;
2357 *get_subtype
= NULL
;
2360 *get_subtype
= NULL
;
2361 return "Control Type unkown";
2365 static void ieee80211(struct pkt_buff
*pkt
)
2367 int8_t (*get_content
)(struct pkt_buff
*pkt
) = NULL
;
2368 const char *(*get_subtype
)(u8 subtype
, struct pkt_buff
*pkt
,
2369 int8_t (**get_content
)(struct pkt_buff
*pkt
)) = NULL
;
2370 const char *subtype
= NULL
;
2371 struct ieee80211_frm_ctrl
*frm_ctrl
;
2373 frm_ctrl
= (struct ieee80211_frm_ctrl
*)
2374 pkt_pull(pkt
, sizeof(*frm_ctrl
));
2375 if (frm_ctrl
== NULL
)
2378 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
2379 le16_to_cpu(frm_ctrl
->frame_control
));
2381 tprintf(" [ Proto Version (%u), ", frm_ctrl
->proto_version
);
2382 tprintf("Type (%u, %s), ", frm_ctrl
->type
,
2383 frame_control_type(frm_ctrl
->type
, &get_subtype
));
2385 subtype
= (*get_subtype
)(frm_ctrl
->subtype
, pkt
, &get_content
);
2386 tprintf("Subtype (%u, %s)", frm_ctrl
->subtype
, subtype
);
2388 tprintf("%s%s%s", colorize_start_full(black
, red
),
2389 "No SubType Data available", colorize_end());
2392 tprintf("%s%s", frm_ctrl
->to_ds
? ", Frame goes to DS" : "",
2393 frm_ctrl
->from_ds
? ", Frame comes from DS" : "");
2394 tprintf("%s", frm_ctrl
->more_frags
? ", More Fragments" : "");
2395 tprintf("%s", frm_ctrl
->retry
? ", Frame is retransmitted" : "");
2396 tprintf("%s", frm_ctrl
->power_mgmt
? ", In Power Saving Mode" : "");
2397 tprintf("%s", frm_ctrl
->more_data
? ", More Data" : "");
2398 tprintf("%s", frm_ctrl
->wep
? ", Needs WEP" : "");
2399 tprintf("%s", frm_ctrl
->order
? ", Order" : "");
2403 tprintf(" [ Subtype %s: ", subtype
);
2404 if (!((*get_content
) (pkt
)))
2405 tprintf("%s%s%s", colorize_start_full(black
, red
),
2406 "Failed to dissect Subtype", colorize_end());
2409 tprintf("%s%s%s", colorize_start_full(black
, red
),
2410 "No SubType Data available", colorize_end());
2415 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
2418 static void ieee80211_less(struct pkt_buff
*pkt
)
2420 tprintf("802.11 frame (more on todo)");
2423 struct protocol ieee80211_ops
= {
2425 .print_full
= ieee80211
,
2426 .print_less
= ieee80211_less
,
2429 EXPORT_SYMBOL(ieee80211_ops
);