diff options
Diffstat (limited to 'include/linux/ieee80211.h')
-rw-r--r-- | include/linux/ieee80211.h | 392 |
1 files changed, 374 insertions, 18 deletions
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 8f2c20b4a15d..371237b0d8b9 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -98,6 +98,7 @@ | |||
98 | 98 | ||
99 | #define IEEE80211_MAX_SSID_LEN 32 | 99 | #define IEEE80211_MAX_SSID_LEN 32 |
100 | #define IEEE80211_MAX_MESH_ID_LEN 32 | 100 | #define IEEE80211_MAX_MESH_ID_LEN 32 |
101 | #define IEEE80211_QOS_CTL_LEN 2 | ||
101 | 102 | ||
102 | struct ieee80211_hdr { | 103 | struct ieee80211_hdr { |
103 | __le16 frame_control; | 104 | __le16 frame_control; |
@@ -109,6 +110,355 @@ struct ieee80211_hdr { | |||
109 | u8 addr4[6]; | 110 | u8 addr4[6]; |
110 | } __attribute__ ((packed)); | 111 | } __attribute__ ((packed)); |
111 | 112 | ||
113 | /** | ||
114 | * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set | ||
115 | * @fc: frame control bytes in little-endian byteorder | ||
116 | */ | ||
117 | static inline int ieee80211_has_tods(__le16 fc) | ||
118 | { | ||
119 | return (fc & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0; | ||
120 | } | ||
121 | |||
122 | /** | ||
123 | * ieee80211_has_fromds - check if IEEE80211_FCTL_FROMDS is set | ||
124 | * @fc: frame control bytes in little-endian byteorder | ||
125 | */ | ||
126 | static inline int ieee80211_has_fromds(__le16 fc) | ||
127 | { | ||
128 | return (fc & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0; | ||
129 | } | ||
130 | |||
131 | /** | ||
132 | * ieee80211_has_a4 - check if IEEE80211_FCTL_TODS and IEEE80211_FCTL_FROMDS are set | ||
133 | * @fc: frame control bytes in little-endian byteorder | ||
134 | */ | ||
135 | static inline int ieee80211_has_a4(__le16 fc) | ||
136 | { | ||
137 | __le16 tmp = cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | ||
138 | return (fc & tmp) == tmp; | ||
139 | } | ||
140 | |||
141 | /** | ||
142 | * ieee80211_has_morefrags - check if IEEE80211_FCTL_MOREFRAGS is set | ||
143 | * @fc: frame control bytes in little-endian byteorder | ||
144 | */ | ||
145 | static inline int ieee80211_has_morefrags(__le16 fc) | ||
146 | { | ||
147 | return (fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0; | ||
148 | } | ||
149 | |||
150 | /** | ||
151 | * ieee80211_has_retry - check if IEEE80211_FCTL_RETRY is set | ||
152 | * @fc: frame control bytes in little-endian byteorder | ||
153 | */ | ||
154 | static inline int ieee80211_has_retry(__le16 fc) | ||
155 | { | ||
156 | return (fc & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0; | ||
157 | } | ||
158 | |||
159 | /** | ||
160 | * ieee80211_has_pm - check if IEEE80211_FCTL_PM is set | ||
161 | * @fc: frame control bytes in little-endian byteorder | ||
162 | */ | ||
163 | static inline int ieee80211_has_pm(__le16 fc) | ||
164 | { | ||
165 | return (fc & cpu_to_le16(IEEE80211_FCTL_PM)) != 0; | ||
166 | } | ||
167 | |||
168 | /** | ||
169 | * ieee80211_has_moredata - check if IEEE80211_FCTL_MOREDATA is set | ||
170 | * @fc: frame control bytes in little-endian byteorder | ||
171 | */ | ||
172 | static inline int ieee80211_has_moredata(__le16 fc) | ||
173 | { | ||
174 | return (fc & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0; | ||
175 | } | ||
176 | |||
177 | /** | ||
178 | * ieee80211_has_protected - check if IEEE80211_FCTL_PROTECTED is set | ||
179 | * @fc: frame control bytes in little-endian byteorder | ||
180 | */ | ||
181 | static inline int ieee80211_has_protected(__le16 fc) | ||
182 | { | ||
183 | return (fc & cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0; | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * ieee80211_has_order - check if IEEE80211_FCTL_ORDER is set | ||
188 | * @fc: frame control bytes in little-endian byteorder | ||
189 | */ | ||
190 | static inline int ieee80211_has_order(__le16 fc) | ||
191 | { | ||
192 | return (fc & cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0; | ||
193 | } | ||
194 | |||
195 | /** | ||
196 | * ieee80211_is_mgmt - check if type is IEEE80211_FTYPE_MGMT | ||
197 | * @fc: frame control bytes in little-endian byteorder | ||
198 | */ | ||
199 | static inline int ieee80211_is_mgmt(__le16 fc) | ||
200 | { | ||
201 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | ||
202 | cpu_to_le16(IEEE80211_FTYPE_MGMT); | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * ieee80211_is_ctl - check if type is IEEE80211_FTYPE_CTL | ||
207 | * @fc: frame control bytes in little-endian byteorder | ||
208 | */ | ||
209 | static inline int ieee80211_is_ctl(__le16 fc) | ||
210 | { | ||
211 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | ||
212 | cpu_to_le16(IEEE80211_FTYPE_CTL); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * ieee80211_is_data - check if type is IEEE80211_FTYPE_DATA | ||
217 | * @fc: frame control bytes in little-endian byteorder | ||
218 | */ | ||
219 | static inline int ieee80211_is_data(__le16 fc) | ||
220 | { | ||
221 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | ||
222 | cpu_to_le16(IEEE80211_FTYPE_DATA); | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set | ||
227 | * @fc: frame control bytes in little-endian byteorder | ||
228 | */ | ||
229 | static inline int ieee80211_is_data_qos(__le16 fc) | ||
230 | { | ||
231 | /* | ||
232 | * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need | ||
233 | * to check the one bit | ||
234 | */ | ||
235 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_STYPE_QOS_DATA)) == | ||
236 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA); | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * ieee80211_is_data_present - check if type is IEEE80211_FTYPE_DATA and has data | ||
241 | * @fc: frame control bytes in little-endian byteorder | ||
242 | */ | ||
243 | static inline int ieee80211_is_data_present(__le16 fc) | ||
244 | { | ||
245 | /* | ||
246 | * mask with 0x40 and test that that bit is clear to only return true | ||
247 | * for the data-containing substypes. | ||
248 | */ | ||
249 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 0x40)) == | ||
250 | cpu_to_le16(IEEE80211_FTYPE_DATA); | ||
251 | } | ||
252 | |||
253 | /** | ||
254 | * ieee80211_is_assoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_REQ | ||
255 | * @fc: frame control bytes in little-endian byteorder | ||
256 | */ | ||
257 | static inline int ieee80211_is_assoc_req(__le16 fc) | ||
258 | { | ||
259 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
260 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ); | ||
261 | } | ||
262 | |||
263 | /** | ||
264 | * ieee80211_is_assoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_RESP | ||
265 | * @fc: frame control bytes in little-endian byteorder | ||
266 | */ | ||
267 | static inline int ieee80211_is_assoc_resp(__le16 fc) | ||
268 | { | ||
269 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
270 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_RESP); | ||
271 | } | ||
272 | |||
273 | /** | ||
274 | * ieee80211_is_reassoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_REQ | ||
275 | * @fc: frame control bytes in little-endian byteorder | ||
276 | */ | ||
277 | static inline int ieee80211_is_reassoc_req(__le16 fc) | ||
278 | { | ||
279 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
280 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ); | ||
281 | } | ||
282 | |||
283 | /** | ||
284 | * ieee80211_is_reassoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_RESP | ||
285 | * @fc: frame control bytes in little-endian byteorder | ||
286 | */ | ||
287 | static inline int ieee80211_is_reassoc_resp(__le16 fc) | ||
288 | { | ||
289 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
290 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_RESP); | ||
291 | } | ||
292 | |||
293 | /** | ||
294 | * ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_REQ | ||
295 | * @fc: frame control bytes in little-endian byteorder | ||
296 | */ | ||
297 | static inline int ieee80211_is_probe_req(__le16 fc) | ||
298 | { | ||
299 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
300 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ); | ||
301 | } | ||
302 | |||
303 | /** | ||
304 | * ieee80211_is_probe_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_RESP | ||
305 | * @fc: frame control bytes in little-endian byteorder | ||
306 | */ | ||
307 | static inline int ieee80211_is_probe_resp(__le16 fc) | ||
308 | { | ||
309 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
310 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * ieee80211_is_beacon - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_BEACON | ||
315 | * @fc: frame control bytes in little-endian byteorder | ||
316 | */ | ||
317 | static inline int ieee80211_is_beacon(__le16 fc) | ||
318 | { | ||
319 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
320 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); | ||
321 | } | ||
322 | |||
323 | /** | ||
324 | * ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM | ||
325 | * @fc: frame control bytes in little-endian byteorder | ||
326 | */ | ||
327 | static inline int ieee80211_is_atim(__le16 fc) | ||
328 | { | ||
329 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
330 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ATIM); | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * ieee80211_is_disassoc - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DISASSOC | ||
335 | * @fc: frame control bytes in little-endian byteorder | ||
336 | */ | ||
337 | static inline int ieee80211_is_disassoc(__le16 fc) | ||
338 | { | ||
339 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
340 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * ieee80211_is_auth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_AUTH | ||
345 | * @fc: frame control bytes in little-endian byteorder | ||
346 | */ | ||
347 | static inline int ieee80211_is_auth(__le16 fc) | ||
348 | { | ||
349 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
350 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); | ||
351 | } | ||
352 | |||
353 | /** | ||
354 | * ieee80211_is_deauth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DEAUTH | ||
355 | * @fc: frame control bytes in little-endian byteorder | ||
356 | */ | ||
357 | static inline int ieee80211_is_deauth(__le16 fc) | ||
358 | { | ||
359 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
360 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH); | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * ieee80211_is_action - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ACTION | ||
365 | * @fc: frame control bytes in little-endian byteorder | ||
366 | */ | ||
367 | static inline int ieee80211_is_action(__le16 fc) | ||
368 | { | ||
369 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
370 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); | ||
371 | } | ||
372 | |||
373 | /** | ||
374 | * ieee80211_is_back_req - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK_REQ | ||
375 | * @fc: frame control bytes in little-endian byteorder | ||
376 | */ | ||
377 | static inline int ieee80211_is_back_req(__le16 fc) | ||
378 | { | ||
379 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
380 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK_REQ); | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * ieee80211_is_back - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK | ||
385 | * @fc: frame control bytes in little-endian byteorder | ||
386 | */ | ||
387 | static inline int ieee80211_is_back(__le16 fc) | ||
388 | { | ||
389 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
390 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK); | ||
391 | } | ||
392 | |||
393 | /** | ||
394 | * ieee80211_is_pspoll - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_PSPOLL | ||
395 | * @fc: frame control bytes in little-endian byteorder | ||
396 | */ | ||
397 | static inline int ieee80211_is_pspoll(__le16 fc) | ||
398 | { | ||
399 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
400 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); | ||
401 | } | ||
402 | |||
403 | /** | ||
404 | * ieee80211_is_rts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_RTS | ||
405 | * @fc: frame control bytes in little-endian byteorder | ||
406 | */ | ||
407 | static inline int ieee80211_is_rts(__le16 fc) | ||
408 | { | ||
409 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
410 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); | ||
411 | } | ||
412 | |||
413 | /** | ||
414 | * ieee80211_is_cts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CTS | ||
415 | * @fc: frame control bytes in little-endian byteorder | ||
416 | */ | ||
417 | static inline int ieee80211_is_cts(__le16 fc) | ||
418 | { | ||
419 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
420 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * ieee80211_is_ack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_ACK | ||
425 | * @fc: frame control bytes in little-endian byteorder | ||
426 | */ | ||
427 | static inline int ieee80211_is_ack(__le16 fc) | ||
428 | { | ||
429 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
430 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK); | ||
431 | } | ||
432 | |||
433 | /** | ||
434 | * ieee80211_is_cfend - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFEND | ||
435 | * @fc: frame control bytes in little-endian byteorder | ||
436 | */ | ||
437 | static inline int ieee80211_is_cfend(__le16 fc) | ||
438 | { | ||
439 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
440 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFEND); | ||
441 | } | ||
442 | |||
443 | /** | ||
444 | * ieee80211_is_cfendack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFENDACK | ||
445 | * @fc: frame control bytes in little-endian byteorder | ||
446 | */ | ||
447 | static inline int ieee80211_is_cfendack(__le16 fc) | ||
448 | { | ||
449 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
450 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFENDACK); | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * ieee80211_is_nullfunc - check if FTYPE=IEEE80211_FTYPE_DATA and STYPE=IEEE80211_STYPE_NULLFUNC | ||
455 | * @fc: frame control bytes in little-endian byteorder | ||
456 | */ | ||
457 | static inline int ieee80211_is_nullfunc(__le16 fc) | ||
458 | { | ||
459 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | ||
460 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC); | ||
461 | } | ||
112 | 462 | ||
113 | struct ieee80211s_hdr { | 463 | struct ieee80211s_hdr { |
114 | u8 flags; | 464 | u8 flags; |
@@ -553,48 +903,54 @@ enum ieee80211_back_parties { | |||
553 | #define WLAN_MAX_KEY_LEN 32 | 903 | #define WLAN_MAX_KEY_LEN 32 |
554 | 904 | ||
555 | /** | 905 | /** |
906 | * ieee80211_get_qos_ctl - get pointer to qos control bytes | ||
907 | * @hdr: the frame | ||
908 | * | ||
909 | * The qos ctrl bytes come after the frame_control, duration, seq_num | ||
910 | * and 3 or 4 addresses of length ETH_ALEN. | ||
911 | * 3 addr: 2 + 2 + 2 + 3*6 = 24 | ||
912 | * 4 addr: 2 + 2 + 2 + 4*6 = 30 | ||
913 | */ | ||
914 | static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr) | ||
915 | { | ||
916 | if (ieee80211_has_a4(hdr->frame_control)) | ||
917 | return (u8 *)hdr + 30; | ||
918 | else | ||
919 | return (u8 *)hdr + 24; | ||
920 | } | ||
921 | |||
922 | /** | ||
556 | * ieee80211_get_SA - get pointer to SA | 923 | * ieee80211_get_SA - get pointer to SA |
924 | * @hdr: the frame | ||
557 | * | 925 | * |
558 | * Given an 802.11 frame, this function returns the offset | 926 | * Given an 802.11 frame, this function returns the offset |
559 | * to the source address (SA). It does not verify that the | 927 | * to the source address (SA). It does not verify that the |
560 | * header is long enough to contain the address, and the | 928 | * header is long enough to contain the address, and the |
561 | * header must be long enough to contain the frame control | 929 | * header must be long enough to contain the frame control |
562 | * field. | 930 | * field. |
563 | * | ||
564 | * @hdr: the frame | ||
565 | */ | 931 | */ |
566 | static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) | 932 | static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) |
567 | { | 933 | { |
568 | __le16 fc = hdr->frame_control; | 934 | if (ieee80211_has_a4(hdr->frame_control)) |
569 | fc &= cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | ||
570 | |||
571 | switch (fc) { | ||
572 | case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS): | ||
573 | return hdr->addr3; | ||
574 | case __constant_cpu_to_le16(IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS): | ||
575 | return hdr->addr4; | 935 | return hdr->addr4; |
576 | default: | 936 | if (ieee80211_has_fromds(hdr->frame_control)) |
577 | return hdr->addr2; | 937 | return hdr->addr3; |
578 | } | 938 | return hdr->addr2; |
579 | } | 939 | } |
580 | 940 | ||
581 | /** | 941 | /** |
582 | * ieee80211_get_DA - get pointer to DA | 942 | * ieee80211_get_DA - get pointer to DA |
943 | * @hdr: the frame | ||
583 | * | 944 | * |
584 | * Given an 802.11 frame, this function returns the offset | 945 | * Given an 802.11 frame, this function returns the offset |
585 | * to the destination address (DA). It does not verify that | 946 | * to the destination address (DA). It does not verify that |
586 | * the header is long enough to contain the address, and the | 947 | * the header is long enough to contain the address, and the |
587 | * header must be long enough to contain the frame control | 948 | * header must be long enough to contain the frame control |
588 | * field. | 949 | * field. |
589 | * | ||
590 | * @hdr: the frame | ||
591 | */ | 950 | */ |
592 | static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) | 951 | static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) |
593 | { | 952 | { |
594 | __le16 fc = hdr->frame_control; | 953 | if (ieee80211_has_tods(hdr->frame_control)) |
595 | fc &= cpu_to_le16(IEEE80211_FCTL_TODS); | ||
596 | |||
597 | if (fc) | ||
598 | return hdr->addr3; | 954 | return hdr->addr3; |
599 | else | 955 | else |
600 | return hdr->addr1; | 956 | return hdr->addr1; |