proto_80211_mac_hdr.c: implement partly info elements
[netsniff-ng.git] / src / proto_80211_mac_hdr.c
blob5f319617b947b54fc4926f931a49ee54cff272f8
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2012 Daniel Borkmann <borkmann@iogearbox.net>
4 * Copyright 2012 Markus Amend <markus@netsniff-ng.org>
5 * Subject to the GPL, version 2.
6 */
8 #include <stdio.h>
9 #include <stdint.h>
10 #include <netinet/in.h> /* for ntohs() */
11 #include <asm/byteorder.h>
13 #include "proto.h"
14 #include "protos.h"
15 #include "dissector_80211.h"
16 #include "built_in.h"
17 #include "pkt_buff.h"
18 #include "oui.h"
20 /* Note: Fields are encoded in little-endian! */
21 struct ieee80211_frm_ctrl {
22 union {
23 u16 frame_control;
24 struct {
25 #if defined(__LITTLE_ENDIAN_BITFIELD)
26 /* Correct order here ... */
27 __extension__ u16 proto_version:2,
28 type:2,
29 subtype:4,
30 to_ds:1,
31 from_ds:1,
32 more_frags:1,
33 retry:1,
34 power_mgmt:1,
35 more_data:1,
36 wep:1,
37 order:1;
38 #elif defined(__BIG_ENDIAN_BITFIELD)
39 __extension__ u16 subtype:4,
40 type:2,
41 proto_version:2,
42 order:1,
43 wep:1,
44 more_data:1,
45 power_mgmt:1,
46 retry:1,
47 more_frags:1,
48 from_ds:1,
49 to_ds:1;
50 #else
51 # error "Adjust your <asm/byteorder.h> defines"
52 #endif
55 } __packed;
57 /* Management Frame start */
58 /* Note: Fields are encoded in little-endian! */
59 struct ieee80211_mgmt {
60 u16 duration;
61 u8 da[6];
62 u8 sa[6];
63 u8 bssid[6];
64 u16 seq_ctrl;
65 } __packed;
67 struct ieee80211_mgmt_auth {
68 u16 auth_alg;
69 u16 auth_transaction;
70 u16 status_code;
71 /* possibly followed by Challenge text */
72 u8 variable[0];
73 } __packed;
75 struct ieee80211_mgmt_deauth {
76 u16 reason_code;
77 } __packed;
79 struct ieee80211_mgmt_assoc_req {
80 u16 capab_info;
81 u16 listen_interval;
82 /* followed by SSID and Supported rates */
83 u8 variable[0];
84 } __packed;
86 struct ieee80211_mgmt_assoc_resp {
87 u16 capab_info;
88 u16 status_code;
89 u16 aid;
90 /* followed by Supported rates */
91 u8 variable[0];
92 } __packed;
94 struct ieee80211_mgmt_reassoc_resp {
95 u16 capab_info;
96 u16 status_code;
97 u16 aid;
98 /* followed by Supported rates */
99 u8 variable[0];
100 } __packed;
102 struct ieee80211_mgmt_reassoc_req {
103 u16 capab_info;
104 u16 listen_interval;
105 u8 current_ap[6];
106 /* followed by SSID and Supported rates */
107 u8 variable[0];
108 } __packed;
110 struct ieee80211_mgmt_disassoc {
111 u16 reason_code;
112 } __packed;
114 struct ieee80211_mgmt_probe_req {
115 } __packed;
117 struct ieee80211_mgmt_beacon {
118 u64 timestamp;
119 u16 beacon_int;
120 u16 capab_info;
121 /* followed by some of SSID, Supported rates,
122 * FH Params, DS Params, CF Params, IBSS Params, TIM */
123 u8 variable[0];
124 } __packed;
126 struct ieee80211_mgmt_probe_resp {
127 u8 timestamp[8];
128 u16 beacon_int;
129 u16 capab_info;
130 /* followed by some of SSID, Supported rates,
131 * FH Params, DS Params, CF Params, IBSS Params, TIM */
132 u8 variable[0];
133 } __packed;
134 /* Management Frame end */
136 /* Control Frame start */
137 /* Note: Fields are encoded in little-endian! */
138 struct ieee80211_ctrl {
139 } __packed;
141 struct ieee80211_ctrl_rts {
142 u16 duration;
143 u8 da[6];
144 u8 sa[6];
145 } __packed;
147 struct ieee80211_ctrl_cts {
148 u16 duration;
149 u8 da[6];
150 } __packed;
152 struct ieee80211_ctrl_ack {
153 u16 duration;
154 u8 da[6];
155 } __packed;
157 struct ieee80211_ctrl_ps_poll {
158 u16 aid;
159 u8 bssid[6];
160 u8 sa[6];
161 } __packed;
163 struct ieee80211_ctrl_cf_end {
164 u16 duration;
165 u8 bssid[6];
166 u8 sa[6];
167 } __packed;
169 struct ieee80211_ctrl_cf_end_ack {
170 u16 duration;
171 u8 bssid[6];
172 u8 sa[6];
173 } __packed;
174 /* Control Frame end */
176 /* Data Frame start */
177 /* Note: Fields are encoded in little-endian! */
178 struct ieee80211_data {
179 } __packed;
181 /* TODO: Extend */
182 /* Data Frame end */
185 /* http://www.sss-mag.com/pdf/802_11tut.pdf
186 * http://www.scribd.com/doc/78443651/111/Management-Frames
187 * http://www.wildpackets.com/resources/compendium/wireless_lan/wlan_packets
188 * http://www.rhyshaden.com/wireless.htm
191 struct element_reserved {
192 u8 len;
193 } __packed;
195 struct element_ssid {
196 u8 len;
197 u8 SSID[0];
198 } __packed;
200 struct element_supp_rates {
201 u8 len;
202 u8 SSID[0];
203 } __packed;
205 struct element_fh_ps {
206 u8 len;
207 u16 dwell_time;
208 u8 hop_set;
209 u8 hop_pattern;
210 u8 hop_index;
211 } __packed;
213 struct element_dsss_ps {
214 u8 len;
215 u8 curr_ch;
216 } __packed;
218 struct element_cf_ps {
219 u8 len;
220 u8 cfp_cnt;
221 u8 cfp_period;
222 u16 cfp_max_dur;
223 u16 cfp_dur_rem;
224 } __packed;
226 struct element_tim {
227 u8 len;
228 u8 dtim_cnt;
229 u8 dtim_period;
230 u8 bmp_cntrl;
231 u8 part_virt_bmp[0];
232 } __packed;
237 struct element_erp {
238 u8 len;
239 u8 param;
240 } __packed;
245 struct element_ext_supp_rates {
246 u8 len;
247 u8 rates[0];
248 } __packed;
251 struct element_vend_spec {
252 u8 len;
253 u8 oui[0];
254 u8 specific[0];
255 } __packed;
257 static float data_rates(u8 id) {
258 switch (id) {
259 case 2:
260 return 1;
261 case 3:
262 return 1.5;
263 case 4:
264 return 2;
265 case 5:
266 return 2.5;
267 case 6:
268 return 3;
269 case 9:
270 return 4.5;
271 case 11:
272 return 5.5;
273 case 12:
274 return 6;
275 case 18:
276 return 9;
277 case 22:
278 return 11;
279 case 24:
280 return 12;
281 case 27:
282 return 13.5;
283 case 36:
284 return 18;
285 case 44:
286 return 22;
287 case 48:
288 return 24;
289 case 54:
290 return 27;
291 case 66:
292 return 33;
293 case 72:
294 return 36;
295 case 96:
296 return 48;
297 case 108:
298 return 54;
301 return 0;
304 static int8_t inf_reserved(struct pkt_buff *pkt, u8 *id) {
305 struct element_reserved *reserved =
306 (struct element_reserved *) pkt_pull(pkt, sizeof(*reserved));
307 if (reserved == NULL)
308 return 0;
310 tprintf(" Reserved (%u, Len (%u)): ", *id, reserved->len);
312 if (!pkt_pull(pkt, reserved->len))
313 return 0;
315 return 1;
318 static int8_t inf_ssid(struct pkt_buff *pkt, u8 *id) {
319 struct element_ssid *ssid =
320 (struct element_ssid *) pkt_pull(pkt, sizeof(*ssid));
321 if (ssid == NULL)
322 return 0;
324 tprintf(" SSID (%u, Len (%u)): ", *id, ssid->len);
326 if (ssid->len) {
327 char *ssid_name = (char *) pkt_pull(pkt, ssid->len);
328 if (ssid_name == NULL)
329 return 0;
330 for(u8 i=0; i < ssid->len; i++)
331 tprintf("%c",ssid_name[i]);
333 else
334 tprintf("Wildcard SSID");
336 return 1;
339 static int8_t inf_supp_rates(struct pkt_buff *pkt, u8 *id) {
340 struct element_supp_rates *supp_rates =
341 (struct element_supp_rates *) pkt_pull(pkt, sizeof(*supp_rates));
342 if (supp_rates == NULL)
343 return 0;
345 tprintf("Rates (%u, Len (%u)): ", *id, supp_rates->len);
347 if (supp_rates->len) {
348 u8 *rates = pkt_pull(pkt, supp_rates->len);
349 if (rates == NULL)
350 return 0;
351 for(u8 i=0; i < supp_rates->len; i++)
352 tprintf("%g ",(rates[i] & 0x80) ? ((rates[i] & 0x3f) * 0.5) : data_rates(rates[i]));
354 else
355 return 0;
357 return 1;
360 static int8_t inf_fh_ps(struct pkt_buff *pkt, u8 *id) {
361 struct element_fh_ps *fh_ps =
362 (struct element_fh_ps *) pkt_pull(pkt, sizeof(*fh_ps));
363 if (fh_ps == NULL)
364 return 0;
366 tprintf("FH Param Set (%u, Len(%u)): ", *id, fh_ps->len);
367 tprintf("Dwell Time: %fs, ", le16_to_cpu(fh_ps->dwell_time) * 0.001024);
368 tprintf("HopSet: %u, ", fh_ps->hop_set);
369 tprintf("HopPattern: %u, ", fh_ps->hop_pattern);
370 tprintf("HopIndex: %u", fh_ps->hop_index);
372 return 1;
375 static int8_t inf_dsss_ps(struct pkt_buff *pkt, u8 *id) {
376 struct element_dsss_ps *dsss_ps =
377 (struct element_dsss_ps *) pkt_pull(pkt, sizeof(*dsss_ps));
378 if (dsss_ps == NULL)
379 return 0;
381 tprintf("DSSS Param Set (%u, Len(%u)): ", *id, dsss_ps->len);
382 tprintf("Current Channel: %u", dsss_ps->curr_ch);
384 return 1;
387 static int8_t inf_cf_ps(struct pkt_buff *pkt, u8 *id) {
388 struct element_cf_ps *cf_ps =
389 (struct element_cf_ps *) pkt_pull(pkt, sizeof(*cf_ps));
390 if (cf_ps == NULL)
391 return 0;
393 tprintf("CF Param Set (%u, Len(%u)): ", *id, cf_ps->len);
394 tprintf("CFP Count: %u, ", cf_ps->cfp_cnt);
395 tprintf("CFP Period: %u, ", cf_ps->cfp_period);
396 tprintf("CFP MaxDur: %fs, ", le16_to_cpu(cf_ps->cfp_max_dur) * 0.001024);
397 tprintf("CFP DurRem: %fs", le16_to_cpu(cf_ps->cfp_dur_rem) * 0.001024);
399 return 1;
402 static int8_t inf_tim(struct pkt_buff *pkt, u8 *id) {
403 struct element_tim *tim =
404 (struct element_tim *) pkt_pull(pkt, sizeof(*tim));
405 if (tim == NULL)
406 return 0;
408 tprintf("TIM (%u, Len(%u)): ", *id, tim->len);
409 tprintf("DTIM Count: %u, ", tim->dtim_cnt);
410 tprintf("DTIM Period: %u, ", tim->dtim_period);
411 tprintf("Bitmap Control: %u, ", tim->bmp_cntrl);
412 if ((tim->len - sizeof(*tim) + 1) > 0) {
413 u8 *bmp = pkt_pull(pkt, (tim->len - sizeof(*tim) + 1));
414 if (bmp == NULL)
415 return 0;
416 tprintf("Partial Virtual Bitmap: 0x");
417 for(u8 i=0; i < (tim->len - sizeof(*tim) + 1); i++)
418 tprintf("%.2x ", bmp[i]);
421 return 1;
424 static int8_t inf_ibss_ps(struct pkt_buff *pkt, u8 *id) {
425 return 1;
428 static int8_t inf_country(struct pkt_buff *pkt, u8 *id) {
429 return 1;
432 static int8_t inf_hop_pp(struct pkt_buff *pkt, u8 *id) {
433 return 1;
436 static int8_t inf_hop_pt(struct pkt_buff *pkt, u8 *id) {
437 return 1;
440 static int8_t inf_req(struct pkt_buff *pkt, u8 *id) {
441 return 1;
444 static int8_t inf_bss_load(struct pkt_buff *pkt, u8 *id) {
445 return 1;
448 static int8_t inf_edca_ps(struct pkt_buff *pkt, u8 *id) {
449 return 1;
452 static int8_t inf_tspec(struct pkt_buff *pkt, u8 *id) {
453 return 1;
456 static int8_t inf_tclas(struct pkt_buff *pkt, u8 *id) {
457 return 1;
460 static int8_t inf_sched(struct pkt_buff *pkt, u8 *id) {
461 return 1;
464 static int8_t inf_chall_txt(struct pkt_buff *pkt, u8 *id) {
465 return 1;
468 static int8_t inf_pwr_constr(struct pkt_buff *pkt, u8 *id) {
469 return 1;
472 static int8_t inf_pwr_cap(struct pkt_buff *pkt, u8 *id) {
473 return 1;
476 static int8_t inf_tpc_req(struct pkt_buff *pkt, u8 *id) {
477 return 1;
480 static int8_t inf_tpc_rep(struct pkt_buff *pkt, u8 *id) {
481 return 1;
484 static int8_t inf_supp_ch(struct pkt_buff *pkt, u8 *id) {
485 return 1;
488 static int8_t inf_ch_sw_ann(struct pkt_buff *pkt, u8 *id) {
489 return 1;
492 static int8_t inf_meas_req(struct pkt_buff *pkt, u8 *id) {
493 return 1;
496 static int8_t inf_meas_rep(struct pkt_buff *pkt, u8 *id) {
497 return 1;
500 static int8_t inf_quiet(struct pkt_buff *pkt, u8 *id) {
501 return 1;
504 static int8_t inf_ibss_dfs(struct pkt_buff *pkt, u8 *id) {
505 return 1;
508 static int8_t inf_erp(struct pkt_buff *pkt, u8 *id) {
509 struct element_erp *erp =
510 (struct element_erp *) pkt_pull(pkt, sizeof(*erp));
511 if (erp == NULL)
512 return 0;
514 tprintf("ERP (%u, Len(%u)): ", *id, erp->len);
515 tprintf("Non ERP Present (%u), ", erp->param & 0x1);
516 tprintf("Use Protection (%u), ", (erp->param >> 1) & 0x1);
517 tprintf("Barker Preamble Mode (%u), ", (erp->param >> 2) & 0x1);
518 tprintf("Reserved (0x%.5x)", erp->param >> 3);
520 return 1;
523 static int8_t inf_ts_del(struct pkt_buff *pkt, u8 *id) {
524 return 1;
527 static int8_t inf_tclas_proc(struct pkt_buff *pkt, u8 *id) {
528 return 1;
531 static int8_t inf_ht_cap(struct pkt_buff *pkt, u8 *id) {
532 return 1;
535 static int8_t inf_qos_cap(struct pkt_buff *pkt, u8 *id) {
536 return 1;
539 static int8_t inf_rsn(struct pkt_buff *pkt, u8 *id) {
540 return 1;
543 static int8_t inf_ext_supp_rates(struct pkt_buff *pkt, u8 *id) {
544 struct element_ext_supp_rates *ext_supp_rates =
545 (struct element_ext_supp_rates *) pkt_pull(pkt, sizeof(*ext_supp_rates));
546 if (ext_supp_rates == NULL)
547 return 0;
549 tprintf("Ext Support Rates (%u, Len(%u)): ", *id, ext_supp_rates->len);
551 if (ext_supp_rates->len) {
552 u8 *rates = pkt_pull(pkt, ext_supp_rates->len);
553 if (rates == NULL)
554 return 0;
555 for(u8 i=0; i < ext_supp_rates->len; i++)
556 tprintf("%g ",(rates[i] & 0x80) ? ((rates[i] & 0x3f) * 0.5) : data_rates(rates[i]));
558 else
559 return 0;
561 return 1;
564 static int8_t inf_ap_ch_exp(struct pkt_buff *pkt, u8 *id) {
565 return 1;
568 static int8_t inf_neighb_rep(struct pkt_buff *pkt, u8 *id) {
569 return 1;
572 static int8_t inf_rcpi(struct pkt_buff *pkt, u8 *id) {
573 return 1;
576 static int8_t inf_mde(struct pkt_buff *pkt, u8 *id) {
577 return 1;
580 static int8_t inf_fte(struct pkt_buff *pkt, u8 *id) {
581 return 1;
584 static int8_t inf_time_out_int(struct pkt_buff *pkt, u8 *id) {
585 return 1;
588 static int8_t inf_rde(struct pkt_buff *pkt, u8 *id) {
589 return 1;
592 static int8_t inf_dse_reg_loc(struct pkt_buff *pkt, u8 *id) {
593 return 1;
596 static int8_t inf_supp_op_class(struct pkt_buff *pkt, u8 *id) {
597 return 1;
600 static int8_t inf_ext_ch_sw_ann(struct pkt_buff *pkt, u8 *id) {
601 return 1;
604 static int8_t inf_ht_op(struct pkt_buff *pkt, u8 *id) {
605 return 1;
608 static int8_t inf_sec_ch_offs(struct pkt_buff *pkt, u8 *id) {
609 return 1;
612 static int8_t inf_bss_avg_acc_del(struct pkt_buff *pkt, u8 *id) {
613 return 1;
616 static int8_t inf_ant(struct pkt_buff *pkt, u8 *id) {
617 return 1;
620 static int8_t inf_rsni(struct pkt_buff *pkt, u8 *id) {
621 return 1;
624 static int8_t inf_meas_pilot_trans(struct pkt_buff *pkt, u8 *id) {
625 return 1;
628 static int8_t inf_bss_avl_adm_cap(struct pkt_buff *pkt, u8 *id) {
629 return 1;
632 static int8_t inf_bss_ac_acc_del(struct pkt_buff *pkt, u8 *id) {
633 return 1;
636 static int8_t inf_time_adv(struct pkt_buff *pkt, u8 *id) {
637 return 1;
640 static int8_t inf_rm_ena_cap(struct pkt_buff *pkt, u8 *id) {
641 return 1;
644 static int8_t inf_mult_bssid(struct pkt_buff *pkt, u8 *id) {
645 return 1;
648 static int8_t inf_20_40_bss_coex(struct pkt_buff *pkt, u8 *id) {
649 return 1;
652 static int8_t inf_20_40_bss_int_ch_rep(struct pkt_buff *pkt, u8 *id) {
653 return 1;
656 static int8_t inf_overl_bss_scan_para(struct pkt_buff *pkt, u8 *id) {
657 return 1;
660 static int8_t inf_ric_desc(struct pkt_buff *pkt, u8 *id) {
661 return 1;
664 static int8_t inf_mgmt_mic(struct pkt_buff *pkt, u8 *id) {
665 return 1;
668 static int8_t inf_ev_req(struct pkt_buff *pkt, u8 *id) {
669 return 1;
672 static int8_t inf_ev_rep(struct pkt_buff *pkt, u8 *id) {
673 return 1;
676 static int8_t inf_diagn_req(struct pkt_buff *pkt, u8 *id) {
677 return 1;
680 static int8_t inf_diagn_rep(struct pkt_buff *pkt, u8 *id) {
681 return 1;
684 static int8_t inf_loc_para(struct pkt_buff *pkt, u8 *id) {
685 return 1;
688 static int8_t inf_nontr_bssid_cap(struct pkt_buff *pkt, u8 *id) {
689 return 1;
692 static int8_t inf_ssid_list(struct pkt_buff *pkt, u8 *id) {
693 return 1;
696 static int8_t inf_mult_bssid_index(struct pkt_buff *pkt, u8 *id) {
697 return 1;
700 static int8_t inf_fms_desc(struct pkt_buff *pkt, u8 *id) {
701 return 1;
704 static int8_t inf_fms_req(struct pkt_buff *pkt, u8 *id) {
705 return 1;
708 static int8_t inf_fms_resp(struct pkt_buff *pkt, u8 *id) {
709 return 1;
712 static int8_t inf_qos_tfc_cap(struct pkt_buff *pkt, u8 *id) {
713 return 1;
716 static int8_t inf_bss_max_idle_per(struct pkt_buff *pkt, u8 *id) {
717 return 1;
720 static int8_t inf_tfs_req(struct pkt_buff *pkt, u8 *id) {
721 return 1;
724 static int8_t inf_tfs_resp(struct pkt_buff *pkt, u8 *id) {
725 return 1;
728 static int8_t inf_wnm_sleep_mod(struct pkt_buff *pkt, u8 *id) {
729 return 1;
732 static int8_t inf_tim_bcst_req(struct pkt_buff *pkt, u8 *id) {
733 return 1;
736 static int8_t inf_tim_bcst_resp(struct pkt_buff *pkt, u8 *id) {
737 return 1;
740 static int8_t inf_coll_interf_rep(struct pkt_buff *pkt, u8 *id) {
741 return 1;
744 static int8_t inf_ch_usage(struct pkt_buff *pkt, u8 *id) {
745 return 1;
748 static int8_t inf_time_zone(struct pkt_buff *pkt, u8 *id) {
749 return 1;
752 static int8_t inf_dms_req(struct pkt_buff *pkt, u8 *id) {
753 return 1;
756 static int8_t inf_dms_resp(struct pkt_buff *pkt, u8 *id) {
757 return 1;
760 static int8_t inf_link_id(struct pkt_buff *pkt, u8 *id) {
761 return 1;
764 static int8_t inf_wakeup_sched(struct pkt_buff *pkt, u8 *id) {
765 return 1;
768 static int8_t inf_ch_sw_timing(struct pkt_buff *pkt, u8 *id) {
769 return 1;
772 static int8_t inf_pti_ctrl(struct pkt_buff *pkt, u8 *id) {
773 return 1;
776 static int8_t inf_tpu_buff_status(struct pkt_buff *pkt, u8 *id) {
777 return 1;
780 static int8_t inf_interw(struct pkt_buff *pkt, u8 *id) {
781 return 1;
784 static int8_t inf_adv_proto(struct pkt_buff *pkt, u8 *id) {
785 return 1;
788 static int8_t inf_exp_bandw_req(struct pkt_buff *pkt, u8 *id) {
789 return 1;
792 static int8_t inf_qos_map_set(struct pkt_buff *pkt, u8 *id) {
793 return 1;
796 static int8_t inf_roam_cons(struct pkt_buff *pkt, u8 *id) {
797 return 1;
800 static int8_t inf_emer_alert_id(struct pkt_buff *pkt, u8 *id) {
801 return 1;
804 static int8_t inf_mesh_conf(struct pkt_buff *pkt, u8 *id) {
805 return 1;
808 static int8_t inf_mesh_id(struct pkt_buff *pkt, u8 *id) {
809 return 1;
812 static int8_t inf_mesh_link_metr_rep(struct pkt_buff *pkt, u8 *id) {
813 return 1;
816 static int8_t inf_cong_notif(struct pkt_buff *pkt, u8 *id) {
817 return 1;
820 static int8_t inf_mesh_peer_mgmt(struct pkt_buff *pkt, u8 *id) {
821 return 1;
824 static int8_t inf_mesh_ch_sw_para(struct pkt_buff *pkt, u8 *id) {
825 return 1;
828 static int8_t inf_mesh_awake_win(struct pkt_buff *pkt, u8 *id) {
829 return 1;
832 static int8_t inf_beacon_timing(struct pkt_buff *pkt, u8 *id) {
833 return 1;
836 static int8_t inf_mccaop_setup_req(struct pkt_buff *pkt, u8 *id) {
837 return 1;
840 static int8_t inf_mccaop_setup_rep(struct pkt_buff *pkt, u8 *id) {
841 return 1;
844 static int8_t inf_mccaop_adv(struct pkt_buff *pkt, u8 *id) {
845 return 1;
848 static int8_t inf_mccaop_teardwn(struct pkt_buff *pkt, u8 *id) {
849 return 1;
852 static int8_t inf_gann(struct pkt_buff *pkt, u8 *id) {
853 return 1;
856 static int8_t inf_rann(struct pkt_buff *pkt, u8 *id) {
857 return 1;
860 static int8_t inf_ext_cap(struct pkt_buff *pkt, u8 *id) {
861 return 1;
864 static int8_t inf_preq(struct pkt_buff *pkt, u8 *id) {
865 return 1;
868 static int8_t inf_prep(struct pkt_buff *pkt, u8 *id) {
869 return 1;
872 static int8_t inf_perr(struct pkt_buff *pkt, u8 *id) {
873 return 1;
876 static int8_t inf_pxu(struct pkt_buff *pkt, u8 *id) {
877 return 1;
880 static int8_t inf_pxuc(struct pkt_buff *pkt, u8 *id) {
881 return 1;
884 static int8_t inf_auth_mesh_peer_exch(struct pkt_buff *pkt, u8 *id) {
885 return 1;
888 static int8_t inf_mic(struct pkt_buff *pkt, u8 *id) {
889 return 1;
892 static int8_t inf_dest_uri(struct pkt_buff *pkt, u8 *id) {
893 return 1;
896 static int8_t inf_u_apsd_coex(struct pkt_buff *pkt, u8 *id) {
897 return 1;
900 static int8_t inf_mccaop_adv_overv(struct pkt_buff *pkt, u8 *id) {
901 return 1;
904 static int8_t inf_vend_spec(struct pkt_buff *pkt, u8 *id) {
905 struct element_vend_spec *vend_spec =
906 (struct element_vend_spec *) pkt_pull(pkt, sizeof(*vend_spec));
907 if (vend_spec == NULL)
908 return 0;
910 tprintf("Vendor Specific (%u, Len (%u)): ", *id, vend_spec->len);
912 u8 *data = pkt_pull(pkt, vend_spec->len);
913 if (data == NULL)
914 return 0;
916 tprintf("Data 0x");
917 for(u8 i=0; i < vend_spec->len; i++)
918 tprintf("%.2x", data[i]);
920 return 1;
923 static int8_t inf_elements(struct pkt_buff *pkt) {
924 u8 *id = pkt_pull(pkt, 1);
926 if (id == NULL)
927 return 0;
929 switch (*id) {
930 case 0:
931 return inf_ssid(pkt, id);
932 case 1:
933 return inf_supp_rates(pkt, id);
934 case 2:
935 return inf_fh_ps(pkt, id);
936 case 3:
937 return inf_dsss_ps(pkt, id);
938 case 4:
939 return inf_cf_ps(pkt, id);
940 case 5:
941 return inf_tim(pkt, id);
942 case 6:
943 return inf_ibss_ps(pkt, id);
944 case 7:
945 return inf_country(pkt, id);
946 case 8:
947 return inf_hop_pp(pkt, id);
948 case 9:
949 return inf_hop_pt(pkt, id);
950 case 10:
951 return inf_req(pkt, id);
952 case 11:
953 return inf_bss_load(pkt, id);
954 case 12:
955 return inf_edca_ps(pkt, id);
956 case 13:
957 return inf_tspec(pkt, id);
958 case 14:
959 return inf_tclas(pkt, id);
960 case 15:
961 return inf_sched(pkt, id);
962 case 16:
963 return inf_chall_txt(pkt, id);
964 case 32:
965 return inf_pwr_constr(pkt, id);
966 case 33:
967 return inf_pwr_cap(pkt, id);
968 case 34:
969 return inf_tpc_req(pkt, id);
970 case 35:
971 return inf_tpc_rep(pkt, id);
972 case 36:
973 return inf_supp_ch(pkt, id);
974 case 37:
975 return inf_ch_sw_ann(pkt, id);
976 case 38:
977 return inf_meas_req(pkt, id);
978 case 39:
979 return inf_meas_rep(pkt, id);
980 case 40:
981 return inf_quiet(pkt, id);
982 case 41:
983 return inf_ibss_dfs(pkt, id);
984 case 42:
985 return inf_erp(pkt, id);
986 case 43:
987 return inf_ts_del(pkt, id);
988 case 44:
989 return inf_tclas_proc(pkt, id);
990 case 45:
991 return inf_ht_cap(pkt, id);
992 case 46:
993 return inf_qos_cap(pkt, id);
994 case 47:
995 return inf_reserved(pkt, id);
996 case 48:
997 return inf_rsn(pkt, id);
998 case 49:
999 return inf_rsn(pkt, id);
1000 case 50:
1001 return inf_ext_supp_rates(pkt, id);
1002 case 51:
1003 return inf_ap_ch_exp(pkt, id);
1004 case 52:
1005 return inf_neighb_rep(pkt, id);
1006 case 53:
1007 return inf_rcpi(pkt, id);
1008 case 54:
1009 return inf_mde(pkt, id);
1010 case 55:
1011 return inf_fte(pkt, id);
1012 case 56:
1013 return inf_time_out_int(pkt, id);
1014 case 57:
1015 return inf_rde(pkt, id);
1016 case 58:
1017 return inf_dse_reg_loc(pkt, id);
1018 case 59:
1019 return inf_supp_op_class(pkt, id);
1020 case 60:
1021 return inf_ext_ch_sw_ann(pkt, id);
1022 case 61:
1023 return inf_ht_op(pkt, id);
1024 case 62:
1025 return inf_sec_ch_offs(pkt, id);
1026 case 63:
1027 return inf_bss_avg_acc_del(pkt, id);
1028 case 64:
1029 return inf_ant(pkt, id);
1030 case 65:
1031 return inf_rsni(pkt, id);
1032 case 66:
1033 return inf_meas_pilot_trans(pkt, id);
1034 case 67:
1035 return inf_bss_avl_adm_cap(pkt, id);
1036 case 68:
1037 return inf_bss_ac_acc_del(pkt, id);
1038 case 69:
1039 return inf_time_adv(pkt, id);
1040 case 70:
1041 return inf_rm_ena_cap(pkt, id);
1042 case 71:
1043 return inf_mult_bssid(pkt, id);
1044 case 72:
1045 return inf_20_40_bss_coex(pkt, id);
1046 case 73:
1047 return inf_20_40_bss_int_ch_rep(pkt, id);
1048 case 74:
1049 return inf_overl_bss_scan_para(pkt, id);
1050 case 75:
1051 return inf_ric_desc(pkt, id);
1052 case 76:
1053 return inf_mgmt_mic(pkt, id);
1054 case 78:
1055 return inf_ev_req(pkt, id);
1056 case 79:
1057 return inf_ev_rep(pkt, id);
1058 case 80:
1059 return inf_diagn_req(pkt, id);
1060 case 81:
1061 return inf_diagn_rep(pkt, id);
1062 case 82:
1063 return inf_loc_para(pkt, id);
1064 case 83:
1065 return inf_nontr_bssid_cap(pkt, id);
1066 case 84:
1067 return inf_ssid_list(pkt, id);
1068 case 85:
1069 return inf_mult_bssid_index(pkt, id);
1070 case 86:
1071 return inf_fms_desc(pkt, id);
1072 case 87:
1073 return inf_fms_req(pkt, id);
1074 case 88:
1075 return inf_fms_resp(pkt, id);
1076 case 89:
1077 return inf_qos_tfc_cap(pkt, id);
1078 case 90:
1079 return inf_bss_max_idle_per(pkt, id);
1080 case 91:
1081 return inf_tfs_req(pkt, id);
1082 case 92:
1083 return inf_tfs_resp(pkt, id);
1084 case 93:
1085 return inf_wnm_sleep_mod(pkt, id);
1086 case 94:
1087 return inf_tim_bcst_req(pkt, id);
1088 case 95:
1089 return inf_tim_bcst_resp(pkt, id);
1090 case 96:
1091 return inf_coll_interf_rep(pkt, id);
1092 case 97:
1093 return inf_ch_usage(pkt, id);
1094 case 98:
1095 return inf_time_zone(pkt, id);
1096 case 99:
1097 return inf_dms_req(pkt, id);
1098 case 100:
1099 return inf_dms_resp(pkt, id);
1100 case 101:
1101 return inf_link_id(pkt, id);
1102 case 102:
1103 return inf_wakeup_sched(pkt, id);
1104 case 104:
1105 return inf_ch_sw_timing(pkt, id);
1106 case 105:
1107 return inf_pti_ctrl(pkt, id);
1108 case 106:
1109 return inf_tpu_buff_status(pkt, id);
1110 case 107:
1111 return inf_interw(pkt, id);
1112 case 108:
1113 return inf_adv_proto(pkt, id);
1114 case 109:
1115 return inf_exp_bandw_req(pkt, id);
1116 case 110:
1117 return inf_qos_map_set(pkt, id);
1118 case 111:
1119 return inf_roam_cons(pkt, id);
1120 case 112:
1121 return inf_emer_alert_id(pkt, id);
1122 case 113:
1123 return inf_mesh_conf(pkt, id);
1124 case 114:
1125 return inf_mesh_id(pkt, id);
1126 case 115:
1127 return inf_mesh_link_metr_rep(pkt, id);
1128 case 116:
1129 return inf_cong_notif(pkt, id);
1130 case 117:
1131 return inf_mesh_peer_mgmt(pkt, id);
1132 case 118:
1133 return inf_mesh_ch_sw_para(pkt, id);
1134 case 119:
1135 return inf_mesh_awake_win(pkt, id);
1136 case 120:
1137 return inf_beacon_timing(pkt, id);
1138 case 121:
1139 return inf_mccaop_setup_req(pkt, id);
1140 case 122:
1141 return inf_mccaop_setup_rep(pkt, id);
1142 case 123:
1143 return inf_mccaop_adv(pkt, id);
1144 case 124:
1145 return inf_mccaop_teardwn(pkt, id);
1146 case 125:
1147 return inf_gann(pkt, id);
1148 case 126:
1149 return inf_rann(pkt, id);
1150 case 127:
1151 return inf_ext_cap(pkt, id);
1152 case 128:
1153 return inf_reserved(pkt, id);
1154 case 129:
1155 return inf_reserved(pkt, id);
1156 case 130:
1157 return inf_preq(pkt, id);
1158 case 131:
1159 return inf_prep(pkt, id);
1160 case 132:
1161 return inf_perr(pkt, id);
1162 case 133:
1163 return inf_reserved(pkt, id);
1164 case 134:
1165 return inf_reserved(pkt, id);
1166 case 135:
1167 return inf_reserved(pkt, id);
1168 case 136:
1169 return inf_reserved(pkt, id);
1170 case 137:
1171 return inf_pxu(pkt, id);
1172 case 138:
1173 return inf_pxuc(pkt, id);
1174 case 139:
1175 return inf_auth_mesh_peer_exch(pkt, id);
1176 case 140:
1177 return inf_mic(pkt, id);
1178 case 141:
1179 return inf_dest_uri(pkt, id);
1180 case 142:
1181 return inf_u_apsd_coex(pkt, id);
1182 case 174:
1183 return inf_mccaop_adv_overv(pkt, id);
1184 case 221:
1185 return inf_vend_spec(pkt, id);
1188 if((*id >= 17 && *id <= 31) || (*id >= 143 && *id <= 173))
1189 return inf_reserved(pkt, id);
1191 return 0;
1194 static int8_t cap_field(u16 cap_inf) {
1196 #define ESS 0b0000000000000001
1197 #define IBSS 0b0000000000000010
1198 #define CF_Pollable 0b0000000000000100
1199 #define CF_Poll_Req 0b0000000000001000
1200 #define Privacy 0b0000000000010000
1201 #define Short_Pre 0b0000000000100000
1202 #define PBCC 0b0000000001000000
1203 #define Ch_Agility 0b0000000010000000
1204 #define Spec_Mgmt 0b0000000100000000
1205 #define QoS 0b0000001000000000
1206 #define Short_Slot_t 0b0000010000000000
1207 #define APSD 0b0000100000000000
1208 #define Radio_Meas 0b0001000000000000
1209 #define DSSS_OFDM 0b0010000000000000
1210 #define Del_Block_ACK 0b0100000000000000
1211 #define Imm_Block_ACK 0b1000000000000000
1213 if(ESS & cap_inf)
1214 tprintf(" ESS;");
1215 if(IBSS & cap_inf)
1216 tprintf(" IBSS;");
1217 if(CF_Pollable & cap_inf)
1218 tprintf(" CF Pollable;");
1219 if(CF_Poll_Req & cap_inf)
1220 tprintf(" CF-Poll Request;");
1221 if(Privacy & cap_inf)
1222 tprintf(" Privacy;");
1223 if(Short_Pre & cap_inf)
1224 tprintf(" Short Preamble;");
1225 if(PBCC & cap_inf)
1226 tprintf(" PBCC;");
1227 if(Ch_Agility & cap_inf)
1228 tprintf(" Channel Agility;");
1229 if(Spec_Mgmt & cap_inf)
1230 tprintf(" Spectrum Management;");
1231 if(QoS & cap_inf)
1232 tprintf(" QoS;");
1233 if(Short_Slot_t & cap_inf)
1234 tprintf(" Short Slot Time;");
1235 if(APSD & cap_inf)
1236 tprintf(" APSD;");
1237 if(Radio_Meas & cap_inf)
1238 tprintf(" Radio Measurement;");
1239 if(DSSS_OFDM & cap_inf)
1240 tprintf(" DSSS-OFDM;");
1241 if(Del_Block_ACK & cap_inf)
1242 tprintf(" Delayed Block Ack;");
1243 if(Imm_Block_ACK & cap_inf)
1244 tprintf(" Immediate Block Ack;");
1246 return 1;
1249 /* Management Dissectors */
1250 static int8_t assoc_req(struct pkt_buff *pkt) {
1251 return 0;
1254 static int8_t assoc_resp(struct pkt_buff *pkt) {
1255 return 0;
1258 static int8_t reassoc_req(struct pkt_buff *pkt) {
1259 return 0;
1262 static int8_t reassoc_resp(struct pkt_buff *pkt) {
1263 return 0;
1266 static int8_t probe_req(struct pkt_buff *pkt) {
1267 return 0;
1270 static int8_t probe_resp(struct pkt_buff *pkt) {
1271 return 0;
1274 static int8_t beacon(struct pkt_buff *pkt) {
1275 struct ieee80211_mgmt_beacon *beacon =
1276 (struct ieee80211_mgmt_beacon *) pkt_pull(pkt, sizeof(*beacon));
1277 if (beacon == NULL)
1278 return 0;
1279 tprintf("Timestamp 0x%.16lx, ", le64_to_cpu(beacon->timestamp));
1280 tprintf("Beacon Interval (%fs), ",
1281 le16_to_cpu(beacon->beacon_int) * 0.001024);
1282 tprintf("Capabilities (0x%x <->",
1283 le16_to_cpu(beacon->capab_info));
1284 cap_field(le16_to_cpu(beacon->capab_info));
1285 tprintf(")");
1287 if(pkt_len(pkt)) {
1288 tprintf("\n\tParameters:");
1289 while (inf_elements(pkt)) {
1290 tprintf("\n\t");
1294 if(pkt_len(pkt))
1295 return 0;
1297 return 1;
1300 static int8_t atim(struct pkt_buff *pkt) {
1301 return 0;
1304 static int8_t disassoc(struct pkt_buff *pkt) {
1305 return 0;
1308 static int8_t auth(struct pkt_buff *pkt) {
1309 return 0;
1312 static int8_t deauth(struct pkt_buff *pkt) {
1313 return 0;
1315 /* End Management Dissectors */
1317 /* Control Dissectors */
1318 static int8_t ps_poll(struct pkt_buff *pkt) {
1319 return 0;
1322 static int8_t rts(struct pkt_buff *pkt) {
1323 return 0;
1326 static int8_t cts(struct pkt_buff *pkt) {
1327 return 0;
1330 static int8_t ack(struct pkt_buff *pkt) {
1331 return 0;
1334 static int8_t cf_end(struct pkt_buff *pkt) {
1335 return 0;
1338 static int8_t cf_end_ack(struct pkt_buff *pkt) {
1339 return 0;
1341 /* End Control Dissectors */
1343 /* Data Dissectors */
1344 static int8_t data(struct pkt_buff *pkt) {
1345 return 0;
1348 static int8_t data_cf_ack(struct pkt_buff *pkt) {
1349 return 0;
1352 static int8_t data_cf_poll(struct pkt_buff *pkt) {
1353 return 0;
1356 static int8_t data_cf_ack_poll(struct pkt_buff *pkt) {
1357 return 0;
1360 static int8_t null(struct pkt_buff *pkt) {
1361 return 0;
1364 static int8_t cf_ack(struct pkt_buff *pkt) {
1365 return 0;
1368 static int8_t cf_poll(struct pkt_buff *pkt) {
1369 return 0;
1372 static int8_t cf_ack_poll(struct pkt_buff *pkt) {
1373 return 0;
1375 /* End Data Dissectors */
1377 static char *mgt_sub(u8 subtype, struct pkt_buff *pkt, int8_t (**get_content)(struct pkt_buff *pkt)) {
1379 struct ieee80211_mgmt *mgmt =
1380 (struct ieee80211_mgmt *) pkt_pull(pkt, sizeof(*mgmt));
1381 if (mgmt == NULL)
1382 return 0;
1384 const char *dst = lookup_vendor((mgmt->da[0] << 16) | (mgmt->da[1] << 8) | mgmt->da[2]);
1385 const char *src = lookup_vendor((mgmt->sa[0] << 16) | (mgmt->sa[1] << 8) | mgmt->sa[2]);
1386 const char *bssid = lookup_vendor((mgmt->bssid[0] << 16) | (mgmt->bssid[1] << 8) | mgmt->bssid[2]);
1387 u16 seq_ctrl = le16_to_cpu(mgmt->seq_ctrl);
1389 tprintf("Duration (%u),", le16_to_cpu(mgmt->duration));
1390 tprintf("\n\tDestination (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1391 mgmt->da[0], mgmt->da[1], mgmt->da[2], mgmt->da[3], mgmt->da[4], mgmt->da[5]);
1392 if(dst)
1393 tprintf("=> (%s:%.2x:%.2x:%.2x)", dst, mgmt->da[3], mgmt->da[4], mgmt->da[5]);
1394 tprintf("\n\tSource (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1395 mgmt->sa[0], mgmt->sa[1], mgmt->sa[2], mgmt->sa[3], mgmt->sa[4], mgmt->sa[5]);
1396 if(src)
1397 tprintf("=> (%s:%.2x:%.2x:%.2x)", src, mgmt->sa[3], mgmt->sa[4], mgmt->sa[5]);
1398 tprintf("\n\tBSSID (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x) ",
1399 mgmt->bssid[0], mgmt->bssid[1], mgmt->bssid[2], mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5]);
1400 if(bssid)
1401 tprintf("=> (%s:%.2x:%.2x:%.2x)", bssid, mgmt->bssid[3], mgmt->bssid[4], mgmt->bssid[5]);
1402 tprintf("\n\tFragmentnr. (%u), Seqnr. (%u). ", seq_ctrl & 0xf, seq_ctrl >> 4);
1404 switch (subtype) {
1405 case 0b0000:
1406 *get_content = assoc_req;
1407 return "Association Request";
1408 case 0b0001:
1409 *get_content = assoc_resp;
1410 return "Association Response";
1411 case 0b0010:
1412 *get_content = reassoc_req;
1413 return "Reassociation Request";
1414 case 0b0011:
1415 *get_content = reassoc_resp;
1416 return "Reassociation Response";
1417 case 0b0100:
1418 *get_content = probe_req;
1419 return "Probe Request";
1420 case 0b0101:
1421 *get_content = probe_resp;
1422 return "Probe Response";
1423 case 0b1000:
1424 *get_content = beacon;
1425 return "Beacon";
1426 case 0b1001:
1427 *get_content = atim;
1428 return "ATIM";
1429 case 0b1010:
1430 *get_content = disassoc;
1431 return "Disassociation";
1432 case 0b1011:
1433 *get_content = auth;
1434 return "Authentication";
1435 case 0b1100:
1436 *get_content = deauth;
1437 return "Deauthentication";
1440 if ((subtype >= 0b0110 && subtype <= 0b0111) || (subtype >= 0b1101 && subtype <= 0b1111))
1441 return "Reserved";
1443 return "Management SubType not supported";
1446 static char *ctrl_sub(u8 subtype, struct pkt_buff *pkt, int8_t (**get_content)(struct pkt_buff *pkt)) {
1448 switch (subtype) {
1449 case 0b1010:
1450 *get_content = ps_poll;
1451 return "PS-Poll";
1452 case 0b1011:
1453 *get_content = rts;
1454 return "RTS";
1455 case 0b1100:
1456 *get_content = cts;
1457 return "CTS";
1458 case 0b1101:
1459 *get_content = ack;
1460 return "ACK";
1461 case 0b1110:
1462 *get_content = cf_end;
1463 return "CF End";
1464 case 0b1111:
1465 *get_content = cf_end_ack;
1466 return "CF End + CF-ACK";
1469 if (subtype <= 0b1001)
1470 return "Reserved";
1472 return "Control SubType not supported";
1475 static char *data_sub(u8 subtype, struct pkt_buff *pkt, int8_t (**get_content)(struct pkt_buff *pkt)) {
1477 switch (subtype) {
1478 case 0b0000:
1479 *get_content = data;
1480 return "Data";
1481 case 0b0001:
1482 *get_content = data_cf_ack;
1483 return "Data + CF-ACK";
1484 case 0b0010:
1485 *get_content = data_cf_poll;
1486 return "Data + CF-Poll";
1487 case 0b0011:
1488 *get_content = data_cf_ack_poll;
1489 return "Data + CF-ACK + CF-Poll";
1490 case 0b0100:
1491 *get_content = null;
1492 return "Null";
1493 case 0b0101:
1494 *get_content = cf_ack;
1495 return "CF-ACK";
1496 case 0b0110:
1497 *get_content = cf_poll;
1498 return "CF-Poll";
1499 case 0b0111:
1500 *get_content = cf_ack_poll;
1501 return "CF-ACK + CF-Poll";
1504 if (subtype >= 0b1000 && subtype <= 0b1111)
1505 return "Reserved";
1507 return "Data SubType not supported";
1510 static char *frame_control_type(u8 type, char *(**get_subtype)(u8 subtype, struct pkt_buff *pkt, int8_t (**get_content)(struct pkt_buff *pkt))) {
1511 switch (type) {
1512 case 0b00:
1513 *get_subtype = mgt_sub;
1514 return "Management";
1515 case 0b01:
1516 *get_subtype = ctrl_sub;
1517 return "Control";
1518 case 0b10:
1519 *get_subtype = data_sub;
1520 return "Data";
1521 case 0b11: return "Reserved";
1524 return "Control Type not supported";
1528 static void ieee80211(struct pkt_buff *pkt)
1530 int8_t (*get_content)(struct pkt_buff *pkt) = NULL;
1531 char *(*get_subtype)(u8 subtype, struct pkt_buff *pkt, int8_t (**get_content)(struct pkt_buff *pkt)) = NULL;
1532 char *subtype = NULL;
1534 struct ieee80211_frm_ctrl *frm_ctrl =
1535 (struct ieee80211_frm_ctrl *) pkt_pull(pkt, sizeof(*frm_ctrl));
1536 if (frm_ctrl == NULL)
1537 return;
1539 tprintf(" [ 802.11 Frame Control (0x%04x)]\n",
1540 le16_to_cpu(frm_ctrl->frame_control));
1541 tprintf("\t [ Proto Version (%u), ", frm_ctrl->proto_version);
1542 tprintf("Type (%u, %s), ", frm_ctrl->type, frame_control_type(frm_ctrl->type, &get_subtype));
1543 if (get_subtype) {
1544 subtype = (*get_subtype)(frm_ctrl->subtype, pkt, &get_content);
1545 tprintf("Subtype (%u, %s)", frm_ctrl->subtype, subtype);
1547 else
1548 tprintf("\n%s%s%s", colorize_start_full(black, red),
1549 "No SubType Data available", colorize_end());
1550 tprintf("%s%s",
1551 frm_ctrl->to_ds ? ", Frame goes to DS" : "",
1552 frm_ctrl->from_ds ? ", Frame comes from DS" : "");
1553 tprintf("%s", frm_ctrl->more_frags ? ", More Fragments" : "");
1554 tprintf("%s", frm_ctrl->retry ? ", Frame is retransmitted" : "");
1555 tprintf("%s", frm_ctrl->power_mgmt ? ", In Power Saving Mode" : "");
1556 tprintf("%s", frm_ctrl->more_data ? ", More Data" : "");
1557 tprintf("%s", frm_ctrl->wep ? ", Needs WEP" : "");
1558 tprintf("%s", frm_ctrl->order ? ", Order" : "");
1559 tprintf(" ]\n");
1561 if (get_content) {
1562 tprintf(" [ Subtype %s: ", subtype);
1563 if (!((*get_content) (pkt)))
1564 tprintf("\n%s%s%s", colorize_start_full(black, red),
1565 "Failed to dissect Subtype", colorize_end());
1566 tprintf(" ]");
1568 else
1569 tprintf("\n%s%s%s", colorize_start_full(black, red),
1570 "No SubType Data available", colorize_end());
1572 // pkt_set_proto(pkt, &ieee802_lay2, ntohs(eth->h_proto));
1575 static void ieee80211_less(struct pkt_buff *pkt)
1577 tprintf("802.11 frame (more on todo)");
1580 struct protocol ieee80211_ops = {
1581 .key = 0,
1582 .print_full = ieee80211,
1583 .print_less = ieee80211_less,
1586 EXPORT_SYMBOL(ieee80211_ops);