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 #if defined(__DragonFly__)
77 void ieee80211_promisc(struct ieee80211vap
*, int);
78 void ieee80211_allmulti(struct ieee80211vap
*, int);
80 void ieee80211_promisc(struct ieee80211vap
*, bool);
81 void ieee80211_allmulti(struct ieee80211vap
*, bool);
83 void ieee80211_syncflag(struct ieee80211vap
*, int flag
);
84 void ieee80211_syncflag_ht(struct ieee80211vap
*, int flag
);
85 void ieee80211_syncflag_ext(struct ieee80211vap
*, int flag
);
87 #if defined(__DragonFly__)
91 #define ieee80211_input(ni, m, rssi, nf) \
92 ((ni)->ni_vap->iv_input(ni, m, NULL, rssi, nf))
93 int ieee80211_input_all(struct ieee80211com
*, struct mbuf
*, int, int);
95 int ieee80211_input_mimo(struct ieee80211_node
*, struct mbuf
*,
96 struct ieee80211_rx_stats
*);
97 int ieee80211_input_mimo_all(struct ieee80211com
*, struct mbuf
*,
98 struct ieee80211_rx_stats
*);
100 struct ieee80211_bpf_params
;
101 int ieee80211_mgmt_output(struct ieee80211_node
*, struct mbuf
*, int,
102 struct ieee80211_bpf_params
*);
103 int ieee80211_raw_xmit(struct ieee80211_node
*, struct mbuf
*,
104 const struct ieee80211_bpf_params
*);
105 #if defined(__DragonFly__)
106 int ieee80211_output(struct ifnet
*, struct mbuf
*,
107 struct sockaddr
*, struct rtentry
*rt
);
109 int ieee80211_output(struct ifnet
*, struct mbuf
*,
110 const struct sockaddr
*, struct route
*ro
);
112 int ieee80211_vap_pkt_send_dest(struct ieee80211vap
*, struct mbuf
*,
113 struct ieee80211_node
*);
114 int ieee80211_raw_output(struct ieee80211vap
*, struct ieee80211_node
*,
115 struct mbuf
*, const struct ieee80211_bpf_params
*);
116 void ieee80211_send_setup(struct ieee80211_node
*, struct mbuf
*, int, int,
117 const uint8_t [IEEE80211_ADDR_LEN
], const uint8_t [IEEE80211_ADDR_LEN
],
118 const uint8_t [IEEE80211_ADDR_LEN
]);
119 #if defined(__DragonFly__)
120 void ieee80211_vap_start(struct ifnet
*ifp
, struct ifaltq_subque
*ifsq
);
122 int ieee80211_vap_transmit(struct ifnet
*ifp
, struct mbuf
*m
);
123 void ieee80211_vap_qflush(struct ifnet
*ifp
);
124 int ieee80211_send_nulldata(struct ieee80211_node
*);
125 int ieee80211_classify(struct ieee80211_node
*, struct mbuf
*m
);
126 struct mbuf
*ieee80211_mbuf_adjust(struct ieee80211vap
*, int,
127 struct ieee80211_key
*, struct mbuf
*);
128 struct mbuf
*ieee80211_encap(struct ieee80211vap
*, struct ieee80211_node
*,
130 void ieee80211_free_mbuf(struct mbuf
*);
131 int ieee80211_send_mgmt(struct ieee80211_node
*, int, int);
132 struct ieee80211_appie
;
133 int ieee80211_send_probereq(struct ieee80211_node
*ni
,
134 const uint8_t sa
[IEEE80211_ADDR_LEN
],
135 const uint8_t da
[IEEE80211_ADDR_LEN
],
136 const uint8_t bssid
[IEEE80211_ADDR_LEN
],
137 const uint8_t *ssid
, size_t ssidlen
);
138 struct mbuf
* ieee80211_ff_encap1(struct ieee80211vap
*, struct mbuf
*,
139 const struct ether_header
*);
140 void ieee80211_tx_complete(struct ieee80211_node
*,
144 * The formation of ProbeResponse frames requires guidance to
145 * deal with legacy clients. When the client is identified as
146 * "legacy 11b" ieee80211_send_proberesp is passed this token.
148 #define IEEE80211_SEND_LEGACY_11B 0x1 /* legacy 11b client */
149 #define IEEE80211_SEND_LEGACY_11 0x2 /* other legacy client */
150 #define IEEE80211_SEND_LEGACY 0x3 /* any legacy client */
151 struct mbuf
*ieee80211_alloc_proberesp(struct ieee80211_node
*, int);
152 int ieee80211_send_proberesp(struct ieee80211vap
*,
153 const uint8_t da
[IEEE80211_ADDR_LEN
], int);
154 struct mbuf
*ieee80211_alloc_rts(struct ieee80211com
*ic
,
155 const uint8_t [IEEE80211_ADDR_LEN
],
156 const uint8_t [IEEE80211_ADDR_LEN
], uint16_t);
157 struct mbuf
*ieee80211_alloc_cts(struct ieee80211com
*,
158 const uint8_t [IEEE80211_ADDR_LEN
], uint16_t);
160 uint8_t *ieee80211_add_rates(uint8_t *, const struct ieee80211_rateset
*);
161 uint8_t *ieee80211_add_xrates(uint8_t *, const struct ieee80211_rateset
*);
162 uint8_t *ieee80211_add_ssid(uint8_t *, const uint8_t *, u_int
);
163 uint8_t *ieee80211_add_wpa(uint8_t *, const struct ieee80211vap
*);
164 uint8_t *ieee80211_add_rsn(uint8_t *, const struct ieee80211vap
*);
165 uint8_t *ieee80211_add_qos(uint8_t *, const struct ieee80211_node
*);
166 uint16_t ieee80211_getcapinfo(struct ieee80211vap
*,
167 struct ieee80211_channel
*);
168 struct ieee80211_wme_state
;
169 uint8_t * ieee80211_add_wme_info(uint8_t *frm
, struct ieee80211_wme_state
*wme
);
171 void ieee80211_reset_erp(struct ieee80211com
*);
172 void ieee80211_set_shortslottime(struct ieee80211com
*, int onoff
);
173 int ieee80211_iserp_rateset(const struct ieee80211_rateset
*);
174 void ieee80211_setbasicrates(struct ieee80211_rateset
*,
175 enum ieee80211_phymode
);
176 void ieee80211_addbasicrates(struct ieee80211_rateset
*,
177 enum ieee80211_phymode
);
180 * Return the size of the 802.11 header for a management or data frame.
183 ieee80211_hdrsize(const void *data
)
185 const struct ieee80211_frame
*wh
= data
;
186 int size
= sizeof(struct ieee80211_frame
);
188 /* NB: we don't handle control frames */
189 KASSERT((wh
->i_fc
[0]&IEEE80211_FC0_TYPE_MASK
) != IEEE80211_FC0_TYPE_CTL
,
190 ("%s: control frame", __func__
));
191 if (IEEE80211_IS_DSTODS(wh
))
192 size
+= IEEE80211_ADDR_LEN
;
193 if (IEEE80211_QOS_HAS_SEQ(wh
))
194 size
+= sizeof(uint16_t);
199 * Like ieee80211_hdrsize, but handles any type of frame.
202 ieee80211_anyhdrsize(const void *data
)
204 const struct ieee80211_frame
*wh
= data
;
206 if ((wh
->i_fc
[0]&IEEE80211_FC0_TYPE_MASK
) == IEEE80211_FC0_TYPE_CTL
) {
207 switch (wh
->i_fc
[0] & IEEE80211_FC0_SUBTYPE_MASK
) {
208 case IEEE80211_FC0_SUBTYPE_CTS
:
209 case IEEE80211_FC0_SUBTYPE_ACK
:
210 return sizeof(struct ieee80211_frame_ack
);
211 case IEEE80211_FC0_SUBTYPE_BAR
:
212 return sizeof(struct ieee80211_frame_bar
);
214 return sizeof(struct ieee80211_frame_min
);
216 return ieee80211_hdrsize(data
);
220 * Template for an in-kernel authenticator. Authenticators
221 * register with the protocol code and are typically loaded
222 * as separate modules as needed. One special authenticator
223 * is xauth; it intercepts requests so that protocols like
224 * WPA can be handled in user space.
226 struct ieee80211_authenticator
{
227 const char *ia_name
; /* printable name */
228 int (*ia_attach
)(struct ieee80211vap
*);
229 void (*ia_detach
)(struct ieee80211vap
*);
230 void (*ia_node_join
)(struct ieee80211_node
*);
231 void (*ia_node_leave
)(struct ieee80211_node
*);
233 void ieee80211_authenticator_register(int type
,
234 const struct ieee80211_authenticator
*);
235 void ieee80211_authenticator_unregister(int type
);
236 const struct ieee80211_authenticator
*ieee80211_authenticator_get(int auth
);
240 * Template for an MAC ACL policy module. Such modules
241 * register with the protocol code and are passed the sender's
242 * address of each received auth frame for validation.
244 struct ieee80211_aclator
{
245 const char *iac_name
; /* printable name */
246 int (*iac_attach
)(struct ieee80211vap
*);
247 void (*iac_detach
)(struct ieee80211vap
*);
248 int (*iac_check
)(struct ieee80211vap
*,
249 const struct ieee80211_frame
*wh
);
250 int (*iac_add
)(struct ieee80211vap
*,
251 const uint8_t mac
[IEEE80211_ADDR_LEN
]);
252 int (*iac_remove
)(struct ieee80211vap
*,
253 const uint8_t mac
[IEEE80211_ADDR_LEN
]);
254 int (*iac_flush
)(struct ieee80211vap
*);
255 int (*iac_setpolicy
)(struct ieee80211vap
*, int);
256 int (*iac_getpolicy
)(struct ieee80211vap
*);
257 int (*iac_setioctl
)(struct ieee80211vap
*, struct ieee80211req
*);
258 int (*iac_getioctl
)(struct ieee80211vap
*, struct ieee80211req
*);
260 void ieee80211_aclator_register(const struct ieee80211_aclator
*);
261 void ieee80211_aclator_unregister(const struct ieee80211_aclator
*);
262 const struct ieee80211_aclator
*ieee80211_aclator_get(const char *name
);
264 /* flags for ieee80211_fix_rate() */
265 #define IEEE80211_F_DOSORT 0x00000001 /* sort rate list */
266 #define IEEE80211_F_DOFRATE 0x00000002 /* use fixed legacy rate */
267 #define IEEE80211_F_DONEGO 0x00000004 /* calc negotiated rate */
268 #define IEEE80211_F_DODEL 0x00000008 /* delete ignore rate */
269 #define IEEE80211_F_DOBRS 0x00000010 /* check basic rate set */
270 #define IEEE80211_F_JOIN 0x00000020 /* sta joining our bss */
271 #define IEEE80211_F_DOFMCS 0x00000040 /* use fixed HT rate */
272 int ieee80211_fix_rate(struct ieee80211_node
*,
273 struct ieee80211_rateset
*, int);
281 uint8_t wmep_logcwmin
; /* log2(cwmin) */
282 uint8_t wmep_logcwmax
; /* log2(cwmax) */
283 uint8_t wmep_txopLimit
;
284 uint8_t wmep_noackPolicy
; /* 0 (ack), 1 (no ack) */
286 #define IEEE80211_TXOP_TO_US(_txop) ((_txop)<<5)
287 #define IEEE80211_US_TO_TXOP(_us) ((_us)>>5)
289 struct chanAccParams
{
290 uint8_t cap_info
; /* version of the current set */
291 struct wmeParams cap_wmeParams
[WME_NUM_AC
];
294 struct ieee80211_wme_state
{
296 #define WME_F_AGGRMODE 0x00000001 /* STATUS: WME aggressive mode */
297 u_int wme_hipri_traffic
; /* VI/VO frames in beacon interval */
298 u_int wme_hipri_switch_thresh
;/* aggressive mode switch thresh */
299 u_int wme_hipri_switch_hysteresis
;/* aggressive mode switch hysteresis */
301 struct wmeParams wme_params
[4]; /* from assoc resp for each AC*/
302 struct chanAccParams wme_wmeChanParams
; /* WME params applied to self */
303 struct chanAccParams wme_wmeBssChanParams
;/* WME params bcast to stations */
304 struct chanAccParams wme_chanParams
; /* params applied to self */
305 struct chanAccParams wme_bssChanParams
; /* params bcast to stations */
307 int (*wme_update
)(struct ieee80211com
*);
310 void ieee80211_wme_initparams(struct ieee80211vap
*);
311 void ieee80211_wme_updateparams(struct ieee80211vap
*);
312 void ieee80211_wme_updateparams_locked(struct ieee80211vap
*);
315 * Return the WME TID from a QoS frame. If no TID
316 * is present return the index for the "non-QoS" entry.
318 static __inline
uint8_t
319 ieee80211_gettid(const struct ieee80211_frame
*wh
)
323 if (IEEE80211_QOS_HAS_SEQ(wh
)) {
324 if (IEEE80211_IS_DSTODS(wh
))
325 tid
= ((const struct ieee80211_qosframe_addr4
*)wh
)->
328 tid
= ((const struct ieee80211_qosframe
*)wh
)->i_qos
[0];
329 tid
&= IEEE80211_QOS_TID
;
331 tid
= IEEE80211_NONQOS_TID
;
335 void ieee80211_waitfor_parent(struct ieee80211com
*);
336 void ieee80211_start_locked(struct ieee80211vap
*);
337 void ieee80211_init(void *);
338 void ieee80211_start_all(struct ieee80211com
*);
339 void ieee80211_stop_locked(struct ieee80211vap
*);
340 void ieee80211_stop(struct ieee80211vap
*);
341 void ieee80211_stop_all(struct ieee80211com
*);
342 void ieee80211_suspend_all(struct ieee80211com
*);
343 void ieee80211_resume_all(struct ieee80211com
*);
344 void ieee80211_restart_all(struct ieee80211com
*);
345 void ieee80211_dturbo_switch(struct ieee80211vap
*, int newflags
);
346 void ieee80211_swbmiss(void *arg
);
347 void ieee80211_beacon_miss(struct ieee80211com
*);
348 int ieee80211_new_state(struct ieee80211vap
*, enum ieee80211_state
, int);
349 int ieee80211_new_state_locked(struct ieee80211vap
*, enum ieee80211_state
,
351 void ieee80211_print_essid(const uint8_t *, int);
352 void ieee80211_dump_pkt(struct ieee80211com
*,
353 const uint8_t *, int, int, int);
355 extern const char *ieee80211_opmode_name
[];
356 extern const char *ieee80211_state_name
[IEEE80211_S_MAX
];
357 extern const char *ieee80211_wme_acnames
[];
360 * Beacon frames constructed by ieee80211_beacon_alloc
361 * have the following structure filled in so drivers
362 * can update the frame later w/ minimal overhead.
364 struct ieee80211_beacon_offsets
{
365 uint8_t bo_flags
[4]; /* update/state flags */
366 uint16_t *bo_caps
; /* capabilities */
367 uint8_t *bo_cfp
; /* start of CFParms element */
368 uint8_t *bo_tim
; /* start of atim/dtim */
369 uint8_t *bo_wme
; /* start of WME parameters */
370 uint8_t *bo_tdma
; /* start of TDMA parameters */
371 uint8_t *bo_tim_trailer
;/* start of fixed-size trailer */
372 uint16_t bo_tim_len
; /* atim/dtim length in bytes */
373 uint16_t bo_tim_trailer_len
;/* tim trailer length in bytes */
374 uint8_t *bo_erp
; /* start of ERP element */
375 uint8_t *bo_htinfo
; /* start of HT info element */
376 uint8_t *bo_ath
; /* start of ATH parameters */
377 uint8_t *bo_appie
; /* start of AppIE element */
378 uint16_t bo_appie_len
; /* AppIE length in bytes */
379 uint16_t bo_csa_trailer_len
;
380 uint8_t *bo_csa
; /* start of CSA element */
381 uint8_t *bo_quiet
; /* start of Quiet element */
382 uint8_t *bo_meshconf
; /* start of MESHCONF element */
383 uint8_t *bo_spare
[3];
385 struct mbuf
*ieee80211_beacon_alloc(struct ieee80211_node
*);
388 * Beacon frame updates are signaled through calls to iv_update_beacon
389 * with one of the IEEE80211_BEACON_* tokens defined below. For devices
390 * that construct beacon frames on the host this can trigger a rebuild
391 * or defer the processing. For devices that offload beacon frame
392 * handling this callback can be used to signal a rebuild. The bo_flags
393 * array in the ieee80211_beacon_offsets structure is intended to record
394 * deferred processing requirements; ieee80211_beacon_update uses the
395 * state to optimize work. Since this structure is owned by the driver
396 * and not visible to the 802.11 layer drivers must supply an iv_update_beacon
397 * callback that marks the flag bits and schedules (as necessary) an update.
400 IEEE80211_BEACON_CAPS
= 0, /* capabilities */
401 IEEE80211_BEACON_TIM
= 1, /* DTIM/ATIM */
402 IEEE80211_BEACON_WME
= 2,
403 IEEE80211_BEACON_ERP
= 3, /* Extended Rate Phy */
404 IEEE80211_BEACON_HTINFO
= 4, /* HT Information */
405 IEEE80211_BEACON_APPIE
= 5, /* Application IE's */
406 IEEE80211_BEACON_CFP
= 6, /* CFParms */
407 IEEE80211_BEACON_CSA
= 7, /* Channel Switch Announcement */
408 IEEE80211_BEACON_TDMA
= 9, /* TDMA Info */
409 IEEE80211_BEACON_ATH
= 10, /* ATH parameters */
410 IEEE80211_BEACON_MESHCONF
= 11, /* Mesh Configuration */
412 int ieee80211_beacon_update(struct ieee80211_node
*,
413 struct mbuf
*, int mcast
);
415 void ieee80211_csa_startswitch(struct ieee80211com
*,
416 struct ieee80211_channel
*, int mode
, int count
);
417 void ieee80211_csa_completeswitch(struct ieee80211com
*);
418 void ieee80211_csa_cancelswitch(struct ieee80211com
*);
419 void ieee80211_cac_completeswitch(struct ieee80211vap
*);
422 * Notification methods called from the 802.11 state machine.
423 * Note that while these are defined here, their implementation
426 void ieee80211_notify_node_join(struct ieee80211_node
*, int newassoc
);
427 void ieee80211_notify_node_leave(struct ieee80211_node
*);
428 void ieee80211_notify_scan_done(struct ieee80211vap
*);
429 void ieee80211_notify_wds_discover(struct ieee80211_node
*);
430 void ieee80211_notify_csa(struct ieee80211com
*,
431 const struct ieee80211_channel
*, int mode
, int count
);
432 void ieee80211_notify_radar(struct ieee80211com
*,
433 const struct ieee80211_channel
*);
434 enum ieee80211_notify_cac_event
{
435 IEEE80211_NOTIFY_CAC_START
= 0, /* CAC timer started */
436 IEEE80211_NOTIFY_CAC_STOP
= 1, /* CAC intentionally stopped */
437 IEEE80211_NOTIFY_CAC_RADAR
= 2, /* CAC stopped due to radar detectio */
438 IEEE80211_NOTIFY_CAC_EXPIRE
= 3, /* CAC expired w/o radar */
440 void ieee80211_notify_cac(struct ieee80211com
*,
441 const struct ieee80211_channel
*,
442 enum ieee80211_notify_cac_event
);
443 void ieee80211_notify_node_deauth(struct ieee80211_node
*);
444 void ieee80211_notify_node_auth(struct ieee80211_node
*);
445 void ieee80211_notify_country(struct ieee80211vap
*, const uint8_t [],
446 const uint8_t cc
[2]);
447 void ieee80211_notify_radio(struct ieee80211com
*, int);
448 #endif /* _NET80211_IEEE80211_PROTO_H_ */