2 * Copyright (c) 2001 Atsushi Onoe
3 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #ifndef _NET80211_IEEE80211_PROTO_H_
29 #define _NET80211_IEEE80211_PROTO_H_
32 * 802.11 protocol implementation definitions.
35 enum ieee80211_state
{
36 IEEE80211_S_INIT
= 0, /* default state */
37 IEEE80211_S_SCAN
= 1, /* scanning */
38 IEEE80211_S_AUTH
= 2, /* try to authenticate */
39 IEEE80211_S_ASSOC
= 3, /* try to assoc */
40 IEEE80211_S_CAC
= 4, /* doing channel availability check */
41 IEEE80211_S_RUN
= 5, /* operational (e.g. associated) */
42 IEEE80211_S_CSA
= 6, /* channel switch announce pending */
43 IEEE80211_S_SLEEP
= 7, /* power save */
45 #define IEEE80211_S_MAX (IEEE80211_S_SLEEP+1)
47 #define IEEE80211_SEND_MGMT(_ni,_type,_arg) \
48 ((*(_ni)->ni_ic->ic_send_mgmt)(_ni, _type, _arg))
50 extern const char *mgt_subtype_name
[];
51 extern const char *ctl_subtype_name
[];
52 extern const char *ieee80211_phymode_name
[IEEE80211_MODE_MAX
];
53 extern const int ieee80211_opcap
[IEEE80211_OPMODE_MAX
];
55 static __inline
const char *
56 ieee80211_mgt_subtype_name(uint8_t subtype
)
58 return mgt_subtype_name
[(subtype
& IEEE80211_FC0_SUBTYPE_MASK
) >>
59 IEEE80211_FC0_SUBTYPE_SHIFT
];
62 static __inline
const char *
63 ieee80211_ctl_subtype_name(uint8_t subtype
)
65 return ctl_subtype_name
[(subtype
& IEEE80211_FC0_SUBTYPE_MASK
) >>
66 IEEE80211_FC0_SUBTYPE_SHIFT
];
69 const char *ieee80211_reason_to_string(uint16_t);
71 void ieee80211_proto_attach(struct ieee80211com
*);
72 void ieee80211_proto_detach(struct ieee80211com
*);
73 void ieee80211_proto_vattach(struct ieee80211vap
*);
74 void ieee80211_proto_vdetach(struct ieee80211vap
*);
76 void ieee80211_promisc(struct ieee80211vap
*, bool);
77 void ieee80211_allmulti(struct ieee80211vap
*, bool);
78 void ieee80211_syncflag(struct ieee80211vap
*, int flag
);
79 void ieee80211_syncflag_ht(struct ieee80211vap
*, int flag
);
80 void ieee80211_syncflag_ext(struct ieee80211vap
*, int flag
);
82 #define ieee80211_input(ni, m, rssi, nf) \
83 ((ni)->ni_vap->iv_input(ni, m, NULL, rssi, nf))
84 int ieee80211_input_all(struct ieee80211com
*, struct mbuf
*, int, int);
86 int ieee80211_input_mimo(struct ieee80211_node
*, struct mbuf
*,
87 struct ieee80211_rx_stats
*);
88 int ieee80211_input_mimo_all(struct ieee80211com
*, struct mbuf
*,
89 struct ieee80211_rx_stats
*);
91 struct ieee80211_bpf_params
;
92 int ieee80211_mgmt_output(struct ieee80211_node
*, struct mbuf
*, int,
93 struct ieee80211_bpf_params
*);
94 int ieee80211_raw_xmit(struct ieee80211_node
*, struct mbuf
*,
95 const struct ieee80211_bpf_params
*);
96 int ieee80211_output(struct ifnet
*, struct mbuf
*,
97 const struct sockaddr
*, struct route
*ro
);
98 int ieee80211_vap_pkt_send_dest(struct ieee80211vap
*, struct mbuf
*,
99 struct ieee80211_node
*);
100 int ieee80211_raw_output(struct ieee80211vap
*, struct ieee80211_node
*,
101 struct mbuf
*, const struct ieee80211_bpf_params
*);
102 void ieee80211_send_setup(struct ieee80211_node
*, struct mbuf
*, int, int,
103 const uint8_t [IEEE80211_ADDR_LEN
], const uint8_t [IEEE80211_ADDR_LEN
],
104 const uint8_t [IEEE80211_ADDR_LEN
]);
105 int ieee80211_vap_transmit(struct ifnet
*ifp
, struct mbuf
*m
);
106 void ieee80211_vap_qflush(struct ifnet
*ifp
);
107 int ieee80211_send_nulldata(struct ieee80211_node
*);
108 int ieee80211_classify(struct ieee80211_node
*, struct mbuf
*m
);
109 struct mbuf
*ieee80211_mbuf_adjust(struct ieee80211vap
*, int,
110 struct ieee80211_key
*, struct mbuf
*);
111 struct mbuf
*ieee80211_encap(struct ieee80211vap
*, struct ieee80211_node
*,
113 void ieee80211_free_mbuf(struct mbuf
*);
114 int ieee80211_send_mgmt(struct ieee80211_node
*, int, int);
115 struct ieee80211_appie
;
116 int ieee80211_send_probereq(struct ieee80211_node
*ni
,
117 const uint8_t sa
[IEEE80211_ADDR_LEN
],
118 const uint8_t da
[IEEE80211_ADDR_LEN
],
119 const uint8_t bssid
[IEEE80211_ADDR_LEN
],
120 const uint8_t *ssid
, size_t ssidlen
);
121 struct mbuf
* ieee80211_ff_encap1(struct ieee80211vap
*, struct mbuf
*,
122 const struct ether_header
*);
123 void ieee80211_tx_complete(struct ieee80211_node
*,
127 * The formation of ProbeResponse frames requires guidance to
128 * deal with legacy clients. When the client is identified as
129 * "legacy 11b" ieee80211_send_proberesp is passed this token.
131 #define IEEE80211_SEND_LEGACY_11B 0x1 /* legacy 11b client */
132 #define IEEE80211_SEND_LEGACY_11 0x2 /* other legacy client */
133 #define IEEE80211_SEND_LEGACY 0x3 /* any legacy client */
134 struct mbuf
*ieee80211_alloc_proberesp(struct ieee80211_node
*, int);
135 int ieee80211_send_proberesp(struct ieee80211vap
*,
136 const uint8_t da
[IEEE80211_ADDR_LEN
], int);
137 struct mbuf
*ieee80211_alloc_rts(struct ieee80211com
*ic
,
138 const uint8_t [IEEE80211_ADDR_LEN
],
139 const uint8_t [IEEE80211_ADDR_LEN
], uint16_t);
140 struct mbuf
*ieee80211_alloc_cts(struct ieee80211com
*,
141 const uint8_t [IEEE80211_ADDR_LEN
], uint16_t);
143 uint8_t *ieee80211_add_rates(uint8_t *, const struct ieee80211_rateset
*);
144 uint8_t *ieee80211_add_xrates(uint8_t *, const struct ieee80211_rateset
*);
145 uint8_t *ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int
);
146 uint8_t *ieee80211_add_wpa(uint8_t *, const struct ieee80211vap
*);
147 uint8_t *ieee80211_add_rsn(uint8_t *, const struct ieee80211vap
*);
148 uint8_t *ieee80211_add_qos(uint8_t *, const struct ieee80211_node
*);
149 uint16_t ieee80211_getcapinfo(struct ieee80211vap
*,
150 struct ieee80211_channel
*);
151 struct ieee80211_wme_state
;
152 uint8_t * ieee80211_add_wme_info(uint8_t *frm
, struct ieee80211_wme_state
*wme
);
154 void ieee80211_reset_erp(struct ieee80211com
*);
155 void ieee80211_set_shortslottime(struct ieee80211com
*, int onoff
);
156 int ieee80211_iserp_rateset(const struct ieee80211_rateset
*);
157 void ieee80211_setbasicrates(struct ieee80211_rateset
*,
158 enum ieee80211_phymode
);
159 void ieee80211_addbasicrates(struct ieee80211_rateset
*,
160 enum ieee80211_phymode
);
163 * Return the size of the 802.11 header for a management or data frame.
166 ieee80211_hdrsize(const void *data
)
168 const struct ieee80211_frame
*wh
= data
;
169 int size
= sizeof(struct ieee80211_frame
);
171 /* NB: we don't handle control frames */
172 KASSERT((wh
->i_fc
[0]&IEEE80211_FC0_TYPE_MASK
) != IEEE80211_FC0_TYPE_CTL
,
173 ("%s: control frame", __func__
));
174 if (IEEE80211_IS_DSTODS(wh
))
175 size
+= IEEE80211_ADDR_LEN
;
176 if (IEEE80211_QOS_HAS_SEQ(wh
))
177 size
+= sizeof(uint16_t);
182 * Like ieee80211_hdrsize, but handles any type of frame.
185 ieee80211_anyhdrsize(const void *data
)
187 const struct ieee80211_frame
*wh
= data
;
189 if ((wh
->i_fc
[0]&IEEE80211_FC0_TYPE_MASK
) == IEEE80211_FC0_TYPE_CTL
) {
190 switch (wh
->i_fc
[0] & IEEE80211_FC0_SUBTYPE_MASK
) {
191 case IEEE80211_FC0_SUBTYPE_CTS
:
192 case IEEE80211_FC0_SUBTYPE_ACK
:
193 return sizeof(struct ieee80211_frame_ack
);
194 case IEEE80211_FC0_SUBTYPE_BAR
:
195 return sizeof(struct ieee80211_frame_bar
);
197 return sizeof(struct ieee80211_frame_min
);
199 return ieee80211_hdrsize(data
);
203 * Template for an in-kernel authenticator. Authenticators
204 * register with the protocol code and are typically loaded
205 * as separate modules as needed. One special authenticator
206 * is xauth; it intercepts requests so that protocols like
207 * WPA can be handled in user space.
209 struct ieee80211_authenticator
{
210 const char *ia_name
; /* printable name */
211 int (*ia_attach
)(struct ieee80211vap
*);
212 void (*ia_detach
)(struct ieee80211vap
*);
213 void (*ia_node_join
)(struct ieee80211_node
*);
214 void (*ia_node_leave
)(struct ieee80211_node
*);
216 void ieee80211_authenticator_register(int type
,
217 const struct ieee80211_authenticator
*);
218 void ieee80211_authenticator_unregister(int type
);
219 const struct ieee80211_authenticator
*ieee80211_authenticator_get(int auth
);
223 * Template for an MAC ACL policy module. Such modules
224 * register with the protocol code and are passed the sender's
225 * address of each received auth frame for validation.
227 struct ieee80211_aclator
{
228 const char *iac_name
; /* printable name */
229 int (*iac_attach
)(struct ieee80211vap
*);
230 void (*iac_detach
)(struct ieee80211vap
*);
231 int (*iac_check
)(struct ieee80211vap
*,
232 const struct ieee80211_frame
*wh
);
233 int (*iac_add
)(struct ieee80211vap
*,
234 const uint8_t mac
[IEEE80211_ADDR_LEN
]);
235 int (*iac_remove
)(struct ieee80211vap
*,
236 const uint8_t mac
[IEEE80211_ADDR_LEN
]);
237 int (*iac_flush
)(struct ieee80211vap
*);
238 int (*iac_setpolicy
)(struct ieee80211vap
*, int);
239 int (*iac_getpolicy
)(struct ieee80211vap
*);
240 int (*iac_setioctl
)(struct ieee80211vap
*, struct ieee80211req
*);
241 int (*iac_getioctl
)(struct ieee80211vap
*, struct ieee80211req
*);
243 void ieee80211_aclator_register(const struct ieee80211_aclator
*);
244 void ieee80211_aclator_unregister(const struct ieee80211_aclator
*);
245 const struct ieee80211_aclator
*ieee80211_aclator_get(const char *name
);
247 /* flags for ieee80211_fix_rate() */
248 #define IEEE80211_F_DOSORT 0x00000001 /* sort rate list */
249 #define IEEE80211_F_DOFRATE 0x00000002 /* use fixed legacy rate */
250 #define IEEE80211_F_DONEGO 0x00000004 /* calc negotiated rate */
251 #define IEEE80211_F_DODEL 0x00000008 /* delete ignore rate */
252 #define IEEE80211_F_DOBRS 0x00000010 /* check basic rate set */
253 #define IEEE80211_F_JOIN 0x00000020 /* sta joining our bss */
254 #define IEEE80211_F_DOFMCS 0x00000040 /* use fixed HT rate */
255 int ieee80211_fix_rate(struct ieee80211_node
*,
256 struct ieee80211_rateset
*, int);
264 uint8_t wmep_logcwmin
; /* log2(cwmin) */
265 uint8_t wmep_logcwmax
; /* log2(cwmax) */
266 uint8_t wmep_txopLimit
;
267 uint8_t wmep_noackPolicy
; /* 0 (ack), 1 (no ack) */
269 #define IEEE80211_TXOP_TO_US(_txop) ((_txop)<<5)
270 #define IEEE80211_US_TO_TXOP(_us) ((_us)>>5)
272 struct chanAccParams
{
273 uint8_t cap_info
; /* version of the current set */
274 struct wmeParams cap_wmeParams
[WME_NUM_AC
];
277 struct ieee80211_wme_state
{
279 #define WME_F_AGGRMODE 0x00000001 /* STATUS: WME aggressive mode */
280 u_int wme_hipri_traffic
; /* VI/VO frames in beacon interval */
281 u_int wme_hipri_switch_thresh
;/* aggressive mode switch thresh */
282 u_int wme_hipri_switch_hysteresis
;/* aggressive mode switch hysteresis */
284 struct wmeParams wme_params
[4]; /* from assoc resp for each AC*/
285 struct chanAccParams wme_wmeChanParams
; /* WME params applied to self */
286 struct chanAccParams wme_wmeBssChanParams
;/* WME params bcast to stations */
287 struct chanAccParams wme_chanParams
; /* params applied to self */
288 struct chanAccParams wme_bssChanParams
; /* params bcast to stations */
290 int (*wme_update
)(struct ieee80211com
*);
293 void ieee80211_wme_initparams(struct ieee80211vap
*);
294 void ieee80211_wme_updateparams(struct ieee80211vap
*);
295 void ieee80211_wme_updateparams_locked(struct ieee80211vap
*);
298 * Return the WME TID from a QoS frame. If no TID
299 * is present return the index for the "non-QoS" entry.
301 static __inline
uint8_t
302 ieee80211_gettid(const struct ieee80211_frame
*wh
)
306 if (IEEE80211_QOS_HAS_SEQ(wh
)) {
307 if (IEEE80211_IS_DSTODS(wh
))
308 tid
= ((const struct ieee80211_qosframe_addr4
*)wh
)->
311 tid
= ((const struct ieee80211_qosframe
*)wh
)->i_qos
[0];
312 tid
&= IEEE80211_QOS_TID
;
314 tid
= IEEE80211_NONQOS_TID
;
318 void ieee80211_waitfor_parent(struct ieee80211com
*);
319 void ieee80211_start_locked(struct ieee80211vap
*);
320 void ieee80211_init(void *);
321 void ieee80211_start_all(struct ieee80211com
*);
322 void ieee80211_stop_locked(struct ieee80211vap
*);
323 void ieee80211_stop(struct ieee80211vap
*);
324 void ieee80211_stop_all(struct ieee80211com
*);
325 void ieee80211_suspend_all(struct ieee80211com
*);
326 void ieee80211_resume_all(struct ieee80211com
*);
327 void ieee80211_restart_all(struct ieee80211com
*);
328 void ieee80211_dturbo_switch(struct ieee80211vap
*, int newflags
);
329 void ieee80211_swbmiss(void *arg
);
330 void ieee80211_beacon_miss(struct ieee80211com
*);
331 int ieee80211_new_state(struct ieee80211vap
*, enum ieee80211_state
, int);
332 int ieee80211_new_state_locked(struct ieee80211vap
*, enum ieee80211_state
,
334 void ieee80211_print_essid(const uint8_t *, int);
335 void ieee80211_dump_pkt(struct ieee80211com
*,
336 const uint8_t *, int, int, int);
338 extern const char *ieee80211_opmode_name
[];
339 extern const char *ieee80211_state_name
[IEEE80211_S_MAX
];
340 extern const char *ieee80211_wme_acnames
[];
343 * Beacon frames constructed by ieee80211_beacon_alloc
344 * have the following structure filled in so drivers
345 * can update the frame later w/ minimal overhead.
347 struct ieee80211_beacon_offsets
{
348 uint8_t bo_flags
[4]; /* update/state flags */
349 uint16_t *bo_caps
; /* capabilities */
350 uint8_t *bo_cfp
; /* start of CFParms element */
351 uint8_t *bo_tim
; /* start of atim/dtim */
352 uint8_t *bo_wme
; /* start of WME parameters */
353 uint8_t *bo_tdma
; /* start of TDMA parameters */
354 uint8_t *bo_tim_trailer
;/* start of fixed-size trailer */
355 uint16_t bo_tim_len
; /* atim/dtim length in bytes */
356 uint16_t bo_tim_trailer_len
;/* tim trailer length in bytes */
357 uint8_t *bo_erp
; /* start of ERP element */
358 uint8_t *bo_htinfo
; /* start of HT info element */
359 uint8_t *bo_ath
; /* start of ATH parameters */
360 uint8_t *bo_appie
; /* start of AppIE element */
361 uint16_t bo_appie_len
; /* AppIE length in bytes */
362 uint16_t bo_csa_trailer_len
;
363 uint8_t *bo_csa
; /* start of CSA element */
364 uint8_t *bo_quiet
; /* start of Quiet element */
365 uint8_t *bo_meshconf
; /* start of MESHCONF element */
366 uint8_t *bo_spare
[3];
368 struct mbuf
*ieee80211_beacon_alloc(struct ieee80211_node
*);
371 * Beacon frame updates are signaled through calls to iv_update_beacon
372 * with one of the IEEE80211_BEACON_* tokens defined below. For devices
373 * that construct beacon frames on the host this can trigger a rebuild
374 * or defer the processing. For devices that offload beacon frame
375 * handling this callback can be used to signal a rebuild. The bo_flags
376 * array in the ieee80211_beacon_offsets structure is intended to record
377 * deferred processing requirements; ieee80211_beacon_update uses the
378 * state to optimize work. Since this structure is owned by the driver
379 * and not visible to the 802.11 layer drivers must supply an iv_update_beacon
380 * callback that marks the flag bits and schedules (as necessary) an update.
383 IEEE80211_BEACON_CAPS
= 0, /* capabilities */
384 IEEE80211_BEACON_TIM
= 1, /* DTIM/ATIM */
385 IEEE80211_BEACON_WME
= 2,
386 IEEE80211_BEACON_ERP
= 3, /* Extended Rate Phy */
387 IEEE80211_BEACON_HTINFO
= 4, /* HT Information */
388 IEEE80211_BEACON_APPIE
= 5, /* Application IE's */
389 IEEE80211_BEACON_CFP
= 6, /* CFParms */
390 IEEE80211_BEACON_CSA
= 7, /* Channel Switch Announcement */
391 IEEE80211_BEACON_TDMA
= 9, /* TDMA Info */
392 IEEE80211_BEACON_ATH
= 10, /* ATH parameters */
393 IEEE80211_BEACON_MESHCONF
= 11, /* Mesh Configuration */
395 int ieee80211_beacon_update(struct ieee80211_node
*,
396 struct mbuf
*, int mcast
);
398 void ieee80211_csa_startswitch(struct ieee80211com
*,
399 struct ieee80211_channel
*, int mode
, int count
);
400 void ieee80211_csa_completeswitch(struct ieee80211com
*);
401 void ieee80211_csa_cancelswitch(struct ieee80211com
*);
402 void ieee80211_cac_completeswitch(struct ieee80211vap
*);
405 * Notification methods called from the 802.11 state machine.
406 * Note that while these are defined here, their implementation
409 void ieee80211_notify_node_join(struct ieee80211_node
*, int newassoc
);
410 void ieee80211_notify_node_leave(struct ieee80211_node
*);
411 void ieee80211_notify_scan_done(struct ieee80211vap
*);
412 void ieee80211_notify_wds_discover(struct ieee80211_node
*);
413 void ieee80211_notify_csa(struct ieee80211com
*,
414 const struct ieee80211_channel
*, int mode
, int count
);
415 void ieee80211_notify_radar(struct ieee80211com
*,
416 const struct ieee80211_channel
*);
417 enum ieee80211_notify_cac_event
{
418 IEEE80211_NOTIFY_CAC_START
= 0, /* CAC timer started */
419 IEEE80211_NOTIFY_CAC_STOP
= 1, /* CAC intentionally stopped */
420 IEEE80211_NOTIFY_CAC_RADAR
= 2, /* CAC stopped due to radar detectio */
421 IEEE80211_NOTIFY_CAC_EXPIRE
= 3, /* CAC expired w/o radar */
423 void ieee80211_notify_cac(struct ieee80211com
*,
424 const struct ieee80211_channel
*,
425 enum ieee80211_notify_cac_event
);
426 void ieee80211_notify_node_deauth(struct ieee80211_node
*);
427 void ieee80211_notify_node_auth(struct ieee80211_node
*);
428 void ieee80211_notify_country(struct ieee80211vap
*, const uint8_t [],
429 const uint8_t cc
[2]);
430 void ieee80211_notify_radio(struct ieee80211com
*, int);
431 #endif /* _NET80211_IEEE80211_PROTO_H_ */