aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/ieee80211.h
diff options
context:
space:
mode:
authorHarvey Harrison <harvey.harrison@gmail.com>2008-06-11 17:21:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-06-14 12:18:12 -0400
commitfd7c8a40b2a63863f749e4d17f0d94d2e5ab1331 (patch)
tree098e07d68b4d1e7a6c02750db480204c0dd469d5 /include/linux/ieee80211.h
parente36cfdc9b17fa64245ee6206287e5120e59bbfca (diff)
mac80211: add helpers for frame control testing
A few general categories: 1) ieee80211_has_* tests if particular fctl bits are set, the helpers are de in the same order as the fctl defines: A combined _has_a4 was also added to test when both FROMDS and TODS are set. 2) ieee80211_is_* is meant to test whether the frame control is of a certain ftype - data, mgmt, ctl, and two special helpers _is_data_qos, _is_data_pres which also test a subset of the stype space. When testing for a particular stype applicable only to one ftype, functions like ieee80211_is_ack have been added. Note that the ftype is also being checked in these helpers. They have been added for all mgmt and ctl stypes in the same order as the STYPE defines. 3) ieee80211_get_* is meant to take a struct ieee80211_hdr * and returns a pointer to somewhere in the struct, see get_SA, get_DA, get_qos_ctl. The intel wireless drivers had helpers that used this namespace, convert the all to use the new helpers and remove the byteshifting as they were defined in cpu-order rather than little-endian. Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'include/linux/ieee80211.h')
-rw-r--r--include/linux/ieee80211.h392
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
102struct ieee80211_hdr { 103struct 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 */
117static 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 */
126static 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 */
135static 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 */
145static 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 */
154static 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 */
163static 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 */
172static 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 */
181static 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 */
190static 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 */
199static 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 */
209static 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 */
219static 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 */
229static 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 */
243static 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 */
257static 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 */
267static 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 */
277static 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 */
287static 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 */
297static 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 */
307static 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 */
317static 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 */
327static 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 */
337static 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 */
347static 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 */
357static 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 */
367static 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 */
377static 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 */
387static 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 */
397static 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 */
407static 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 */
417static 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 */
427static 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 */
437static 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 */
447static 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 */
457static 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
113struct ieee80211s_hdr { 463struct 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 */
914static 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 */
566static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) 932static 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 */
592static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) 951static 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;