The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/net80211/ieee80211_output.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: ieee80211_output.c,v 1.45 2006/11/16 01:33:41 christos Exp $   */
    2 /*-
    3  * Copyright (c) 2001 Atsushi Onoe
    4  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission.
   17  *
   18  * Alternatively, this software may be distributed under the terms of the
   19  * GNU General Public License ("GPL") version 2 as published by the Free
   20  * Software Foundation.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 #ifdef __FreeBSD__
   36 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_output.c,v 1.34 2005/08/10 16:22:29 sam Exp $");
   37 #endif
   38 #ifdef __NetBSD__
   39 __KERNEL_RCSID(0, "$NetBSD: ieee80211_output.c,v 1.45 2006/11/16 01:33:41 christos Exp $");
   40 #endif
   41 
   42 #include "opt_inet.h"
   43 
   44 #ifdef __NetBSD__
   45 #include "bpfilter.h"
   46 #endif /* __NetBSD__ */
   47 
   48 #include <sys/param.h>
   49 #include <sys/systm.h> 
   50 #include <sys/mbuf.h>   
   51 #include <sys/kernel.h>
   52 #include <sys/endian.h>
   53 #include <sys/errno.h>
   54 #include <sys/proc.h>
   55 #include <sys/sysctl.h>
   56 
   57 #include <net/if.h>
   58 #include <net/if_llc.h>
   59 #include <net/if_media.h>
   60 #include <net/if_arp.h>
   61 #include <net/if_ether.h>
   62 #include <net/if_llc.h>
   63 #include <net/if_vlanvar.h>
   64 
   65 #include <net80211/ieee80211_netbsd.h>
   66 #include <net80211/ieee80211_var.h>
   67 
   68 #if NBPFILTER > 0
   69 #include <net/bpf.h>
   70 #endif
   71 
   72 #ifdef INET
   73 #include <netinet/in.h>
   74 #include <netinet/in_systm.h>
   75 #include <netinet/in_var.h>
   76 #include <netinet/ip.h>
   77 #include <net/if_ether.h>
   78 #endif
   79 
   80 #ifdef IEEE80211_DEBUG
   81 /*
   82  * Decide if an outbound management frame should be
   83  * printed when debugging is enabled.  This filters some
   84  * of the less interesting frames that come frequently
   85  * (e.g. beacons).
   86  */
   87 static __inline int
   88 doprint(struct ieee80211com *ic, int subtype)
   89 {
   90         switch (subtype) {
   91         case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
   92                 return (ic->ic_opmode == IEEE80211_M_IBSS);
   93         }
   94         return 1;
   95 }
   96 #endif
   97 
   98 /*
   99  * Set the direction field and address fields of an outgoing
  100  * non-QoS frame.  Note this should be called early on in
  101  * constructing a frame as it sets i_fc[1]; other bits can
  102  * then be or'd in.
  103  */
  104 static void
  105 ieee80211_send_setup(struct ieee80211com *ic,
  106         struct ieee80211_node *ni,
  107         struct ieee80211_frame *wh,
  108         int type,
  109         const u_int8_t sa[IEEE80211_ADDR_LEN],
  110         const u_int8_t da[IEEE80211_ADDR_LEN],
  111         const u_int8_t bssid[IEEE80211_ADDR_LEN])
  112 {
  113 #define WH4(wh) ((struct ieee80211_frame_addr4 *)wh)
  114 
  115         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | type;
  116         if ((type & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_DATA) {
  117                 switch (ic->ic_opmode) {
  118                 case IEEE80211_M_STA:
  119                         wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
  120                         IEEE80211_ADDR_COPY(wh->i_addr1, bssid);
  121                         IEEE80211_ADDR_COPY(wh->i_addr2, sa);
  122                         IEEE80211_ADDR_COPY(wh->i_addr3, da);
  123                         break;
  124                 case IEEE80211_M_IBSS:
  125                 case IEEE80211_M_AHDEMO:
  126                         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
  127                         IEEE80211_ADDR_COPY(wh->i_addr1, da);
  128                         IEEE80211_ADDR_COPY(wh->i_addr2, sa);
  129                         IEEE80211_ADDR_COPY(wh->i_addr3, bssid);
  130                         break;
  131                 case IEEE80211_M_HOSTAP:
  132                         wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
  133                         IEEE80211_ADDR_COPY(wh->i_addr1, da);
  134                         IEEE80211_ADDR_COPY(wh->i_addr2, bssid);
  135                         IEEE80211_ADDR_COPY(wh->i_addr3, sa);
  136                         break;
  137                 case IEEE80211_M_MONITOR:       /* NB: to quiet compiler */
  138                         break;
  139                 }
  140         } else {
  141                 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
  142                 IEEE80211_ADDR_COPY(wh->i_addr1, da);
  143                 IEEE80211_ADDR_COPY(wh->i_addr2, sa);
  144                 IEEE80211_ADDR_COPY(wh->i_addr3, bssid);
  145         }
  146         *(u_int16_t *)&wh->i_dur[0] = 0;
  147         /* NB: use non-QoS tid */
  148         *(u_int16_t *)&wh->i_seq[0] =
  149             htole16(ni->ni_txseqs[0] << IEEE80211_SEQ_SEQ_SHIFT);
  150         ni->ni_txseqs[0]++;
  151 #undef WH4
  152 }
  153 
  154 /*
  155  * Send a management frame to the specified node.  The node pointer
  156  * must have a reference as the pointer will be passed to the driver
  157  * and potentially held for a long time.  If the frame is successfully
  158  * dispatched to the driver, then it is responsible for freeing the
  159  * reference (and potentially free'ing up any associated storage).
  160  */
  161 static int
  162 ieee80211_mgmt_output(struct ieee80211com *ic, struct ieee80211_node *ni,
  163     struct mbuf *m, int type, int timer)
  164 {
  165         struct ifnet *ifp = ic->ic_ifp;
  166         struct ieee80211_frame *wh;
  167 
  168         IASSERT(ni != NULL, ("null node"));
  169 
  170         /*
  171          * Yech, hack alert!  We want to pass the node down to the
  172          * driver's start routine.  If we don't do so then the start
  173          * routine must immediately look it up again and that can
  174          * cause a lock order reversal if, for example, this frame
  175          * is being sent because the station is being timedout and
  176          * the frame being sent is a DEAUTH message.  We could stick
  177          * this in an m_tag and tack that on to the mbuf.  However
  178          * that's rather expensive to do for every frame so instead
  179          * we stuff it in the rcvif field since outbound frames do
  180          * not (presently) use this.
  181          */
  182         M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
  183         if (m == NULL)
  184                 return ENOMEM;
  185 #ifdef __FreeBSD__
  186         KASSERT(m->m_pkthdr.rcvif == NULL, ("rcvif not null"));
  187 #endif
  188         m->m_pkthdr.rcvif = (void *)ni;
  189 
  190         wh = mtod(m, struct ieee80211_frame *);
  191         ieee80211_send_setup(ic, ni, wh, 
  192                 IEEE80211_FC0_TYPE_MGT | type,
  193                 ic->ic_myaddr, ni->ni_macaddr, ni->ni_bssid);
  194         if ((m->m_flags & M_LINK0) != 0 && ni->ni_challenge != NULL) {
  195                 m->m_flags &= ~M_LINK0;
  196                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
  197                         "[%s] encrypting frame (%s)\n",
  198                         ether_sprintf(wh->i_addr1), __func__);
  199                 wh->i_fc[1] |= IEEE80211_FC1_WEP;
  200         }
  201 #ifdef IEEE80211_DEBUG
  202         /* avoid printing too many frames */
  203         if ((ieee80211_msg_debug(ic) && doprint(ic, type)) ||
  204             ieee80211_msg_dumppkts(ic)) {
  205                 printf("[%s] send %s on channel %u\n",
  206                     ether_sprintf(wh->i_addr1),
  207                     ieee80211_mgt_subtype_name[
  208                         (type & IEEE80211_FC0_SUBTYPE_MASK) >>
  209                                 IEEE80211_FC0_SUBTYPE_SHIFT],
  210                     ieee80211_chan2ieee(ic, ic->ic_curchan));
  211         }
  212 #endif
  213         IEEE80211_NODE_STAT(ni, tx_mgmt);
  214         IF_ENQUEUE(&ic->ic_mgtq, m);
  215         if (timer) {
  216                 /*
  217                  * Set the mgt frame timeout.
  218                  */
  219                 ic->ic_mgt_timer = timer;
  220                 ifp->if_timer = 1;
  221         }
  222         (*ifp->if_start)(ifp);
  223         return 0;
  224 }
  225 
  226 /*
  227  * Send a null data frame to the specified node.
  228  *
  229  * NB: the caller is assumed to have setup a node reference
  230  *     for use; this is necessary to deal with a race condition
  231  *     when probing for inactive stations.
  232  */
  233 int
  234 ieee80211_send_nulldata(struct ieee80211_node *ni)
  235 {
  236         struct ieee80211com *ic = ni->ni_ic;
  237         struct ifnet *ifp = ic->ic_ifp;
  238         struct mbuf *m;
  239         struct ieee80211_frame *wh;
  240 
  241         MGETHDR(m, M_NOWAIT, MT_HEADER);
  242         if (m == NULL) {
  243                 /* XXX debug msg */
  244                 ic->ic_stats.is_tx_nobuf++;
  245                 ieee80211_unref_node(&ni);
  246                 return ENOMEM;
  247         }
  248         m->m_pkthdr.rcvif = (void *) ni;
  249 
  250         wh = mtod(m, struct ieee80211_frame *);
  251         ieee80211_send_setup(ic, ni, wh,
  252                 IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_NODATA,
  253                 ic->ic_myaddr, ni->ni_macaddr, ni->ni_bssid);
  254         /* NB: power management bit is never sent by an AP */
  255         if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
  256             ic->ic_opmode != IEEE80211_M_HOSTAP)
  257                 wh->i_fc[1] |= IEEE80211_FC1_PWR_MGT;
  258         m->m_len = m->m_pkthdr.len = sizeof(struct ieee80211_frame);
  259 
  260         IEEE80211_NODE_STAT(ni, tx_data);
  261 
  262         IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS,
  263             "[%s] send null data frame on channel %u, pwr mgt %s\n",
  264             ether_sprintf(ni->ni_macaddr),
  265             ieee80211_chan2ieee(ic, ic->ic_curchan),
  266             wh->i_fc[1] & IEEE80211_FC1_PWR_MGT ? "ena" : "dis");
  267 
  268         IF_ENQUEUE(&ic->ic_mgtq, m);            /* cheat */
  269         (*ifp->if_start)(ifp);
  270 
  271         return 0;
  272 }
  273 
  274 /* 
  275  * Assign priority to a frame based on any vlan tag assigned
  276  * to the station and/or any Diffserv setting in an IP header.
  277  * Finally, if an ACM policy is setup (in station mode) it's
  278  * applied.
  279  */
  280 int
  281 ieee80211_classify(struct ieee80211com *ic, struct mbuf *m, struct ieee80211_node *ni)
  282 {
  283         int v_wme_ac, d_wme_ac, ac;
  284 #ifdef INET
  285         struct ether_header *eh;
  286 #endif
  287 
  288         if ((ni->ni_flags & IEEE80211_NODE_QOS) == 0) {
  289                 ac = WME_AC_BE;
  290                 goto done;
  291         }
  292 
  293         /* 
  294          * If node has a vlan tag then all traffic
  295          * to it must have a matching tag.
  296          */
  297         v_wme_ac = 0;
  298         if (ni->ni_vlan != 0) {
  299                 /* XXX used to check ec_nvlans. */
  300                 struct m_tag *mtag = m_tag_find(m, PACKET_TAG_VLAN, NULL);
  301                 if (mtag == NULL) {
  302                         IEEE80211_NODE_STAT(ni, tx_novlantag);
  303                         return 1;
  304                 }
  305                 if (EVL_VLANOFTAG(VLAN_TAG_VALUE(mtag)) !=
  306                     EVL_VLANOFTAG(ni->ni_vlan)) {
  307                         IEEE80211_NODE_STAT(ni, tx_vlanmismatch);
  308                         return 1;
  309                 }
  310                 /* map vlan priority to AC */
  311                 switch (EVL_PRIOFTAG(ni->ni_vlan)) {
  312                 case 1:
  313                 case 2:
  314                         v_wme_ac = WME_AC_BK;
  315                         break;
  316                 case 0:
  317                 case 3:
  318                         v_wme_ac = WME_AC_BE;
  319                         break;
  320                 case 4:
  321                 case 5:
  322                         v_wme_ac = WME_AC_VI;
  323                         break;
  324                 case 6:
  325                 case 7:
  326                         v_wme_ac = WME_AC_VO;
  327                         break;
  328                 }
  329         }
  330 
  331 #ifdef INET
  332         eh = mtod(m, struct ether_header *);
  333         if (eh->ether_type == htons(ETHERTYPE_IP)) {
  334                 const struct ip *ip = (struct ip *)
  335                         (mtod(m, u_int8_t *) + sizeof (*eh));
  336                 /*
  337                  * IP frame, map the TOS field.
  338                  */
  339                 switch (ip->ip_tos) {
  340                 case 0x08:
  341                 case 0x20:
  342                         d_wme_ac = WME_AC_BK;   /* background */
  343                         break;
  344                 case 0x28:
  345                 case 0xa0:
  346                         d_wme_ac = WME_AC_VI;   /* video */
  347                         break;
  348                 case 0x30:                      /* voice */
  349                 case 0xe0:
  350                 case 0x88:                      /* XXX UPSD */
  351                 case 0xb8:
  352                         d_wme_ac = WME_AC_VO;
  353                         break;
  354                 default:
  355                         d_wme_ac = WME_AC_BE;
  356                         break;
  357                 }
  358         } else {
  359 #endif /* INET */
  360                 d_wme_ac = WME_AC_BE;
  361 #ifdef INET
  362         }
  363 #endif
  364         /*
  365          * Use highest priority AC.
  366          */
  367         if (v_wme_ac > d_wme_ac)
  368                 ac = v_wme_ac;
  369         else
  370                 ac = d_wme_ac;
  371 
  372         /*
  373          * Apply ACM policy.
  374          */
  375         if (ic->ic_opmode == IEEE80211_M_STA) {
  376                 static const int acmap[4] = {
  377                         WME_AC_BK,      /* WME_AC_BE */
  378                         WME_AC_BK,      /* WME_AC_BK */
  379                         WME_AC_BE,      /* WME_AC_VI */
  380                         WME_AC_VI,      /* WME_AC_VO */
  381                 };
  382                 while (ac != WME_AC_BK &&
  383                     ic->ic_wme.wme_wmeBssChanParams.cap_wmeParams[ac].wmep_acm)
  384                         ac = acmap[ac];
  385         }
  386 done:
  387         M_WME_SETAC(m, ac);
  388         return 0;
  389 }
  390 
  391 /*
  392  * Insure there is sufficient contiguous space to encapsulate the
  393  * 802.11 data frame.  If room isn't already there, arrange for it.
  394  * Drivers and cipher modules assume we have done the necessary work
  395  * and fail rudely if they don't find the space they need.
  396  */
  397 static struct mbuf *
  398 ieee80211_mbuf_adjust(struct ieee80211com *ic, int hdrsize,
  399         struct ieee80211_key *key, struct mbuf *m)
  400 {
  401 #define TO_BE_RECLAIMED (sizeof(struct ether_header) - sizeof(struct llc))
  402         int needed_space = hdrsize;
  403         int wlen = 0;
  404 
  405         if (key != NULL) {
  406                 /* XXX belongs in crypto code? */
  407                 needed_space += key->wk_cipher->ic_header;
  408                 /* XXX frags */
  409         }
  410         /*
  411          * We know we are called just before stripping an Ethernet
  412          * header and prepending an LLC header.  This means we know
  413          * there will be
  414          *      sizeof(struct ether_header) - sizeof(struct llc)
  415          * bytes recovered to which we need additional space for the
  416          * 802.11 header and any crypto header.
  417          */
  418         /* XXX check trailing space and copy instead? */
  419         if (M_LEADINGSPACE(m) < needed_space - TO_BE_RECLAIMED) {
  420                 struct mbuf *n = m_gethdr(M_NOWAIT, m->m_type);
  421                 if (n == NULL) {
  422                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_OUTPUT,
  423                             "%s: cannot expand storage\n", __func__);
  424                         ic->ic_stats.is_tx_nobuf++;
  425                         m_freem(m);
  426                         return NULL;
  427                 }
  428                 IASSERT(needed_space <= MHLEN,
  429                     ("not enough room, need %u got %zu\n", needed_space, MHLEN));
  430                 /*
  431                  * Setup new mbuf to have leading space to prepend the
  432                  * 802.11 header and any crypto header bits that are
  433                  * required (the latter are added when the driver calls
  434                  * back to ieee80211_crypto_encap to do crypto encapsulation).
  435                  */
  436                 /* NB: must be first 'cuz it clobbers m_data */
  437                 M_MOVE_PKTHDR(n, m);
  438                 n->m_len = 0;                   /* NB: m_gethdr does not set */
  439                 n->m_data += needed_space;
  440                 /*
  441                  * Pull up Ethernet header to create the expected layout.
  442                  * We could use m_pullup but that's overkill (i.e. we don't
  443                  * need the actual data) and it cannot fail so do it inline
  444                  * for speed.
  445                  */
  446                 /* NB: struct ether_header is known to be contiguous */
  447                 n->m_len += sizeof(struct ether_header);
  448                 m->m_len -= sizeof(struct ether_header);
  449                 m->m_data += sizeof(struct ether_header);
  450                 /*
  451                  * Replace the head of the chain.
  452                  */
  453                 n->m_next = m;
  454                 m = n;
  455         } else {
  456                 /* We will overwrite the ethernet header in the
  457                  * 802.11 encapsulation stage.  Make sure that it
  458                  * is writable.
  459                  */
  460                 wlen = sizeof(struct ether_header);
  461         }
  462 
  463         /*
  464          * If we're going to s/w encrypt the mbuf chain make sure it is
  465          * writable.
  466          */
  467         if (key != NULL && (key->wk_flags & IEEE80211_KEY_SWCRYPT) != 0)
  468                 wlen = M_COPYALL;
  469 
  470         if (wlen != 0 && m_makewritable(&m, 0, wlen, M_DONTWAIT) != 0) {
  471                 m_freem(m);
  472                 return NULL;
  473         }
  474         return m;
  475 #undef TO_BE_RECLAIMED
  476 }
  477 
  478 /*
  479  * Return the transmit key to use in sending a unicast frame.
  480  * If a unicast key is set we use that.  When no unicast key is set
  481  * we fall back to the default transmit key.
  482  */ 
  483 static __inline struct ieee80211_key *
  484 ieee80211_crypto_getucastkey(struct ieee80211com *ic, struct ieee80211_node *ni)
  485 {
  486         if (IEEE80211_KEY_UNDEFINED(ni->ni_ucastkey)) {
  487                 if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE ||
  488                     IEEE80211_KEY_UNDEFINED(ic->ic_nw_keys[ic->ic_def_txkey]))
  489                         return NULL;
  490                 return &ic->ic_nw_keys[ic->ic_def_txkey];
  491         } else {
  492                 return &ni->ni_ucastkey;
  493         }
  494 }
  495 
  496 /*
  497  * Return the transmit key to use in sending a multicast frame.
  498  * Multicast traffic always uses the group key which is installed as
  499  * the default tx key.
  500  */ 
  501 static __inline struct ieee80211_key *
  502 ieee80211_crypto_getmcastkey(struct ieee80211com *ic,
  503     struct ieee80211_node *ni)
  504 {
  505         if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE ||
  506             IEEE80211_KEY_UNDEFINED(ic->ic_nw_keys[ic->ic_def_txkey]))
  507                 return NULL;
  508         return &ic->ic_nw_keys[ic->ic_def_txkey];
  509 }
  510 
  511 /*
  512  * Encapsulate an outbound data frame.  The mbuf chain is updated.
  513  * If an error is encountered NULL is returned.  The caller is required
  514  * to provide a node reference and pullup the ethernet header in the
  515  * first mbuf.
  516  */
  517 struct mbuf *
  518 ieee80211_encap(struct ieee80211com *ic, struct mbuf *m,
  519         struct ieee80211_node *ni)
  520 {
  521         struct ether_header eh;
  522         struct ieee80211_frame *wh;
  523         struct ieee80211_key *key;
  524         struct llc *llc;
  525         int hdrsize, datalen, addqos;
  526 
  527         IASSERT(m->m_len >= sizeof(eh), ("no ethernet header!"));
  528         memcpy(&eh, mtod(m, caddr_t), sizeof(struct ether_header));
  529 
  530         /*
  531          * Insure space for additional headers.  First identify
  532          * transmit key to use in calculating any buffer adjustments
  533          * required.  This is also used below to do privacy
  534          * encapsulation work.  Then calculate the 802.11 header
  535          * size and any padding required by the driver.
  536          *
  537          * Note key may be NULL if we fall back to the default
  538          * transmit key and that is not set.  In that case the
  539          * buffer may not be expanded as needed by the cipher
  540          * routines, but they will/should discard it.
  541          */
  542         if (ic->ic_flags & IEEE80211_F_PRIVACY) {
  543                 if (ic->ic_opmode == IEEE80211_M_STA ||
  544                     !IEEE80211_IS_MULTICAST(eh.ether_dhost))
  545                         key = ieee80211_crypto_getucastkey(ic, ni);
  546                 else
  547                         key = ieee80211_crypto_getmcastkey(ic, ni);
  548                 if (key == NULL && eh.ether_type != htons(ETHERTYPE_PAE)) {
  549                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  550                             "[%s] no default transmit key (%s) deftxkey %u\n",
  551                             ether_sprintf(eh.ether_dhost), __func__,
  552                             ic->ic_def_txkey);
  553                         ic->ic_stats.is_tx_nodefkey++;
  554                 }
  555         } else
  556                 key = NULL;
  557         /* XXX 4-address format */
  558         /*
  559          * XXX Some ap's don't handle QoS-encapsulated EAPOL
  560          * frames so suppress use.  This may be an issue if other
  561          * ap's require all data frames to be QoS-encapsulated
  562          * once negotiated in which case we'll need to make this
  563          * configurable.
  564          */
  565         addqos = (ni->ni_flags & IEEE80211_NODE_QOS) &&
  566                  eh.ether_type != htons(ETHERTYPE_PAE);
  567         if (addqos)
  568                 hdrsize = sizeof(struct ieee80211_qosframe);
  569         else
  570                 hdrsize = sizeof(struct ieee80211_frame);
  571         if (ic->ic_flags & IEEE80211_F_DATAPAD)
  572                 hdrsize = roundup(hdrsize, sizeof(u_int32_t));
  573         m = ieee80211_mbuf_adjust(ic, hdrsize, key, m);
  574         if (m == NULL) {
  575                 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */
  576                 goto bad;
  577         }
  578 
  579         /* NB: this could be optimized because of ieee80211_mbuf_adjust */
  580         m_adj(m, sizeof(struct ether_header) - sizeof(struct llc));
  581         llc = mtod(m, struct llc *);
  582         llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
  583         llc->llc_control = LLC_UI;
  584         llc->llc_snap.org_code[0] = 0;
  585         llc->llc_snap.org_code[1] = 0;
  586         llc->llc_snap.org_code[2] = 0;
  587         llc->llc_snap.ether_type = eh.ether_type;
  588         datalen = m->m_pkthdr.len;              /* NB: w/o 802.11 header */
  589 
  590         M_PREPEND(m, hdrsize, M_DONTWAIT);
  591         if (m == NULL) {
  592                 ic->ic_stats.is_tx_nobuf++;
  593                 goto bad;
  594         }
  595         wh = mtod(m, struct ieee80211_frame *);
  596         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
  597         *(u_int16_t *)wh->i_dur = 0;
  598         switch (ic->ic_opmode) {
  599         case IEEE80211_M_STA:
  600                 wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
  601                 IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_bssid);
  602                 IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
  603                 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost);
  604                 break;
  605         case IEEE80211_M_IBSS:
  606         case IEEE80211_M_AHDEMO:
  607                 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
  608                 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
  609                 IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
  610                 /*
  611                  * NB: always use the bssid from ic_bss as the
  612                  *     neighbor's may be stale after an ibss merge
  613                  */
  614                 IEEE80211_ADDR_COPY(wh->i_addr3, ic->ic_bss->ni_bssid);
  615                 break;
  616         case IEEE80211_M_HOSTAP:
  617 #ifndef IEEE80211_NO_HOSTAP
  618                 wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
  619                 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
  620                 IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid);
  621                 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost);
  622 #endif /* !IEEE80211_NO_HOSTAP */
  623                 break;
  624         case IEEE80211_M_MONITOR:
  625                 goto bad;
  626         }
  627         if (m->m_flags & M_MORE_DATA)
  628                 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
  629         if (addqos) {
  630                 struct ieee80211_qosframe *qwh =
  631                         (struct ieee80211_qosframe *) wh;
  632                 int ac, tid;
  633 
  634                 ac = M_WME_GETAC(m);
  635                 /* map from access class/queue to 11e header priorty value */
  636                 tid = WME_AC_TO_TID(ac);
  637                 qwh->i_qos[0] = tid & IEEE80211_QOS_TID;
  638                 if (ic->ic_wme.wme_wmeChanParams.cap_wmeParams[ac].wmep_noackPolicy)
  639                         qwh->i_qos[0] |= 1 << IEEE80211_QOS_ACKPOLICY_S;
  640                 qwh->i_qos[1] = 0;
  641                 qwh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS;
  642 
  643                 *(u_int16_t *)wh->i_seq =
  644                     htole16(ni->ni_txseqs[tid] << IEEE80211_SEQ_SEQ_SHIFT);
  645                 ni->ni_txseqs[tid]++;
  646         } else {
  647                 *(u_int16_t *)wh->i_seq =
  648                     htole16(ni->ni_txseqs[0] << IEEE80211_SEQ_SEQ_SHIFT);
  649                 ni->ni_txseqs[0]++;
  650         }
  651         if (key != NULL) {
  652                 /*
  653                  * IEEE 802.1X: send EAPOL frames always in the clear.
  654                  * WPA/WPA2: encrypt EAPOL keys when pairwise keys are set.
  655                  */
  656                 if (eh.ether_type != htons(ETHERTYPE_PAE) ||
  657                     ((ic->ic_flags & IEEE80211_F_WPA) &&
  658                      (ic->ic_opmode == IEEE80211_M_STA ?
  659                       !IEEE80211_KEY_UNDEFINED(*key) :
  660                       !IEEE80211_KEY_UNDEFINED(ni->ni_ucastkey)))) {
  661                         wh->i_fc[1] |= IEEE80211_FC1_WEP;
  662                         /* XXX do fragmentation */
  663                         if (!ieee80211_crypto_enmic(ic, key, m, 0)) {
  664                                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_OUTPUT,
  665                                     "[%s] enmic failed, discard frame\n",
  666                                     ether_sprintf(eh.ether_dhost));
  667                                 ic->ic_stats.is_crypto_enmicfail++;
  668                                 goto bad;
  669                         }
  670                 }
  671         }
  672 
  673         IEEE80211_NODE_STAT(ni, tx_data);
  674         IEEE80211_NODE_STAT_ADD(ni, tx_bytes, datalen);
  675 
  676         return m;
  677 bad:
  678         if (m != NULL)
  679                 m_freem(m);
  680         return NULL;
  681 }
  682 
  683 /*
  684  * Arguments in:
  685  *
  686  * paylen:  payload length (no FCS, no WEP header)
  687  *
  688  * hdrlen:  header length
  689  *
  690  * rate:    MSDU speed, units 500kb/s
  691  *
  692  * flags:   IEEE80211_F_SHPREAMBLE (use short preamble),
  693  *          IEEE80211_F_SHSLOT (use short slot length)
  694  *
  695  * Arguments out:
  696  *
  697  * d:       802.11 Duration field for RTS,
  698  *          802.11 Duration field for data frame,
  699  *          PLCP Length for data frame,
  700  *          residual octets at end of data slot
  701  */
  702 static int
  703 ieee80211_compute_duration1(int len, int use_ack, uint32_t icflags, int rate,
  704     struct ieee80211_duration *d)
  705 {
  706         int pre, ctsrate;
  707         int ack, bitlen, data_dur, remainder;
  708 
  709         /* RTS reserves medium for SIFS | CTS | SIFS | (DATA) | SIFS | ACK
  710          * DATA reserves medium for SIFS | ACK
  711          *
  712          * XXXMYC: no ACK on multicast/broadcast or control packets
  713          */
  714 
  715         bitlen = len * 8;
  716 
  717         pre = IEEE80211_DUR_DS_SIFS;
  718         if ((icflags & IEEE80211_F_SHPREAMBLE) != 0)
  719                 pre += IEEE80211_DUR_DS_SHORT_PREAMBLE + IEEE80211_DUR_DS_FAST_PLCPHDR;
  720         else
  721                 pre += IEEE80211_DUR_DS_LONG_PREAMBLE + IEEE80211_DUR_DS_SLOW_PLCPHDR;
  722 
  723         d->d_residue = 0;
  724         data_dur = (bitlen * 2) / rate;
  725         remainder = (bitlen * 2) % rate;
  726         if (remainder != 0) {
  727                 d->d_residue = (rate - remainder) / 16;
  728                 data_dur++;
  729         }
  730 
  731         switch (rate) {
  732         case 2:         /* 1 Mb/s */
  733         case 4:         /* 2 Mb/s */
  734                 /* 1 - 2 Mb/s WLAN: send ACK/CTS at 1 Mb/s */
  735                 ctsrate = 2;
  736                 break;
  737         case 11:        /* 5.5 Mb/s */
  738         case 22:        /* 11  Mb/s */
  739         case 44:        /* 22  Mb/s */
  740                 /* 5.5 - 11 Mb/s WLAN: send ACK/CTS at 2 Mb/s */
  741                 ctsrate = 4;
  742                 break;
  743         default:
  744                 /* TBD */
  745                 return -1;
  746         }
  747 
  748         d->d_plcp_len = data_dur;
  749 
  750         ack = (use_ack) ? pre + (IEEE80211_DUR_DS_SLOW_ACK * 2) / ctsrate : 0;
  751 
  752         d->d_rts_dur =
  753             pre + (IEEE80211_DUR_DS_SLOW_CTS * 2) / ctsrate +
  754             pre + data_dur +
  755             ack;
  756 
  757         d->d_data_dur = ack;
  758 
  759         return 0;
  760 }
  761 
  762 /*
  763  * Arguments in:
  764  *
  765  * wh:      802.11 header
  766  *
  767  * paylen:  payload length (no FCS, no WEP header)
  768  *
  769  * rate:    MSDU speed, units 500kb/s
  770  *
  771  * fraglen: fragment length, set to maximum (or higher) for no
  772  *          fragmentation
  773  *
  774  * flags:   IEEE80211_F_PRIVACY (hardware adds WEP),
  775  *          IEEE80211_F_SHPREAMBLE (use short preamble),
  776  *          IEEE80211_F_SHSLOT (use short slot length)
  777  *
  778  * Arguments out:
  779  *
  780  * d0: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields
  781  *     of first/only fragment
  782  *
  783  * dn: 802.11 Duration fields (RTS/Data), PLCP Length, Service fields
  784  *     of last fragment
  785  *
  786  * ieee80211_compute_duration assumes crypto-encapsulation, if any,
  787  * has already taken place.
  788  */
  789 int
  790 ieee80211_compute_duration(const struct ieee80211_frame_min *wh,
  791     const struct ieee80211_key *wk, int len,
  792     uint32_t icflags, int fraglen, int rate, struct ieee80211_duration *d0,
  793     struct ieee80211_duration *dn, int *npktp, int debug)
  794 {
  795         int ack, rc;
  796         int cryptolen,  /* crypto overhead: header+trailer */
  797             firstlen,   /* first fragment's payload + overhead length */
  798             hdrlen,     /* header length w/o driver padding */
  799             lastlen,    /* last fragment's payload length w/ overhead */
  800             lastlen0,   /* last fragment's payload length w/o overhead */
  801             npkt,       /* number of fragments */
  802             overlen,    /* non-802.11 header overhead per fragment */
  803             paylen;     /* payload length w/o overhead */
  804 
  805         hdrlen = ieee80211_anyhdrsize((const void *)wh);
  806 
  807         /* Account for padding required by the driver. */
  808         if (icflags & IEEE80211_F_DATAPAD)
  809                 paylen = len - roundup(hdrlen, sizeof(u_int32_t));
  810         else
  811                 paylen = len - hdrlen;
  812 
  813         overlen = IEEE80211_CRC_LEN;
  814 
  815         if (wk != NULL) {
  816                 cryptolen = wk->wk_cipher->ic_header +
  817                             wk->wk_cipher->ic_trailer;
  818                 paylen -= cryptolen;
  819                 overlen += cryptolen;
  820         }
  821 
  822         npkt = paylen / fraglen;
  823         lastlen0 = paylen % fraglen;
  824 
  825         if (npkt == 0)                  /* no fragments */
  826                 lastlen = paylen + overlen;
  827         else if (lastlen0 != 0) {       /* a short "tail" fragment */
  828                 lastlen = lastlen0 + overlen;
  829                 npkt++;
  830         } else                          /* full-length "tail" fragment */
  831                 lastlen = fraglen + overlen;
  832 
  833         if (npktp != NULL)
  834                 *npktp = npkt;
  835 
  836         if (npkt > 1)
  837                 firstlen = fraglen + overlen;
  838         else
  839                 firstlen = paylen + overlen;
  840 
  841         if (debug) {
  842                 printf("%s: npkt %d firstlen %d lastlen0 %d lastlen %d "
  843                     "fraglen %d overlen %d len %d rate %d icflags %08x\n",
  844                     __func__, npkt, firstlen, lastlen0, lastlen, fraglen,
  845                     overlen, len, rate, icflags);
  846         }
  847 
  848         ack = !IEEE80211_IS_MULTICAST(wh->i_addr1) &&
  849             (wh->i_fc[1] & IEEE80211_FC0_TYPE_MASK) != IEEE80211_FC0_TYPE_CTL;
  850 
  851         rc = ieee80211_compute_duration1(firstlen + hdrlen,
  852             ack, icflags, rate, d0);
  853         if (rc == -1)
  854                 return rc;
  855 
  856         if (npkt <= 1) {
  857                 *dn = *d0;
  858                 return 0;
  859         }
  860         return ieee80211_compute_duration1(lastlen + hdrlen, ack, icflags, rate,
  861             dn);
  862 }
  863 
  864 /*
  865  * Add a supported rates element id to a frame.
  866  */
  867 static u_int8_t *
  868 ieee80211_add_rates(u_int8_t *frm, const struct ieee80211_rateset *rs)
  869 {
  870         int nrates;
  871 
  872         *frm++ = IEEE80211_ELEMID_RATES;
  873         nrates = rs->rs_nrates;
  874         if (nrates > IEEE80211_RATE_SIZE)
  875                 nrates = IEEE80211_RATE_SIZE;
  876         *frm++ = nrates;
  877         memcpy(frm, rs->rs_rates, nrates);
  878         return frm + nrates;
  879 }
  880 
  881 /*
  882  * Add an extended supported rates element id to a frame.
  883  */
  884 static u_int8_t *
  885 ieee80211_add_xrates(u_int8_t *frm, const struct ieee80211_rateset *rs)
  886 {
  887         /*
  888          * Add an extended supported rates element if operating in 11g mode.
  889          */
  890         if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
  891                 int nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
  892                 *frm++ = IEEE80211_ELEMID_XRATES;
  893                 *frm++ = nrates;
  894                 memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
  895                 frm += nrates;
  896         }
  897         return frm;
  898 }
  899 
  900 /* 
  901  * Add an ssid elemet to a frame.
  902  */
  903 static u_int8_t *
  904 ieee80211_add_ssid(u_int8_t *frm, const u_int8_t *ssid, u_int len)
  905 {
  906         *frm++ = IEEE80211_ELEMID_SSID;
  907         *frm++ = len;
  908         memcpy(frm, ssid, len);
  909         return frm + len;
  910 }
  911 
  912 /*
  913  * Add an erp element to a frame.
  914  */
  915 static u_int8_t *
  916 ieee80211_add_erp(u_int8_t *frm, struct ieee80211com *ic)
  917 {
  918         u_int8_t erp;
  919 
  920         *frm++ = IEEE80211_ELEMID_ERP;
  921         *frm++ = 1;
  922         erp = 0;
  923         if (ic->ic_nonerpsta != 0)
  924                 erp |= IEEE80211_ERP_NON_ERP_PRESENT;
  925         if (ic->ic_flags & IEEE80211_F_USEPROT)
  926                 erp |= IEEE80211_ERP_USE_PROTECTION;
  927         if (ic->ic_flags & IEEE80211_F_USEBARKER)
  928                 erp |= IEEE80211_ERP_LONG_PREAMBLE;
  929         *frm++ = erp;
  930         return frm;
  931 }
  932 
  933 static u_int8_t *
  934 ieee80211_setup_wpa_ie(struct ieee80211com *ic, u_int8_t *ie)
  935 {
  936 #define WPA_OUI_BYTES           0x00, 0x50, 0xf2
  937 #define ADDSHORT(frm, v) do {                   \
  938         frm[0] = (v) & 0xff;                    \
  939         frm[1] = (v) >> 8;                      \
  940         frm += 2;                               \
  941 } while (0)
  942 #define ADDSELECTOR(frm, sel) do {              \
  943         memcpy(frm, sel, 4);                    \
  944         frm += 4;                               \
  945 } while (0)
  946         static const u_int8_t oui[4] = { WPA_OUI_BYTES, WPA_OUI_TYPE };
  947         static const u_int8_t cipher_suite[][4] = {
  948                 { WPA_OUI_BYTES, WPA_CSE_WEP40 },       /* NB: 40-bit */
  949                 { WPA_OUI_BYTES, WPA_CSE_TKIP },
  950                 { 0x00, 0x00, 0x00, 0x00 },             /* XXX WRAP */
  951                 { WPA_OUI_BYTES, WPA_CSE_CCMP },
  952                 { 0x00, 0x00, 0x00, 0x00 },             /* XXX CKIP */
  953                 { WPA_OUI_BYTES, WPA_CSE_NULL },
  954         };
  955         static const u_int8_t wep104_suite[4] =
  956                 { WPA_OUI_BYTES, WPA_CSE_WEP104 };
  957         static const u_int8_t key_mgt_unspec[4] =
  958                 { WPA_OUI_BYTES, WPA_ASE_8021X_UNSPEC };
  959         static const u_int8_t key_mgt_psk[4] =
  960                 { WPA_OUI_BYTES, WPA_ASE_8021X_PSK };
  961         const struct ieee80211_rsnparms *rsn = &ic->ic_bss->ni_rsn;
  962         u_int8_t *frm = ie;
  963         u_int8_t *selcnt;
  964 
  965         *frm++ = IEEE80211_ELEMID_VENDOR;
  966         *frm++ = 0;                             /* length filled in below */
  967         memcpy(frm, oui, sizeof(oui));          /* WPA OUI */
  968         frm += sizeof(oui);
  969         ADDSHORT(frm, WPA_VERSION);
  970 
  971         /* XXX filter out CKIP */
  972 
  973         /* multicast cipher */
  974         if (rsn->rsn_mcastcipher == IEEE80211_CIPHER_WEP &&
  975             rsn->rsn_mcastkeylen >= 13)
  976                 ADDSELECTOR(frm, wep104_suite);
  977         else
  978                 ADDSELECTOR(frm, cipher_suite[rsn->rsn_mcastcipher]);
  979 
  980         /* unicast cipher list */
  981         selcnt = frm;
  982         ADDSHORT(frm, 0);                       /* selector count */
  983         if (rsn->rsn_ucastcipherset & (1<<IEEE80211_CIPHER_AES_CCM)) {
  984                 selcnt[0]++;
  985                 ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_AES_CCM]);
  986         }
  987         if (rsn->rsn_ucastcipherset & (1<<IEEE80211_CIPHER_TKIP)) {
  988                 selcnt[0]++;
  989                 ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_TKIP]);
  990         }
  991 
  992         /* authenticator selector list */
  993         selcnt = frm;
  994         ADDSHORT(frm, 0);                       /* selector count */
  995         if (rsn->rsn_keymgmtset & WPA_ASE_8021X_UNSPEC) {
  996                 selcnt[0]++;
  997                 ADDSELECTOR(frm, key_mgt_unspec);
  998         }
  999         if (rsn->rsn_keymgmtset & WPA_ASE_8021X_PSK) {
 1000                 selcnt[0]++;
 1001                 ADDSELECTOR(frm, key_mgt_psk);
 1002         }
 1003 
 1004         /* optional capabilities */
 1005         if (rsn->rsn_caps != 0 && rsn->rsn_caps != RSN_CAP_PREAUTH)
 1006                 ADDSHORT(frm, rsn->rsn_caps);
 1007 
 1008         /* calculate element length */
 1009         ie[1] = frm - ie - 2;
 1010         IASSERT(ie[1]+2 <= sizeof(struct ieee80211_ie_wpa),
 1011                 ("WPA IE too big, %u > %zu",
 1012                 ie[1]+2, sizeof(struct ieee80211_ie_wpa)));
 1013         return frm;
 1014 #undef ADDSHORT
 1015 #undef ADDSELECTOR
 1016 #undef WPA_OUI_BYTES
 1017 }
 1018 
 1019 static u_int8_t *
 1020 ieee80211_setup_rsn_ie(struct ieee80211com *ic, u_int8_t *ie)
 1021 {
 1022 #define RSN_OUI_BYTES           0x00, 0x0f, 0xac
 1023 #define ADDSHORT(frm, v) do {                   \
 1024         frm[0] = (v) & 0xff;                    \
 1025         frm[1] = (v) >> 8;                      \
 1026         frm += 2;                               \
 1027 } while (0)
 1028 #define ADDSELECTOR(frm, sel) do {              \
 1029         memcpy(frm, sel, 4);                    \
 1030         frm += 4;                               \
 1031 } while (0)
 1032         static const u_int8_t cipher_suite[][4] = {
 1033                 { RSN_OUI_BYTES, RSN_CSE_WEP40 },       /* NB: 40-bit */
 1034                 { RSN_OUI_BYTES, RSN_CSE_TKIP },
 1035                 { RSN_OUI_BYTES, RSN_CSE_WRAP },
 1036                 { RSN_OUI_BYTES, RSN_CSE_CCMP },
 1037                 { 0x00, 0x00, 0x00, 0x00 },             /* XXX CKIP */
 1038                 { RSN_OUI_BYTES, RSN_CSE_NULL },
 1039         };
 1040         static const u_int8_t wep104_suite[4] =
 1041                 { RSN_OUI_BYTES, RSN_CSE_WEP104 };
 1042         static const u_int8_t key_mgt_unspec[4] =
 1043                 { RSN_OUI_BYTES, RSN_ASE_8021X_UNSPEC };
 1044         static const u_int8_t key_mgt_psk[4] =
 1045                 { RSN_OUI_BYTES, RSN_ASE_8021X_PSK };
 1046         const struct ieee80211_rsnparms *rsn = &ic->ic_bss->ni_rsn;
 1047         u_int8_t *frm = ie;
 1048         u_int8_t *selcnt;
 1049 
 1050         *frm++ = IEEE80211_ELEMID_RSN;
 1051         *frm++ = 0;                             /* length filled in below */
 1052         ADDSHORT(frm, RSN_VERSION);
 1053 
 1054         /* XXX filter out CKIP */
 1055 
 1056         /* multicast cipher */
 1057         if (rsn->rsn_mcastcipher == IEEE80211_CIPHER_WEP &&
 1058             rsn->rsn_mcastkeylen >= 13)
 1059                 ADDSELECTOR(frm, wep104_suite);
 1060         else
 1061                 ADDSELECTOR(frm, cipher_suite[rsn->rsn_mcastcipher]);
 1062 
 1063         /* unicast cipher list */
 1064         selcnt = frm;
 1065         ADDSHORT(frm, 0);                       /* selector count */
 1066         if (rsn->rsn_ucastcipherset & (1<<IEEE80211_CIPHER_AES_CCM)) {
 1067                 selcnt[0]++;
 1068                 ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_AES_CCM]);
 1069         }
 1070         if (rsn->rsn_ucastcipherset & (1<<IEEE80211_CIPHER_TKIP)) {
 1071                 selcnt[0]++;
 1072                 ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_TKIP]);
 1073         }
 1074 
 1075         /* authenticator selector list */
 1076         selcnt = frm;
 1077         ADDSHORT(frm, 0);                       /* selector count */
 1078         if (rsn->rsn_keymgmtset & WPA_ASE_8021X_UNSPEC) {
 1079                 selcnt[0]++;
 1080                 ADDSELECTOR(frm, key_mgt_unspec);
 1081         }
 1082         if (rsn->rsn_keymgmtset & WPA_ASE_8021X_PSK) {
 1083                 selcnt[0]++;
 1084                 ADDSELECTOR(frm, key_mgt_psk);
 1085         }
 1086 
 1087         /* optional capabilities */
 1088         ADDSHORT(frm, rsn->rsn_caps);
 1089         /* XXX PMKID */
 1090 
 1091         /* calculate element length */
 1092         ie[1] = frm - ie - 2;
 1093         IASSERT(ie[1]+2 <= sizeof(struct ieee80211_ie_wpa),
 1094                 ("RSN IE too big, %u > %zu",
 1095                 ie[1]+2, sizeof(struct ieee80211_ie_wpa)));
 1096         return frm;
 1097 #undef ADDSELECTOR
 1098 #undef ADDSHORT
 1099 #undef RSN_OUI_BYTES
 1100 }
 1101 
 1102 /*
 1103  * Add a WPA/RSN element to a frame.
 1104  */
 1105 static u_int8_t *
 1106 ieee80211_add_wpa(u_int8_t *frm, struct ieee80211com *ic)
 1107 {
 1108 
 1109         IASSERT(ic->ic_flags & IEEE80211_F_WPA, ("no WPA/RSN!"));
 1110         if (ic->ic_flags & IEEE80211_F_WPA2)
 1111                 frm = ieee80211_setup_rsn_ie(ic, frm);
 1112         if (ic->ic_flags & IEEE80211_F_WPA1)
 1113                 frm = ieee80211_setup_wpa_ie(ic, frm);
 1114         return frm;
 1115 }
 1116 
 1117 #define WME_OUI_BYTES           0x00, 0x50, 0xf2
 1118 /*
 1119  * Add a WME information element to a frame.
 1120  */
 1121 static u_int8_t *
 1122 ieee80211_add_wme_info(u_int8_t *frm, struct ieee80211_wme_state *wme)
 1123 {
 1124         static const struct ieee80211_wme_info info = {
 1125                 .wme_id         = IEEE80211_ELEMID_VENDOR,
 1126                 .wme_len        = sizeof(struct ieee80211_wme_info) - 2,
 1127                 .wme_oui        = { WME_OUI_BYTES },
 1128                 .wme_type       = WME_OUI_TYPE,
 1129                 .wme_subtype    = WME_INFO_OUI_SUBTYPE,
 1130                 .wme_version    = WME_VERSION,
 1131                 .wme_info       = 0,
 1132         };
 1133         memcpy(frm, &info, sizeof(info));
 1134         return frm + sizeof(info); 
 1135 }
 1136 
 1137 /*
 1138  * Add a WME parameters element to a frame.
 1139  */
 1140 static u_int8_t *
 1141 ieee80211_add_wme_param(u_int8_t *frm, struct ieee80211_wme_state *wme)
 1142 {
 1143 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
 1144 #define ADDSHORT(frm, v) do {                   \
 1145         frm[0] = (v) & 0xff;                    \
 1146         frm[1] = (v) >> 8;                      \
 1147         frm += 2;                               \
 1148 } while (0)
 1149         /* NB: this works 'cuz a param has an info at the front */
 1150         static const struct ieee80211_wme_info param = {
 1151                 .wme_id         = IEEE80211_ELEMID_VENDOR,
 1152                 .wme_len        = sizeof(struct ieee80211_wme_param) - 2,
 1153                 .wme_oui        = { WME_OUI_BYTES },
 1154                 .wme_type       = WME_OUI_TYPE,
 1155                 .wme_subtype    = WME_PARAM_OUI_SUBTYPE,
 1156                 .wme_version    = WME_VERSION,
 1157         };
 1158         int i;
 1159 
 1160         memcpy(frm, &param, sizeof(param));
 1161         frm += __offsetof(struct ieee80211_wme_info, wme_info);
 1162         *frm++ = wme->wme_bssChanParams.cap_info;       /* AC info */
 1163         *frm++ = 0;                                     /* reserved field */
 1164         for (i = 0; i < WME_NUM_AC; i++) {
 1165                 const struct wmeParams *ac =
 1166                        &wme->wme_bssChanParams.cap_wmeParams[i];
 1167                 *frm++ = SM(i, WME_PARAM_ACI)
 1168                        | SM(ac->wmep_acm, WME_PARAM_ACM)
 1169                        | SM(ac->wmep_aifsn, WME_PARAM_AIFSN)
 1170                        ;
 1171                 *frm++ = SM(ac->wmep_logcwmax, WME_PARAM_LOGCWMAX)
 1172                        | SM(ac->wmep_logcwmin, WME_PARAM_LOGCWMIN)
 1173                        ;
 1174                 ADDSHORT(frm, ac->wmep_txopLimit);
 1175         }
 1176         return frm;
 1177 #undef SM
 1178 #undef ADDSHORT
 1179 }
 1180 #undef WME_OUI_BYTES
 1181 
 1182 /*
 1183  * Send a probe request frame with the specified ssid
 1184  * and any optional information element data.
 1185  */
 1186 int
 1187 ieee80211_send_probereq(struct ieee80211_node *ni,
 1188         const u_int8_t sa[IEEE80211_ADDR_LEN],
 1189         const u_int8_t da[IEEE80211_ADDR_LEN],
 1190         const u_int8_t bssid[IEEE80211_ADDR_LEN],
 1191         const u_int8_t *ssid, size_t ssidlen,
 1192         const void *optie, size_t optielen)
 1193 {
 1194         struct ieee80211com *ic = ni->ni_ic;
 1195         enum ieee80211_phymode mode;
 1196         struct ieee80211_frame *wh;
 1197         struct mbuf *m;
 1198         u_int8_t *frm;
 1199 
 1200         /*
 1201          * Hold a reference on the node so it doesn't go away until after
 1202          * the xmit is complete all the way in the driver.  On error we
 1203          * will remove our reference.
 1204          */
 1205         IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
 1206                 "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n",
 1207                 __func__, __LINE__,
 1208                 ni, ether_sprintf(ni->ni_macaddr),
 1209                 ieee80211_node_refcnt(ni)+1);
 1210         ieee80211_ref_node(ni);
 1211 
 1212         /*
 1213          * prreq frame format
 1214          *      [tlv] ssid
 1215          *      [tlv] supported rates
 1216          *      [tlv] extended supported rates
 1217          *      [tlv] user-specified ie's
 1218          */
 1219         m = ieee80211_getmgtframe(&frm,
 1220                  2 + IEEE80211_NWID_LEN
 1221                + 2 + IEEE80211_RATE_SIZE
 1222                + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 1223                + (optie != NULL ? optielen : 0)
 1224         );
 1225         if (m == NULL) {
 1226                 ic->ic_stats.is_tx_nobuf++;
 1227                 ieee80211_free_node(ni);
 1228                 return ENOMEM;
 1229         }
 1230 
 1231         frm = ieee80211_add_ssid(frm, ssid, ssidlen);
 1232         mode = ieee80211_chan2mode(ic, ic->ic_curchan);
 1233         frm = ieee80211_add_rates(frm, &ic->ic_sup_rates[mode]);
 1234         frm = ieee80211_add_xrates(frm, &ic->ic_sup_rates[mode]);
 1235 
 1236         if (optie != NULL) {
 1237                 memcpy(frm, optie, optielen);
 1238                 frm += optielen;
 1239         }
 1240         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1241 
 1242         M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
 1243         if (m == NULL)
 1244                 return ENOMEM;
 1245         IASSERT(m->m_pkthdr.rcvif == NULL, ("rcvif not null"));
 1246         m->m_pkthdr.rcvif = (void *)ni;
 1247 
 1248         wh = mtod(m, struct ieee80211_frame *);
 1249         ieee80211_send_setup(ic, ni, wh,
 1250                 IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ,
 1251                 sa, da, bssid);
 1252         /* XXX power management? */
 1253 
 1254         IEEE80211_NODE_STAT(ni, tx_probereq);
 1255         IEEE80211_NODE_STAT(ni, tx_mgmt);
 1256 
 1257         IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS,
 1258             "[%s] send probe req on channel %u\n",
 1259             ether_sprintf(wh->i_addr1),
 1260             ieee80211_chan2ieee(ic, ic->ic_curchan));
 1261 
 1262         IF_ENQUEUE(&ic->ic_mgtq, m);
 1263         (*ic->ic_ifp->if_start)(ic->ic_ifp);
 1264         return 0;
 1265 }
 1266 
 1267 /*
 1268  * Send a management frame.  The node is for the destination (or ic_bss
 1269  * when in station mode).  Nodes other than ic_bss have their reference
 1270  * count bumped to reflect our use for an indeterminant time.
 1271  */
 1272 int
 1273 ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
 1274         int type, int arg)
 1275 {
 1276 #define senderr(_x, _v) do { ic->ic_stats._v++; ret = _x; goto bad; } while (0)
 1277         struct mbuf *m;
 1278         u_int8_t *frm;
 1279         u_int16_t capinfo;
 1280         int has_challenge, is_shared_key, ret, timer, status;
 1281 
 1282         IASSERT(ni != NULL, ("null node"));
 1283 
 1284         /*
 1285          * Hold a reference on the node so it doesn't go away until after
 1286          * the xmit is complete all the way in the driver.  On error we
 1287          * will remove our reference.
 1288          */
 1289         IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
 1290                 "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n",
 1291                 __func__, __LINE__,
 1292                 ni, ether_sprintf(ni->ni_macaddr),
 1293                 ieee80211_node_refcnt(ni)+1);
 1294         ieee80211_ref_node(ni);
 1295 
 1296         timer = 0;
 1297         switch (type) {
 1298         case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
 1299                 /*
 1300                  * probe response frame format
 1301                  *      [8] time stamp
 1302                  *      [2] beacon interval
 1303                  *      [2] cabability information
 1304                  *      [tlv] ssid
 1305                  *      [tlv] supported rates
 1306                  *      [tlv] parameter set (FH/DS)
 1307                  *      [tlv] parameter set (IBSS)
 1308                  *      [tlv] extended rate phy (ERP)
 1309                  *      [tlv] extended supported rates
 1310                  *      [tlv] WPA
 1311                  *      [tlv] WME (optional)
 1312                  */
 1313                 m = ieee80211_getmgtframe(&frm,
 1314                          8
 1315                        + sizeof(u_int16_t)
 1316                        + sizeof(u_int16_t)
 1317                        + 2 + IEEE80211_NWID_LEN
 1318                        + 2 + IEEE80211_RATE_SIZE
 1319                        + 7      /* max(7,3) */
 1320                        + 6
 1321                        + 3
 1322                        + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 1323                        /* XXX !WPA1+WPA2 fits w/o a cluster */
 1324                        + (ic->ic_flags & IEEE80211_F_WPA ?
 1325                                 2*sizeof(struct ieee80211_ie_wpa) : 0)
 1326                        + sizeof(struct ieee80211_wme_param)
 1327                 );
 1328                 if (m == NULL)
 1329                         senderr(ENOMEM, is_tx_nobuf);
 1330 
 1331                 memset(frm, 0, 8);      /* timestamp should be filled later */
 1332                 frm += 8;
 1333                 *(u_int16_t *)frm = htole16(ic->ic_bss->ni_intval);
 1334                 frm += 2;
 1335                 if (ic->ic_opmode == IEEE80211_M_IBSS)
 1336                         capinfo = IEEE80211_CAPINFO_IBSS;
 1337                 else
 1338                         capinfo = IEEE80211_CAPINFO_ESS;
 1339                 if (ic->ic_flags & IEEE80211_F_PRIVACY)
 1340                         capinfo |= IEEE80211_CAPINFO_PRIVACY;
 1341                 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
 1342                     IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
 1343                         capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 1344                 if (ic->ic_flags & IEEE80211_F_SHSLOT)
 1345                         capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
 1346                 *(u_int16_t *)frm = htole16(capinfo);
 1347                 frm += 2;
 1348 
 1349                 frm = ieee80211_add_ssid(frm, ic->ic_bss->ni_essid,
 1350                                 ic->ic_bss->ni_esslen);
 1351                 frm = ieee80211_add_rates(frm, &ni->ni_rates);
 1352 
 1353                 if (ic->ic_phytype == IEEE80211_T_FH) {
 1354                         *frm++ = IEEE80211_ELEMID_FHPARMS;
 1355                         *frm++ = 5;
 1356                         *frm++ = ni->ni_fhdwell & 0x00ff;
 1357                         *frm++ = (ni->ni_fhdwell >> 8) & 0x00ff;
 1358                         *frm++ = IEEE80211_FH_CHANSET(
 1359                             ieee80211_chan2ieee(ic, ic->ic_curchan));
 1360                         *frm++ = IEEE80211_FH_CHANPAT(
 1361                             ieee80211_chan2ieee(ic, ic->ic_curchan));
 1362                         *frm++ = ni->ni_fhindex;
 1363                 } else {
 1364                         *frm++ = IEEE80211_ELEMID_DSPARMS;
 1365                         *frm++ = 1;
 1366                         *frm++ = ieee80211_chan2ieee(ic, ic->ic_curchan);
 1367                 }
 1368 
 1369                 if (ic->ic_opmode == IEEE80211_M_IBSS) {
 1370                         *frm++ = IEEE80211_ELEMID_IBSSPARMS;
 1371                         *frm++ = 2;
 1372                         *frm++ = 0; *frm++ = 0;         /* TODO: ATIM window */
 1373                 }
 1374                 if (ic->ic_flags & IEEE80211_F_WPA)
 1375                         frm = ieee80211_add_wpa(frm, ic);
 1376                 if (ic->ic_curmode == IEEE80211_MODE_11G)
 1377                         frm = ieee80211_add_erp(frm, ic);
 1378                 frm = ieee80211_add_xrates(frm, &ni->ni_rates);
 1379                 if (ic->ic_flags & IEEE80211_F_WME)
 1380                         frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
 1381                 m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1382                 break;
 1383 
 1384         case IEEE80211_FC0_SUBTYPE_AUTH:
 1385                 status = arg >> 16;
 1386                 arg &= 0xffff;
 1387                 has_challenge = ((arg == IEEE80211_AUTH_SHARED_CHALLENGE ||
 1388                     arg == IEEE80211_AUTH_SHARED_RESPONSE) &&
 1389                     ni->ni_challenge != NULL);
 1390 
 1391                 /*
 1392                  * Deduce whether we're doing open authentication or
 1393                  * shared key authentication.  We do the latter if
 1394                  * we're in the middle of a shared key authentication
 1395                  * handshake or if we're initiating an authentication
 1396                  * request and configured to use shared key.
 1397                  */
 1398                 is_shared_key = has_challenge ||
 1399                      arg >= IEEE80211_AUTH_SHARED_RESPONSE ||
 1400                      (arg == IEEE80211_AUTH_SHARED_REQUEST &&
 1401                       ic->ic_bss->ni_authmode == IEEE80211_AUTH_SHARED);
 1402 
 1403                 m = ieee80211_getmgtframe(&frm,
 1404                           3 * sizeof(u_int16_t)
 1405                         + (has_challenge && status == IEEE80211_STATUS_SUCCESS ?
 1406                                 sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0)
 1407                 );
 1408                 if (m == NULL)
 1409                         senderr(ENOMEM, is_tx_nobuf);
 1410 
 1411                 ((u_int16_t *)frm)[0] =
 1412                     (is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED)
 1413                                     : htole16(IEEE80211_AUTH_ALG_OPEN);
 1414                 ((u_int16_t *)frm)[1] = htole16(arg);   /* sequence number */
 1415                 ((u_int16_t *)frm)[2] = htole16(status);/* status */
 1416 
 1417                 if (has_challenge && status == IEEE80211_STATUS_SUCCESS) {
 1418                         ((u_int16_t *)frm)[3] =
 1419                             htole16((IEEE80211_CHALLENGE_LEN << 8) |
 1420                             IEEE80211_ELEMID_CHALLENGE);
 1421                         memcpy(&((u_int16_t *)frm)[4], ni->ni_challenge,
 1422                             IEEE80211_CHALLENGE_LEN);
 1423                         m->m_pkthdr.len = m->m_len =
 1424                                 4 * sizeof(u_int16_t) + IEEE80211_CHALLENGE_LEN;
 1425                         if (arg == IEEE80211_AUTH_SHARED_RESPONSE) {
 1426                                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
 1427                                     "[%s] request encrypt frame (%s)\n",
 1428                                     ether_sprintf(ni->ni_macaddr), __func__);
 1429                                 m->m_flags |= M_LINK0; /* WEP-encrypt, please */
 1430                         }
 1431                 } else
 1432                         m->m_pkthdr.len = m->m_len = 3 * sizeof(u_int16_t);
 1433 
 1434                 /* XXX not right for shared key */
 1435                 if (status == IEEE80211_STATUS_SUCCESS)
 1436                         IEEE80211_NODE_STAT(ni, tx_auth);
 1437                 else
 1438                         IEEE80211_NODE_STAT(ni, tx_auth_fail);
 1439 
 1440                 if (ic->ic_opmode == IEEE80211_M_STA)
 1441                         timer = IEEE80211_TRANS_WAIT;
 1442                 break;
 1443 
 1444         case IEEE80211_FC0_SUBTYPE_DEAUTH:
 1445                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
 1446                         "[%s] send station deauthenticate (reason %d)\n",
 1447                         ether_sprintf(ni->ni_macaddr), arg);
 1448                 m = ieee80211_getmgtframe(&frm, sizeof(u_int16_t));
 1449                 if (m == NULL)
 1450                         senderr(ENOMEM, is_tx_nobuf);
 1451                 *(u_int16_t *)frm = htole16(arg);       /* reason */
 1452                 m->m_pkthdr.len = m->m_len = sizeof(u_int16_t);
 1453 
 1454                 IEEE80211_NODE_STAT(ni, tx_deauth);
 1455                 IEEE80211_NODE_STAT_SET(ni, tx_deauth_code, arg);
 1456 
 1457                 ieee80211_node_unauthorize(ni);         /* port closed */
 1458                 break;
 1459 
 1460         case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
 1461         case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
 1462                 /*
 1463                  * asreq frame format
 1464                  *      [2] capability information
 1465                  *      [2] listen interval
 1466                  *      [6*] current AP address (reassoc only)
 1467                  *      [tlv] ssid
 1468                  *      [tlv] supported rates
 1469                  *      [tlv] extended supported rates
 1470                  *      [tlv] WME
 1471                  *      [tlv] user-specified ie's
 1472                  */
 1473                 m = ieee80211_getmgtframe(&frm,
 1474                          sizeof(u_int16_t)
 1475                        + sizeof(u_int16_t)
 1476                        + IEEE80211_ADDR_LEN
 1477                        + 2 + IEEE80211_NWID_LEN
 1478                        + 2 + IEEE80211_RATE_SIZE
 1479                        + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 1480                        + sizeof(struct ieee80211_wme_info)
 1481                        + (ic->ic_opt_ie != NULL ? ic->ic_opt_ie_len : 0)
 1482                 );
 1483                 if (m == NULL)
 1484                         senderr(ENOMEM, is_tx_nobuf);
 1485 
 1486                 capinfo = 0;
 1487                 if (ic->ic_opmode == IEEE80211_M_IBSS)
 1488                         capinfo |= IEEE80211_CAPINFO_IBSS;
 1489                 else            /* IEEE80211_M_STA */
 1490                         capinfo |= IEEE80211_CAPINFO_ESS;
 1491                 if (ic->ic_flags & IEEE80211_F_PRIVACY)
 1492                         capinfo |= IEEE80211_CAPINFO_PRIVACY;
 1493                 /*
 1494                  * NB: Some 11a AP's reject the request when
 1495                  *     short premable is set.
 1496                  */
 1497                 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
 1498                     IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
 1499                         capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 1500                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) &&
 1501                     (ic->ic_caps & IEEE80211_C_SHSLOT))
 1502                         capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
 1503                 *(u_int16_t *)frm = htole16(capinfo);
 1504                 frm += 2;
 1505 
 1506                 *(u_int16_t *)frm = htole16(ic->ic_lintval);
 1507                 frm += 2;
 1508 
 1509                 if (type == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
 1510                         IEEE80211_ADDR_COPY(frm, ic->ic_bss->ni_bssid);
 1511                         frm += IEEE80211_ADDR_LEN;
 1512                 }
 1513 
 1514                 frm = ieee80211_add_ssid(frm, ni->ni_essid, ni->ni_esslen);
 1515                 frm = ieee80211_add_rates(frm, &ni->ni_rates);
 1516                 frm = ieee80211_add_xrates(frm, &ni->ni_rates);
 1517                 if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
 1518                         frm = ieee80211_add_wme_info(frm, &ic->ic_wme);
 1519                 if (ic->ic_opt_ie != NULL) {
 1520                         memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len);
 1521                         frm += ic->ic_opt_ie_len;
 1522                 }
 1523                 m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1524 
 1525                 timer = IEEE80211_TRANS_WAIT;
 1526                 break;
 1527 
 1528         case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
 1529         case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
 1530                 /*
 1531                  * asreq frame format
 1532                  *      [2] capability information
 1533                  *      [2] status
 1534                  *      [2] association ID
 1535                  *      [tlv] supported rates
 1536                  *      [tlv] extended supported rates
 1537                  *      [tlv] WME (if enabled and STA enabled)
 1538                  */
 1539                 m = ieee80211_getmgtframe(&frm,
 1540                          sizeof(u_int16_t)
 1541                        + sizeof(u_int16_t)
 1542                        + sizeof(u_int16_t)
 1543                        + 2 + IEEE80211_RATE_SIZE
 1544                        + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 1545                        + sizeof(struct ieee80211_wme_param)
 1546                 );
 1547                 if (m == NULL)
 1548                         senderr(ENOMEM, is_tx_nobuf);
 1549 
 1550                 capinfo = IEEE80211_CAPINFO_ESS;
 1551                 if (ic->ic_flags & IEEE80211_F_PRIVACY)
 1552                         capinfo |= IEEE80211_CAPINFO_PRIVACY;
 1553                 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
 1554                     IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
 1555                         capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 1556                 if (ic->ic_flags & IEEE80211_F_SHSLOT)
 1557                         capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
 1558                 *(u_int16_t *)frm = htole16(capinfo);
 1559                 frm += 2;
 1560 
 1561                 *(u_int16_t *)frm = htole16(arg);       /* status */
 1562                 frm += 2;
 1563 
 1564                 if (arg == IEEE80211_STATUS_SUCCESS) {
 1565                         *(u_int16_t *)frm = htole16(ni->ni_associd);
 1566                         IEEE80211_NODE_STAT(ni, tx_assoc);
 1567                 } else
 1568                         IEEE80211_NODE_STAT(ni, tx_assoc_fail);
 1569                 frm += 2;
 1570 
 1571                 frm = ieee80211_add_rates(frm, &ni->ni_rates);
 1572                 frm = ieee80211_add_xrates(frm, &ni->ni_rates);
 1573                 if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
 1574                         frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
 1575                 m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1576                 break;
 1577 
 1578         case IEEE80211_FC0_SUBTYPE_DISASSOC:
 1579                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
 1580                         "[%s] send station disassociate (reason %d)\n",
 1581                         ether_sprintf(ni->ni_macaddr), arg);
 1582                 m = ieee80211_getmgtframe(&frm, sizeof(u_int16_t));
 1583                 if (m == NULL)
 1584                         senderr(ENOMEM, is_tx_nobuf);
 1585                 *(u_int16_t *)frm = htole16(arg);       /* reason */
 1586                 m->m_pkthdr.len = m->m_len = sizeof(u_int16_t);
 1587 
 1588                 IEEE80211_NODE_STAT(ni, tx_disassoc);
 1589                 IEEE80211_NODE_STAT_SET(ni, tx_disassoc_code, arg);
 1590                 break;
 1591 
 1592         default:
 1593                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
 1594                         "[%s] invalid mgmt frame type %u\n",
 1595                         ether_sprintf(ni->ni_macaddr), type);
 1596                 senderr(EINVAL, is_tx_unknownmgt);
 1597                 /* NOTREACHED */
 1598         }
 1599         ret = ieee80211_mgmt_output(ic, ni, m, type, timer);
 1600         if (ret != 0) {
 1601 bad:
 1602                 ieee80211_free_node(ni);
 1603         }
 1604         return ret;
 1605 #undef senderr
 1606 }
 1607 
 1608 /*
 1609  * Allocate a beacon frame and fillin the appropriate bits.
 1610  */
 1611 struct mbuf *
 1612 ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni,
 1613         struct ieee80211_beacon_offsets *bo)
 1614 {
 1615         struct ifnet *ifp = ic->ic_ifp;
 1616         struct ieee80211_frame *wh;
 1617         struct mbuf *m;
 1618         int pktlen;
 1619         u_int8_t *frm, *efrm;
 1620         u_int16_t capinfo;
 1621         struct ieee80211_rateset *rs;
 1622 
 1623         /*
 1624          * beacon frame format
 1625          *      [8] time stamp
 1626          *      [2] beacon interval
 1627          *      [2] cabability information
 1628          *      [tlv] ssid
 1629          *      [tlv] supported rates
 1630          *      [3] parameter set (DS)
 1631          *      [tlv] parameter set (IBSS/TIM)
 1632          *      [tlv] extended rate phy (ERP)
 1633          *      [tlv] extended supported rates
 1634          *      [tlv] WME parameters
 1635          *      [tlv] WPA/RSN parameters
 1636          * XXX Vendor-specific OIDs (e.g. Atheros)
 1637          * NB: we allocate the max space required for the TIM bitmap.
 1638          */
 1639         rs = &ni->ni_rates;
 1640         pktlen =   8                                    /* time stamp */
 1641                  + sizeof(u_int16_t)                    /* beacon interval */
 1642                  + sizeof(u_int16_t)                    /* capabilities */
 1643                  + 2 + ni->ni_esslen                    /* ssid */
 1644                  + 2 + IEEE80211_RATE_SIZE              /* supported rates */
 1645                  + 2 + 1                                /* DS parameters */
 1646                  + 2 + 4 + ic->ic_tim_len               /* DTIM/IBSSPARMS */
 1647                  + 2 + 1                                /* ERP */
 1648                  + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 1649                  + (ic->ic_caps & IEEE80211_C_WME ?     /* WME */
 1650                         sizeof(struct ieee80211_wme_param) : 0)
 1651                  + (ic->ic_caps & IEEE80211_C_WPA ?     /* WPA 1+2 */
 1652                         2*sizeof(struct ieee80211_ie_wpa) : 0)
 1653                  ;
 1654         m = ieee80211_getmgtframe(&frm, pktlen);
 1655         if (m == NULL) {
 1656                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
 1657                         "%s: cannot get buf; size %u\n", __func__, pktlen);
 1658                 ic->ic_stats.is_tx_nobuf++;
 1659                 return NULL;
 1660         }
 1661 
 1662         memset(frm, 0, 8);      /* XXX timestamp is set by hardware/driver */
 1663         frm += 8;
 1664         *(u_int16_t *)frm = htole16(ni->ni_intval);
 1665         frm += 2;
 1666         if (ic->ic_opmode == IEEE80211_M_IBSS)
 1667                 capinfo = IEEE80211_CAPINFO_IBSS;
 1668         else
 1669                 capinfo = IEEE80211_CAPINFO_ESS;
 1670         if (ic->ic_flags & IEEE80211_F_PRIVACY)
 1671                 capinfo |= IEEE80211_CAPINFO_PRIVACY;
 1672         if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
 1673             IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
 1674                 capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 1675         if (ic->ic_flags & IEEE80211_F_SHSLOT)
 1676                 capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
 1677         bo->bo_caps = (u_int16_t *)frm;
 1678         *(u_int16_t *)frm = htole16(capinfo);
 1679         frm += 2;
 1680         *frm++ = IEEE80211_ELEMID_SSID;
 1681         if ((ic->ic_flags & IEEE80211_F_HIDESSID) == 0) {
 1682                 *frm++ = ni->ni_esslen;
 1683                 memcpy(frm, ni->ni_essid, ni->ni_esslen);
 1684                 frm += ni->ni_esslen;
 1685         } else
 1686                 *frm++ = 0;
 1687         frm = ieee80211_add_rates(frm, rs);
 1688         if (ic->ic_curmode != IEEE80211_MODE_FH) {
 1689                 *frm++ = IEEE80211_ELEMID_DSPARMS;
 1690                 *frm++ = 1;
 1691                 *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan);
 1692         }
 1693         bo->bo_tim = frm;
 1694         if (ic->ic_opmode == IEEE80211_M_IBSS) {
 1695                 *frm++ = IEEE80211_ELEMID_IBSSPARMS;
 1696                 *frm++ = 2;
 1697                 *frm++ = 0; *frm++ = 0;         /* TODO: ATIM window */
 1698                 bo->bo_tim_len = 0;
 1699         } else {
 1700                 struct ieee80211_tim_ie *tie = (struct ieee80211_tim_ie *) frm;
 1701 
 1702                 tie->tim_ie = IEEE80211_ELEMID_TIM;
 1703                 tie->tim_len = 4;       /* length */
 1704                 tie->tim_count = 0;     /* DTIM count */ 
 1705                 tie->tim_period = ic->ic_dtim_period;   /* DTIM period */
 1706                 tie->tim_bitctl = 0;    /* bitmap control */
 1707                 tie->tim_bitmap[0] = 0; /* Partial Virtual Bitmap */
 1708                 frm += sizeof(struct ieee80211_tim_ie);
 1709                 bo->bo_tim_len = 1;
 1710         }
 1711         bo->bo_trailer = frm;
 1712         if (ic->ic_flags & IEEE80211_F_WME) {
 1713                 bo->bo_wme = frm;
 1714                 frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
 1715                 ic->ic_flags &= ~IEEE80211_F_WMEUPDATE;
 1716         }
 1717         if (ic->ic_flags & IEEE80211_F_WPA)
 1718                 frm = ieee80211_add_wpa(frm, ic);
 1719         if (ic->ic_curmode == IEEE80211_MODE_11G)
 1720                 frm = ieee80211_add_erp(frm, ic);
 1721         efrm = ieee80211_add_xrates(frm, rs);
 1722         bo->bo_trailer_len = efrm - bo->bo_trailer;
 1723         m->m_pkthdr.len = m->m_len = efrm - mtod(m, u_int8_t *);
 1724 
 1725         M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
 1726         IASSERT(m != NULL, ("no space for 802.11 header?"));
 1727         wh = mtod(m, struct ieee80211_frame *);
 1728         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
 1729             IEEE80211_FC0_SUBTYPE_BEACON;
 1730         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
 1731         *(u_int16_t *)wh->i_dur = 0;
 1732         IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
 1733         IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
 1734         IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
 1735         *(u_int16_t *)wh->i_seq = 0;
 1736 
 1737         return m;
 1738 }
 1739 
 1740 /*
 1741  * Update the dynamic parts of a beacon frame based on the current state.
 1742  */
 1743 int
 1744 ieee80211_beacon_update(struct ieee80211com *ic, struct ieee80211_node *ni,
 1745     struct ieee80211_beacon_offsets *bo, struct mbuf *m, int mcast)
 1746 {
 1747         int len_changed = 0;
 1748         u_int16_t capinfo;
 1749 
 1750         IEEE80211_BEACON_LOCK(ic);
 1751         /* XXX faster to recalculate entirely or just changes? */
 1752         if (ic->ic_opmode == IEEE80211_M_IBSS)
 1753                 capinfo = IEEE80211_CAPINFO_IBSS;
 1754         else
 1755                 capinfo = IEEE80211_CAPINFO_ESS;
 1756         if (ic->ic_flags & IEEE80211_F_PRIVACY)
 1757                 capinfo |= IEEE80211_CAPINFO_PRIVACY;
 1758         if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
 1759             IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
 1760                 capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 1761         if (ic->ic_flags & IEEE80211_F_SHSLOT)
 1762                 capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
 1763         *bo->bo_caps = htole16(capinfo);
 1764 
 1765         if (ic->ic_flags & IEEE80211_F_WME) {
 1766                 struct ieee80211_wme_state *wme = &ic->ic_wme;
 1767 
 1768                 /*
 1769                  * Check for agressive mode change.  When there is
 1770                  * significant high priority traffic in the BSS
 1771                  * throttle back BE traffic by using conservative
 1772                  * parameters.  Otherwise BE uses agressive params
 1773                  * to optimize performance of legacy/non-QoS traffic.
 1774                  */
 1775                 if (wme->wme_flags & WME_F_AGGRMODE) {
 1776                         if (wme->wme_hipri_traffic >
 1777                             wme->wme_hipri_switch_thresh) {
 1778                                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
 1779                                     "%s: traffic %u, disable aggressive mode\n",
 1780                                     __func__, wme->wme_hipri_traffic);
 1781                                 wme->wme_flags &= ~WME_F_AGGRMODE;
 1782                                 ieee80211_wme_updateparams_locked(ic);
 1783                                 wme->wme_hipri_traffic =
 1784                                         wme->wme_hipri_switch_hysteresis;
 1785                         } else
 1786                                 wme->wme_hipri_traffic = 0;
 1787                 } else {
 1788                         if (wme->wme_hipri_traffic <=
 1789                             wme->wme_hipri_switch_thresh) {
 1790                                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
 1791                                     "%s: traffic %u, enable aggressive mode\n",
 1792                                     __func__, wme->wme_hipri_traffic);
 1793                                 wme->wme_flags |= WME_F_AGGRMODE;
 1794                                 ieee80211_wme_updateparams_locked(ic);
 1795                                 wme->wme_hipri_traffic = 0;
 1796                         } else
 1797                                 wme->wme_hipri_traffic =
 1798                                         wme->wme_hipri_switch_hysteresis;
 1799                 }
 1800                 if (ic->ic_flags & IEEE80211_F_WMEUPDATE) {
 1801                         (void) ieee80211_add_wme_param(bo->bo_wme, wme);
 1802                         ic->ic_flags &= ~IEEE80211_F_WMEUPDATE;
 1803                 }
 1804         }
 1805 
 1806 #ifndef IEEE80211_NO_HOSTAP
 1807         if (ic->ic_opmode == IEEE80211_M_HOSTAP) {      /* NB: no IBSS support*/
 1808                 struct ieee80211_tim_ie *tie =
 1809                         (struct ieee80211_tim_ie *) bo->bo_tim;
 1810                 if (ic->ic_flags & IEEE80211_F_TIMUPDATE) {
 1811                         u_int timlen, timoff, i;
 1812                         /* 
 1813                          * ATIM/DTIM needs updating.  If it fits in the
 1814                          * current space allocated then just copy in the
 1815                          * new bits.  Otherwise we need to move any trailing
 1816                          * data to make room.  Note that we know there is
 1817                          * contiguous space because ieee80211_beacon_allocate
 1818                          * insures there is space in the mbuf to write a
 1819                          * maximal-size virtual bitmap (based on ic_max_aid).
 1820                          */
 1821                         /*
 1822                          * Calculate the bitmap size and offset, copy any
 1823                          * trailer out of the way, and then copy in the
 1824                          * new bitmap and update the information element.
 1825                          * Note that the tim bitmap must contain at least
 1826                          * one byte and any offset must be even.
 1827                          */
 1828                         if (ic->ic_ps_pending != 0) {
 1829                                 timoff = 128;           /* impossibly large */
 1830                                 for (i = 0; i < ic->ic_tim_len; i++)
 1831                                         if (ic->ic_tim_bitmap[i]) {
 1832                                                 timoff = i &~ 1;
 1833                                                 break;
 1834                                         }
 1835                                 IASSERT(timoff != 128, ("tim bitmap empty!"));
 1836                                 for (i = ic->ic_tim_len-1; i >= timoff; i--)
 1837                                         if (ic->ic_tim_bitmap[i])
 1838                                                 break;
 1839                                 timlen = 1 + (i - timoff);
 1840                         } else {
 1841                                 timoff = 0;
 1842                                 timlen = 1;
 1843                         }
 1844                         if (timlen != bo->bo_tim_len) {
 1845                                 /* copy up/down trailer */
 1846                                 ovbcopy(bo->bo_trailer, tie->tim_bitmap+timlen,
 1847                                         bo->bo_trailer_len);
 1848                                 bo->bo_trailer = tie->tim_bitmap+timlen;
 1849                                 bo->bo_wme = bo->bo_trailer;
 1850                                 bo->bo_tim_len = timlen;
 1851 
 1852                                 /* update information element */
 1853                                 tie->tim_len = 3 + timlen;
 1854                                 tie->tim_bitctl = timoff;
 1855                                 len_changed = 1;
 1856                         }
 1857                         memcpy(tie->tim_bitmap, ic->ic_tim_bitmap + timoff,
 1858                                 bo->bo_tim_len);
 1859 
 1860                         ic->ic_flags &= ~IEEE80211_F_TIMUPDATE;
 1861 
 1862                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
 1863                                 "%s: TIM updated, pending %u, off %u, len %u\n",
 1864                                 __func__, ic->ic_ps_pending, timoff, timlen);
 1865                 }
 1866                 /* count down DTIM period */
 1867                 if (tie->tim_count == 0)
 1868                         tie->tim_count = tie->tim_period - 1;
 1869                 else
 1870                         tie->tim_count--;
 1871                 /* update state for buffered multicast frames on DTIM */
 1872                 if (mcast && (tie->tim_count == 1 || tie->tim_period == 1))
 1873                         tie->tim_bitctl |= 1;
 1874                 else
 1875                         tie->tim_bitctl &= ~1;
 1876         }
 1877 #endif /* !IEEE80211_NO_HOSTAP */
 1878         IEEE80211_BEACON_UNLOCK(ic);
 1879 
 1880         return len_changed;
 1881 }
 1882 
 1883 /*
 1884  * Save an outbound packet for a node in power-save sleep state.
 1885  * The new packet is placed on the node's saved queue, and the TIM
 1886  * is changed, if necessary.
 1887  */
 1888 void
 1889 ieee80211_pwrsave(struct ieee80211com *ic, struct ieee80211_node *ni, 
 1890                   struct mbuf *m)
 1891 {
 1892         int qlen, age;
 1893 
 1894         IEEE80211_NODE_SAVEQ_LOCK(ni);
 1895         if (IF_QFULL(&ni->ni_savedq)) {
 1896                 IF_DROP(&ni->ni_savedq);
 1897                 IEEE80211_NODE_SAVEQ_UNLOCK(ni);
 1898                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
 1899                         "[%s] pwr save q overflow, drops %d (size %d)\n",
 1900                         ether_sprintf(ni->ni_macaddr), 
 1901                         ni->ni_savedq.ifq_drops, IEEE80211_PS_MAX_QUEUE);
 1902 #ifdef IEEE80211_DEBUG
 1903                 if (ieee80211_msg_dumppkts(ic))
 1904                         ieee80211_dump_pkt(mtod(m, caddr_t), m->m_len, -1, -1);
 1905 #endif
 1906                 m_freem(m);
 1907                 return;
 1908         }
 1909         /*
 1910          * Tag the frame with it's expiry time and insert
 1911          * it in the queue.  The aging interval is 4 times
 1912          * the listen interval specified by the station. 
 1913          * Frames that sit around too long are reclaimed
 1914          * using this information.
 1915          */
 1916         /* XXX handle overflow? */
 1917         age = ((ni->ni_intval * ic->ic_bintval) << 2) / 1024; /* TU -> secs */
 1918         _IEEE80211_NODE_SAVEQ_ENQUEUE(ni, m, qlen, age);
 1919         IEEE80211_NODE_SAVEQ_UNLOCK(ni);
 1920 
 1921         IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
 1922                 "[%s] save frame with age %d, %u now queued\n",
 1923                 ether_sprintf(ni->ni_macaddr), age, qlen);
 1924 
 1925         if (qlen == 1)
 1926                 ic->ic_set_tim(ni, 1);
 1927 }

Cache object: 944b8f9d24e0394b645372b07d8b9605


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.