ieee80211_input.h revision 190391
11541Srgrimes/*- 21541Srgrimes * Copyright (c) 2007-2009 Sam Leffler, Errno Consulting 31541Srgrimes * All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 141541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 151541Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 161541Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 171541Srgrimes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 181541Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 191541Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 201541Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 211541Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 221541Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 231541Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 241541Srgrimes * 251541Srgrimes * $FreeBSD: head/sys/net80211/ieee80211_input.h 190391 2009-03-24 20:39:08Z sam $ 261541Srgrimes */ 271541Srgrimes#ifndef _NET80211_IEEE80211_INPUT_H_ 281541Srgrimes#define _NET80211_IEEE80211_INPUT_H_ 291541Srgrimes 301541Srgrimes/* Verify the existence and length of __elem or get out. */ 311541Srgrimes#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen, _action) do { \ 321541Srgrimes if ((__elem) == NULL) { \ 331541Srgrimes IEEE80211_DISCARD(vap, IEEE80211_MSG_ELEMID, \ 3414493Shsu wh, NULL, "%s", "no " #__elem ); \ 3550477Speter vap->iv_stats.is_rx_elem_missing++; \ 361541Srgrimes _action; \ 371541Srgrimes } else if ((__elem)[1] > (__maxlen)) { \ 381541Srgrimes IEEE80211_DISCARD(vap, IEEE80211_MSG_ELEMID, \ 391541Srgrimes wh, NULL, "bad " #__elem " len %d", (__elem)[1]); \ 401541Srgrimes vap->iv_stats.is_rx_elem_toobig++; \ 4190711Swollman _action; \ 42205792Sed } \ 43102227Smike} while (0) 4490711Swollman 45143952Sdas#define IEEE80211_VERIFY_LENGTH(_len, _minlen, _action) do { \ 46143952Sdas if ((_len) < (_minlen)) { \ 47143952Sdas IEEE80211_DISCARD(vap, IEEE80211_MSG_ELEMID, \ 48143952Sdas wh, NULL, "ie too short, got %d, expected %d", \ 49112237Smike (_len), (_minlen)); \ 50143952Sdas vap->iv_stats.is_rx_elem_toosmall++; \ 51143952Sdas _action; \ 52143952Sdas } \ 53143952Sdas} while (0) 54143952Sdas 55112745Smike#ifdef IEEE80211_DEBUG 56112745Smikevoid ieee80211_ssid_mismatch(struct ieee80211vap *, const char *tag, 57112745Smike uint8_t mac[IEEE80211_ADDR_LEN], uint8_t *ssid); 58112745Smike 59112745Smike#define IEEE80211_VERIFY_SSID(_ni, _ssid, _action) do { \ 60102227Smike if ((_ssid)[1] != 0 && \ 61112237Smike ((_ssid)[1] != (_ni)->ni_esslen || \ 62102227Smike memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ 6390711Swollman if (ieee80211_msg_input(vap)) \ 6490711Swollman ieee80211_ssid_mismatch(vap, \ 65112237Smike ieee80211_mgt_subtype_name[subtype >> \ 66112237Smike IEEE80211_FC0_SUBTYPE_SHIFT], \ 67112237Smike wh->i_addr2, _ssid); \ 68112237Smike vap->iv_stats.is_rx_ssidmismatch++; \ 69112237Smike _action; \ 70112237Smike } \ 71112237Smike} while (0) 72112237Smike#else /* !IEEE80211_DEBUG */ 73112237Smike#define IEEE80211_VERIFY_SSID(_ni, _ssid, _action) do { \ 74112237Smike if ((_ssid)[1] != 0 && \ 75112237Smike ((_ssid)[1] != (_ni)->ni_esslen || \ 76112237Smike memcmp((_ssid) + 2, (_ni)->ni_essid, (_ssid)[1]) != 0)) { \ 77112237Smike vap->iv_stats.is_rx_ssidmismatch++; \ 78112237Smike _action; \ 79112237Smike } \ 80112237Smike} while (0) 81112237Smike#endif /* !IEEE80211_DEBUG */ 82112237Smike 83112237Smike/* unalligned little endian access */ 84112237Smike#define LE_READ_2(p) \ 85112237Smike ((uint16_t) \ 86112237Smike ((((const uint8_t *)(p))[0] ) | \ 87112237Smike (((const uint8_t *)(p))[1] << 8))) 88112237Smike#define LE_READ_4(p) \ 89112237Smike ((uint32_t) \ 90112237Smike ((((const uint8_t *)(p))[0] ) | \ 91112237Smike (((const uint8_t *)(p))[1] << 8) | \ 92112237Smike (((const uint8_t *)(p))[2] << 16) | \ 93112237Smike (((const uint8_t *)(p))[3] << 24))) 94112237Smike 95112408Smikestatic __inline int 962939Sbdeiswpaoui(const uint8_t *frm) 97205792Sed{ 982939Sbde return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); 991541Srgrimes} 10024751Sbde 1011541Srgrimesstatic __inline int 102238703Skibiswmeoui(const uint8_t *frm) 1031541Srgrimes{ 104112237Smike return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI); 10514493Shsu} 10614493Shsu 10714493Shsustatic __inline int 108112237Smikeiswmeparam(const uint8_t *frm) 109112237Smike{ 110112237Smike return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && 111112237Smike frm[6] == WME_PARAM_OUI_SUBTYPE; 112205792Sed} 113205792Sed 114205792Sedstatic __inline int 115112237Smikeiswmeinfo(const uint8_t *frm) 116112237Smike{ 11790711Swollman return frm[1] > 5 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI) && 118112237Smike frm[6] == WME_INFO_OUI_SUBTYPE; 1191541Srgrimes} 120238703Skib 1211541Srgrimesstatic __inline int 1221541Srgrimesisatherosoui(const uint8_t *frm) 123130640Sphk{ 12414493Shsu return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); 12514493Shsu} 12614493Shsu 12714493Shsustatic __inline int 12814493Shsuistdmaoui(const uint8_t *frm) 129130640Sphk{ 130205792Sed return frm[1] > 3 && LE_READ_4(frm+2) == ((TDMA_OUI_TYPE<<24)|TDMA_OUI); 131205792Sed} 132205792Sed 13314493Shsustatic __inline int 134143952Sdasishtcapoui(const uint8_t *frm) 135143952Sdas{ 13690711Swollman return frm[1] > 3 && LE_READ_4(frm+2) == ((BCM_OUI_HTCAP<<24)|BCM_OUI); 137112237Smike} 138112237Smike 139205792Sedstatic __inline int 14098644Smckusickishtinfooui(const uint8_t *frm) 141205792Sed{ 14298644Smckusick return frm[1] > 3 && LE_READ_4(frm+2) == ((BCM_OUI_HTINFO<<24)|BCM_OUI); 14398644Smckusick} 14498644Smckusick 14598644Smckusickvoid ieee80211_deliver_data(struct ieee80211vap *, 14698644Smckusick struct ieee80211_node *, struct mbuf *); 14798644Smckusickstruct mbuf *ieee80211_defrag(struct ieee80211_node *, 148112237Smike struct mbuf *, int); 149112237Smikestruct mbuf *ieee80211_decap(struct ieee80211vap *, struct mbuf *, int); 1501541Srgrimesstruct mbuf *ieee80211_decap1(struct mbuf *, int *); 15135938Sdysonint ieee80211_setup_rates(struct ieee80211_node *ni, 152238703Skib const uint8_t *rates, const uint8_t *xrates, int flags); 15335938Sdysonvoid ieee80211_send_error(struct ieee80211_node *, 154130640Sphk const uint8_t mac[IEEE80211_ADDR_LEN], int subtype, int arg); 15535938Sdysonint ieee80211_alloc_challenge(struct ieee80211_node *); 156112237Smikeint ieee80211_parse_beacon(struct ieee80211_node *, struct mbuf *, 157112237Smike struct ieee80211_scanparams *); 15835938Sdysonint ieee80211_parse_action(struct ieee80211_node *, struct mbuf *); 15935938Sdyson#endif /* _NET80211_IEEE80211_INPUT_H_ */ 160130640Sphk