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

Cache object: b2d911d584adedb069d87c78da2e8bf6


[ 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.