[ 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  -  FREEBSD10  -  FREEBSD9  -  FREEBSD92  -  FREEBSD91  -  FREEBSD90  -  FREEBSD8  -  FREEBSD82  -  FREEBSD81  -  FREEBSD80  -  FREEBSD7  -  FREEBSD74  -  FREEBSD73  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  cheribsd  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1  -  FREEBSD-LIBC  -  FREEBSD8-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
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$");
   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[IEEE80211_NONQOS_TID] << IEEE80211_SEQ_SEQ_SHIFT);
  132         ni->ni_txseqs[IEEE80211_NONQOS_TID]++;
  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 /*
  454  * Return the transmit key to use in sending a unicast frame.
  455  * If a unicast key is set we use that.  When no unicast key is set
  456  * we fall back to the default transmit key.
  457  */ 
  458 static __inline struct ieee80211_key *
  459 ieee80211_crypto_getucastkey(struct ieee80211com *ic, struct ieee80211_node *ni)
  460 {
  461         if (IEEE80211_KEY_UNDEFINED(&ni->ni_ucastkey)) {
  462                 if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE ||
  463                     IEEE80211_KEY_UNDEFINED(&ic->ic_nw_keys[ic->ic_def_txkey]))
  464                         return NULL;
  465                 return &ic->ic_nw_keys[ic->ic_def_txkey];
  466         } else {
  467                 return &ni->ni_ucastkey;
  468         }
  469 }
  470 
  471 /*
  472  * Return the transmit key to use in sending a multicast frame.
  473  * Multicast traffic always uses the group key which is installed as
  474  * the default tx key.
  475  */ 
  476 static __inline struct ieee80211_key *
  477 ieee80211_crypto_getmcastkey(struct ieee80211com *ic, struct ieee80211_node *ni)
  478 {
  479         if (ic->ic_def_txkey == IEEE80211_KEYIX_NONE ||
  480             IEEE80211_KEY_UNDEFINED(&ic->ic_nw_keys[ic->ic_def_txkey]))
  481                 return NULL;
  482         return &ic->ic_nw_keys[ic->ic_def_txkey];
  483 }
  484 
  485 /*
  486  * Encapsulate an outbound data frame.  The mbuf chain is updated.
  487  * If an error is encountered NULL is returned.  The caller is required
  488  * to provide a node reference and pullup the ethernet header in the
  489  * first mbuf.
  490  */
  491 struct mbuf *
  492 ieee80211_encap(struct ieee80211com *ic, struct mbuf *m,
  493         struct ieee80211_node *ni)
  494 {
  495         struct ether_header eh;
  496         struct ieee80211_frame *wh;
  497         struct ieee80211_key *key;
  498         struct llc *llc;
  499         int hdrsize, datalen, addqos;
  500 
  501         KASSERT(m->m_len >= sizeof(eh), ("no ethernet header!"));
  502         memcpy(&eh, mtod(m, caddr_t), sizeof(struct ether_header));
  503 
  504         /*
  505          * Insure space for additional headers.  First identify
  506          * transmit key to use in calculating any buffer adjustments
  507          * required.  This is also used below to do privacy
  508          * encapsulation work.  Then calculate the 802.11 header
  509          * size and any padding required by the driver.
  510          *
  511          * Note key may be NULL if we fall back to the default
  512          * transmit key and that is not set.  In that case the
  513          * buffer may not be expanded as needed by the cipher
  514          * routines, but they will/should discard it.
  515          */
  516         if (ic->ic_flags & IEEE80211_F_PRIVACY) {
  517                 if (ic->ic_opmode == IEEE80211_M_STA ||
  518                     !IEEE80211_IS_MULTICAST(eh.ether_dhost))
  519                         key = ieee80211_crypto_getucastkey(ic, ni);
  520                 else
  521                         key = ieee80211_crypto_getmcastkey(ic, ni);
  522                 if (key == NULL && eh.ether_type != htons(ETHERTYPE_PAE)) {
  523                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_CRYPTO,
  524                             "[%s] no default transmit key (%s) deftxkey %u\n",
  525                             ether_sprintf(eh.ether_dhost), __func__,
  526                             ic->ic_def_txkey);
  527                         ic->ic_stats.is_tx_nodefkey++;
  528                 }
  529         } else
  530                 key = NULL;
  531         /* XXX 4-address format */
  532         /*
  533          * XXX Some ap's don't handle QoS-encapsulated EAPOL
  534          * frames so suppress use.  This may be an issue if other
  535          * ap's require all data frames to be QoS-encapsulated
  536          * once negotiated in which case we'll need to make this
  537          * configurable.
  538          */
  539         addqos = (ni->ni_flags & IEEE80211_NODE_QOS) &&
  540                  eh.ether_type != htons(ETHERTYPE_PAE);
  541         if (addqos)
  542                 hdrsize = sizeof(struct ieee80211_qosframe);
  543         else
  544                 hdrsize = sizeof(struct ieee80211_frame);
  545         if (ic->ic_flags & IEEE80211_F_DATAPAD)
  546                 hdrsize = roundup(hdrsize, sizeof(u_int32_t));
  547         m = ieee80211_mbuf_adjust(ic, hdrsize, key, m);
  548         if (m == NULL) {
  549                 /* NB: ieee80211_mbuf_adjust handles msgs+statistics */
  550                 goto bad;
  551         }
  552 
  553         /* NB: this could be optimized because of ieee80211_mbuf_adjust */
  554         m_adj(m, sizeof(struct ether_header) - sizeof(struct llc));
  555         llc = mtod(m, struct llc *);
  556         llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
  557         llc->llc_control = LLC_UI;
  558         llc->llc_snap.org_code[0] = 0;
  559         llc->llc_snap.org_code[1] = 0;
  560         llc->llc_snap.org_code[2] = 0;
  561         llc->llc_snap.ether_type = eh.ether_type;
  562         datalen = m->m_pkthdr.len;              /* NB: w/o 802.11 header */
  563 
  564         M_PREPEND(m, hdrsize, M_DONTWAIT);
  565         if (m == NULL) {
  566                 ic->ic_stats.is_tx_nobuf++;
  567                 goto bad;
  568         }
  569         wh = mtod(m, struct ieee80211_frame *);
  570         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
  571         *(u_int16_t *)wh->i_dur = 0;
  572         switch (ic->ic_opmode) {
  573         case IEEE80211_M_STA:
  574                 wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
  575                 IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_bssid);
  576                 IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
  577                 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost);
  578                 break;
  579         case IEEE80211_M_IBSS:
  580         case IEEE80211_M_AHDEMO:
  581                 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
  582                 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
  583                 IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
  584                 /*
  585                  * NB: always use the bssid from ic_bss as the
  586                  *     neighbor's may be stale after an ibss merge
  587                  */
  588                 IEEE80211_ADDR_COPY(wh->i_addr3, ic->ic_bss->ni_bssid);
  589                 break;
  590         case IEEE80211_M_HOSTAP:
  591                 wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
  592                 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
  593                 IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid);
  594                 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost);
  595                 break;
  596         case IEEE80211_M_MONITOR:
  597                 goto bad;
  598         }
  599         if (m->m_flags & M_MORE_DATA)
  600                 wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA;
  601         if (addqos) {
  602                 struct ieee80211_qosframe *qwh =
  603                         (struct ieee80211_qosframe *) wh;
  604                 int ac, tid;
  605 
  606                 ac = M_WME_GETAC(m);
  607                 /* map from access class/queue to 11e header priorty value */
  608                 tid = WME_AC_TO_TID(ac);
  609                 qwh->i_qos[0] = tid & IEEE80211_QOS_TID;
  610                 if (ic->ic_wme.wme_wmeChanParams.cap_wmeParams[ac].wmep_noackPolicy)
  611                         qwh->i_qos[0] |= 1 << IEEE80211_QOS_ACKPOLICY_S;
  612                 qwh->i_qos[1] = 0;
  613                 qwh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS;
  614 
  615                 *(u_int16_t *)wh->i_seq =
  616                     htole16(ni->ni_txseqs[tid] << IEEE80211_SEQ_SEQ_SHIFT);
  617                 ni->ni_txseqs[tid]++;
  618         } else {
  619                 *(u_int16_t *)wh->i_seq =
  620                     htole16(ni->ni_txseqs[IEEE80211_NONQOS_TID] << IEEE80211_SEQ_SEQ_SHIFT);
  621                 ni->ni_txseqs[IEEE80211_NONQOS_TID]++;
  622         }
  623         if (key != NULL) {
  624                 /*
  625                  * IEEE 802.1X: send EAPOL frames always in the clear.
  626                  * WPA/WPA2: encrypt EAPOL keys when pairwise keys are set.
  627                  */
  628                 if (eh.ether_type != htons(ETHERTYPE_PAE) ||
  629                     ((ic->ic_flags & IEEE80211_F_WPA) &&
  630                      (ic->ic_opmode == IEEE80211_M_STA ?
  631                       !IEEE80211_KEY_UNDEFINED(key) :
  632                       !IEEE80211_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         if (IEEE80211_IS_MULTICAST(wh->i_addr1))
  647                 IEEE80211_NODE_STAT(ni, tx_mcast);
  648         else
  649                 IEEE80211_NODE_STAT(ni, tx_ucast);
  650         IEEE80211_NODE_STAT_ADD(ni, tx_bytes, datalen);
  651 
  652         return m;
  653 bad:
  654         if (m != NULL)
  655                 m_freem(m);
  656         return NULL;
  657 }
  658 
  659 /*
  660  * Add a supported rates element id to a frame.
  661  */
  662 static u_int8_t *
  663 ieee80211_add_rates(u_int8_t *frm, const struct ieee80211_rateset *rs)
  664 {
  665         int nrates;
  666 
  667         *frm++ = IEEE80211_ELEMID_RATES;
  668         nrates = rs->rs_nrates;
  669         if (nrates > IEEE80211_RATE_SIZE)
  670                 nrates = IEEE80211_RATE_SIZE;
  671         *frm++ = nrates;
  672         memcpy(frm, rs->rs_rates, nrates);
  673         return frm + nrates;
  674 }
  675 
  676 /*
  677  * Add an extended supported rates element id to a frame.
  678  */
  679 static u_int8_t *
  680 ieee80211_add_xrates(u_int8_t *frm, const struct ieee80211_rateset *rs)
  681 {
  682         /*
  683          * Add an extended supported rates element if operating in 11g mode.
  684          */
  685         if (rs->rs_nrates > IEEE80211_RATE_SIZE) {
  686                 int nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
  687                 *frm++ = IEEE80211_ELEMID_XRATES;
  688                 *frm++ = nrates;
  689                 memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
  690                 frm += nrates;
  691         }
  692         return frm;
  693 }
  694 
  695 /* 
  696  * Add an ssid elemet to a frame.
  697  */
  698 static u_int8_t *
  699 ieee80211_add_ssid(u_int8_t *frm, const u_int8_t *ssid, u_int len)
  700 {
  701         *frm++ = IEEE80211_ELEMID_SSID;
  702         *frm++ = len;
  703         memcpy(frm, ssid, len);
  704         return frm + len;
  705 }
  706 
  707 /*
  708  * Add an erp element to a frame.
  709  */
  710 static u_int8_t *
  711 ieee80211_add_erp(u_int8_t *frm, struct ieee80211com *ic)
  712 {
  713         u_int8_t erp;
  714 
  715         *frm++ = IEEE80211_ELEMID_ERP;
  716         *frm++ = 1;
  717         erp = 0;
  718         if (ic->ic_nonerpsta != 0)
  719                 erp |= IEEE80211_ERP_NON_ERP_PRESENT;
  720         if (ic->ic_flags & IEEE80211_F_USEPROT)
  721                 erp |= IEEE80211_ERP_USE_PROTECTION;
  722         if (ic->ic_flags & IEEE80211_F_USEBARKER)
  723                 erp |= IEEE80211_ERP_LONG_PREAMBLE;
  724         *frm++ = erp;
  725         return frm;
  726 }
  727 
  728 static u_int8_t *
  729 ieee80211_setup_wpa_ie(struct ieee80211com *ic, u_int8_t *ie)
  730 {
  731 #define WPA_OUI_BYTES           0x00, 0x50, 0xf2
  732 #define ADDSHORT(frm, v) do {                   \
  733         frm[0] = (v) & 0xff;                    \
  734         frm[1] = (v) >> 8;                      \
  735         frm += 2;                               \
  736 } while (0)
  737 #define ADDSELECTOR(frm, sel) do {              \
  738         memcpy(frm, sel, 4);                    \
  739         frm += 4;                               \
  740 } while (0)
  741         static const u_int8_t oui[4] = { WPA_OUI_BYTES, WPA_OUI_TYPE };
  742         static const u_int8_t cipher_suite[][4] = {
  743                 { WPA_OUI_BYTES, WPA_CSE_WEP40 },       /* NB: 40-bit */
  744                 { WPA_OUI_BYTES, WPA_CSE_TKIP },
  745                 { 0x00, 0x00, 0x00, 0x00 },             /* XXX WRAP */
  746                 { WPA_OUI_BYTES, WPA_CSE_CCMP },
  747                 { 0x00, 0x00, 0x00, 0x00 },             /* XXX CKIP */
  748                 { WPA_OUI_BYTES, WPA_CSE_NULL },
  749         };
  750         static const u_int8_t wep104_suite[4] =
  751                 { WPA_OUI_BYTES, WPA_CSE_WEP104 };
  752         static const u_int8_t key_mgt_unspec[4] =
  753                 { WPA_OUI_BYTES, WPA_ASE_8021X_UNSPEC };
  754         static const u_int8_t key_mgt_psk[4] =
  755                 { WPA_OUI_BYTES, WPA_ASE_8021X_PSK };
  756         const struct ieee80211_rsnparms *rsn = &ic->ic_bss->ni_rsn;
  757         u_int8_t *frm = ie;
  758         u_int8_t *selcnt;
  759 
  760         *frm++ = IEEE80211_ELEMID_VENDOR;
  761         *frm++ = 0;                             /* length filled in below */
  762         memcpy(frm, oui, sizeof(oui));          /* WPA OUI */
  763         frm += sizeof(oui);
  764         ADDSHORT(frm, WPA_VERSION);
  765 
  766         /* XXX filter out CKIP */
  767 
  768         /* multicast cipher */
  769         if (rsn->rsn_mcastcipher == IEEE80211_CIPHER_WEP &&
  770             rsn->rsn_mcastkeylen >= 13)
  771                 ADDSELECTOR(frm, wep104_suite);
  772         else
  773                 ADDSELECTOR(frm, cipher_suite[rsn->rsn_mcastcipher]);
  774 
  775         /* unicast cipher list */
  776         selcnt = frm;
  777         ADDSHORT(frm, 0);                       /* selector count */
  778         if (rsn->rsn_ucastcipherset & (1<<IEEE80211_CIPHER_AES_CCM)) {
  779                 selcnt[0]++;
  780                 ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_AES_CCM]);
  781         }
  782         if (rsn->rsn_ucastcipherset & (1<<IEEE80211_CIPHER_TKIP)) {
  783                 selcnt[0]++;
  784                 ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_TKIP]);
  785         }
  786 
  787         /* authenticator selector list */
  788         selcnt = frm;
  789         ADDSHORT(frm, 0);                       /* selector count */
  790         if (rsn->rsn_keymgmtset & WPA_ASE_8021X_UNSPEC) {
  791                 selcnt[0]++;
  792                 ADDSELECTOR(frm, key_mgt_unspec);
  793         }
  794         if (rsn->rsn_keymgmtset & WPA_ASE_8021X_PSK) {
  795                 selcnt[0]++;
  796                 ADDSELECTOR(frm, key_mgt_psk);
  797         }
  798 
  799         /* optional capabilities */
  800         if (rsn->rsn_caps != 0 && rsn->rsn_caps != RSN_CAP_PREAUTH)
  801                 ADDSHORT(frm, rsn->rsn_caps);
  802 
  803         /* calculate element length */
  804         ie[1] = frm - ie - 2;
  805         KASSERT(ie[1]+2 <= sizeof(struct ieee80211_ie_wpa),
  806                 ("WPA IE too big, %u > %zu",
  807                 ie[1]+2, sizeof(struct ieee80211_ie_wpa)));
  808         return frm;
  809 #undef ADDSHORT
  810 #undef ADDSELECTOR
  811 #undef WPA_OUI_BYTES
  812 }
  813 
  814 static u_int8_t *
  815 ieee80211_setup_rsn_ie(struct ieee80211com *ic, u_int8_t *ie)
  816 {
  817 #define RSN_OUI_BYTES           0x00, 0x0f, 0xac
  818 #define ADDSHORT(frm, v) do {                   \
  819         frm[0] = (v) & 0xff;                    \
  820         frm[1] = (v) >> 8;                      \
  821         frm += 2;                               \
  822 } while (0)
  823 #define ADDSELECTOR(frm, sel) do {              \
  824         memcpy(frm, sel, 4);                    \
  825         frm += 4;                               \
  826 } while (0)
  827         static const u_int8_t cipher_suite[][4] = {
  828                 { RSN_OUI_BYTES, RSN_CSE_WEP40 },       /* NB: 40-bit */
  829                 { RSN_OUI_BYTES, RSN_CSE_TKIP },
  830                 { RSN_OUI_BYTES, RSN_CSE_WRAP },
  831                 { RSN_OUI_BYTES, RSN_CSE_CCMP },
  832                 { 0x00, 0x00, 0x00, 0x00 },             /* XXX CKIP */
  833                 { RSN_OUI_BYTES, RSN_CSE_NULL },
  834         };
  835         static const u_int8_t wep104_suite[4] =
  836                 { RSN_OUI_BYTES, RSN_CSE_WEP104 };
  837         static const u_int8_t key_mgt_unspec[4] =
  838                 { RSN_OUI_BYTES, RSN_ASE_8021X_UNSPEC };
  839         static const u_int8_t key_mgt_psk[4] =
  840                 { RSN_OUI_BYTES, RSN_ASE_8021X_PSK };
  841         const struct ieee80211_rsnparms *rsn = &ic->ic_bss->ni_rsn;
  842         u_int8_t *frm = ie;
  843         u_int8_t *selcnt;
  844 
  845         *frm++ = IEEE80211_ELEMID_RSN;
  846         *frm++ = 0;                             /* length filled in below */
  847         ADDSHORT(frm, RSN_VERSION);
  848 
  849         /* XXX filter out CKIP */
  850 
  851         /* multicast cipher */
  852         if (rsn->rsn_mcastcipher == IEEE80211_CIPHER_WEP &&
  853             rsn->rsn_mcastkeylen >= 13)
  854                 ADDSELECTOR(frm, wep104_suite);
  855         else
  856                 ADDSELECTOR(frm, cipher_suite[rsn->rsn_mcastcipher]);
  857 
  858         /* unicast cipher list */
  859         selcnt = frm;
  860         ADDSHORT(frm, 0);                       /* selector count */
  861         if (rsn->rsn_ucastcipherset & (1<<IEEE80211_CIPHER_AES_CCM)) {
  862                 selcnt[0]++;
  863                 ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_AES_CCM]);
  864         }
  865         if (rsn->rsn_ucastcipherset & (1<<IEEE80211_CIPHER_TKIP)) {
  866                 selcnt[0]++;
  867                 ADDSELECTOR(frm, cipher_suite[IEEE80211_CIPHER_TKIP]);
  868         }
  869 
  870         /* authenticator selector list */
  871         selcnt = frm;
  872         ADDSHORT(frm, 0);                       /* selector count */
  873         if (rsn->rsn_keymgmtset & WPA_ASE_8021X_UNSPEC) {
  874                 selcnt[0]++;
  875                 ADDSELECTOR(frm, key_mgt_unspec);
  876         }
  877         if (rsn->rsn_keymgmtset & WPA_ASE_8021X_PSK) {
  878                 selcnt[0]++;
  879                 ADDSELECTOR(frm, key_mgt_psk);
  880         }
  881 
  882         /* optional capabilities */
  883         ADDSHORT(frm, rsn->rsn_caps);
  884         /* XXX PMKID */
  885 
  886         /* calculate element length */
  887         ie[1] = frm - ie - 2;
  888         KASSERT(ie[1]+2 <= sizeof(struct ieee80211_ie_wpa),
  889                 ("RSN IE too big, %u > %zu",
  890                 ie[1]+2, sizeof(struct ieee80211_ie_wpa)));
  891         return frm;
  892 #undef ADDSELECTOR
  893 #undef ADDSHORT
  894 #undef RSN_OUI_BYTES
  895 }
  896 
  897 /*
  898  * Add a WPA/RSN element to a frame.
  899  */
  900 static u_int8_t *
  901 ieee80211_add_wpa(u_int8_t *frm, struct ieee80211com *ic)
  902 {
  903 
  904         KASSERT(ic->ic_flags & IEEE80211_F_WPA, ("no WPA/RSN!"));
  905         if (ic->ic_flags & IEEE80211_F_WPA2)
  906                 frm = ieee80211_setup_rsn_ie(ic, frm);
  907         if (ic->ic_flags & IEEE80211_F_WPA1)
  908                 frm = ieee80211_setup_wpa_ie(ic, frm);
  909         return frm;
  910 }
  911 
  912 #define WME_OUI_BYTES           0x00, 0x50, 0xf2
  913 /*
  914  * Add a WME information element to a frame.
  915  */
  916 static u_int8_t *
  917 ieee80211_add_wme_info(u_int8_t *frm, struct ieee80211_wme_state *wme)
  918 {
  919         static const struct ieee80211_wme_info info = {
  920                 .wme_id         = IEEE80211_ELEMID_VENDOR,
  921                 .wme_len        = sizeof(struct ieee80211_wme_info) - 2,
  922                 .wme_oui        = { WME_OUI_BYTES },
  923                 .wme_type       = WME_OUI_TYPE,
  924                 .wme_subtype    = WME_INFO_OUI_SUBTYPE,
  925                 .wme_version    = WME_VERSION,
  926                 .wme_info       = 0,
  927         };
  928         memcpy(frm, &info, sizeof(info));
  929         return frm + sizeof(info); 
  930 }
  931 
  932 /*
  933  * Add a WME parameters element to a frame.
  934  */
  935 static u_int8_t *
  936 ieee80211_add_wme_param(u_int8_t *frm, struct ieee80211_wme_state *wme)
  937 {
  938 #define SM(_v, _f)      (((_v) << _f##_S) & _f)
  939 #define ADDSHORT(frm, v) do {                   \
  940         frm[0] = (v) & 0xff;                    \
  941         frm[1] = (v) >> 8;                      \
  942         frm += 2;                               \
  943 } while (0)
  944         /* NB: this works 'cuz a param has an info at the front */
  945         static const struct ieee80211_wme_info param = {
  946                 .wme_id         = IEEE80211_ELEMID_VENDOR,
  947                 .wme_len        = sizeof(struct ieee80211_wme_param) - 2,
  948                 .wme_oui        = { WME_OUI_BYTES },
  949                 .wme_type       = WME_OUI_TYPE,
  950                 .wme_subtype    = WME_PARAM_OUI_SUBTYPE,
  951                 .wme_version    = WME_VERSION,
  952         };
  953         int i;
  954 
  955         memcpy(frm, &param, sizeof(param));
  956         frm += __offsetof(struct ieee80211_wme_info, wme_info);
  957         *frm++ = wme->wme_bssChanParams.cap_info;       /* AC info */
  958         *frm++ = 0;                                     /* reserved field */
  959         for (i = 0; i < WME_NUM_AC; i++) {
  960                 const struct wmeParams *ac =
  961                        &wme->wme_bssChanParams.cap_wmeParams[i];
  962                 *frm++ = SM(i, WME_PARAM_ACI)
  963                        | SM(ac->wmep_acm, WME_PARAM_ACM)
  964                        | SM(ac->wmep_aifsn, WME_PARAM_AIFSN)
  965                        ;
  966                 *frm++ = SM(ac->wmep_logcwmax, WME_PARAM_LOGCWMAX)
  967                        | SM(ac->wmep_logcwmin, WME_PARAM_LOGCWMIN)
  968                        ;
  969                 ADDSHORT(frm, ac->wmep_txopLimit);
  970         }
  971         return frm;
  972 #undef SM
  973 #undef ADDSHORT
  974 }
  975 #undef WME_OUI_BYTES
  976 
  977 /*
  978  * Send a probe request frame with the specified ssid
  979  * and any optional information element data.
  980  */
  981 int
  982 ieee80211_send_probereq(struct ieee80211_node *ni,
  983         const u_int8_t sa[IEEE80211_ADDR_LEN],
  984         const u_int8_t da[IEEE80211_ADDR_LEN],
  985         const u_int8_t bssid[IEEE80211_ADDR_LEN],
  986         const u_int8_t *ssid, size_t ssidlen,
  987         const void *optie, size_t optielen)
  988 {
  989         struct ieee80211com *ic = ni->ni_ic;
  990         struct ieee80211_frame *wh;
  991         const struct ieee80211_rateset *rs;
  992         struct mbuf *m;
  993         u_int8_t *frm;
  994 
  995         /*
  996          * Hold a reference on the node so it doesn't go away until after
  997          * the xmit is complete all the way in the driver.  On error we
  998          * will remove our reference.
  999          */
 1000         IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
 1001                 "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n",
 1002                 __func__, __LINE__,
 1003                 ni, ether_sprintf(ni->ni_macaddr),
 1004                 ieee80211_node_refcnt(ni)+1);
 1005         ieee80211_ref_node(ni);
 1006 
 1007         /*
 1008          * prreq frame format
 1009          *      [tlv] ssid
 1010          *      [tlv] supported rates
 1011          *      [tlv] extended supported rates
 1012          *      [tlv] user-specified ie's
 1013          */
 1014         m = ieee80211_getmgtframe(&frm,
 1015                  2 + IEEE80211_NWID_LEN
 1016                + 2 + IEEE80211_RATE_SIZE
 1017                + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 1018                + (optie != NULL ? optielen : 0)
 1019         );
 1020         if (m == NULL) {
 1021                 ic->ic_stats.is_tx_nobuf++;
 1022                 ieee80211_free_node(ni);
 1023                 return ENOMEM;
 1024         }
 1025 
 1026         frm = ieee80211_add_ssid(frm, ssid, ssidlen);
 1027         rs = ieee80211_get_suprates(ic, ic->ic_curchan);
 1028         frm = ieee80211_add_rates(frm, rs);
 1029         frm = ieee80211_add_xrates(frm, rs);
 1030 
 1031         if (optie != NULL) {
 1032                 memcpy(frm, optie, optielen);
 1033                 frm += optielen;
 1034         }
 1035         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1036 
 1037         M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
 1038         if (m == NULL)
 1039                 return ENOMEM;
 1040         KASSERT(m->m_pkthdr.rcvif == NULL, ("rcvif not null"));
 1041         m->m_pkthdr.rcvif = (void *)ni;
 1042 
 1043         wh = mtod(m, struct ieee80211_frame *);
 1044         ieee80211_send_setup(ic, ni, wh,
 1045                 IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ,
 1046                 sa, da, bssid);
 1047         /* XXX power management? */
 1048 
 1049         IEEE80211_NODE_STAT(ni, tx_probereq);
 1050         IEEE80211_NODE_STAT(ni, tx_mgmt);
 1051 
 1052         IEEE80211_DPRINTF(ic, IEEE80211_MSG_DEBUG | IEEE80211_MSG_DUMPPKTS,
 1053             "[%s] send probe req on channel %u\n",
 1054             ether_sprintf(wh->i_addr1),
 1055             ieee80211_chan2ieee(ic, ic->ic_curchan));
 1056 
 1057         IF_ENQUEUE(&ic->ic_mgtq, m);
 1058         if_start(ic->ic_ifp);
 1059         return 0;
 1060 }
 1061 
 1062 /*
 1063  * Calculate capability information for mgt frames.
 1064  */
 1065 static u_int16_t
 1066 getcapinfo(struct ieee80211com *ic, struct ieee80211_channel *chan)
 1067 {
 1068         u_int16_t capinfo;
 1069 
 1070         KASSERT(ic->ic_opmode != IEEE80211_M_STA, ("station mode"));
 1071 
 1072         if (ic->ic_opmode == IEEE80211_M_HOSTAP)
 1073                 capinfo = IEEE80211_CAPINFO_ESS;
 1074         else if (ic->ic_opmode == IEEE80211_M_IBSS)
 1075                 capinfo = IEEE80211_CAPINFO_IBSS;
 1076         else
 1077                 capinfo = 0;
 1078         if (ic->ic_flags & IEEE80211_F_PRIVACY)
 1079                 capinfo |= IEEE80211_CAPINFO_PRIVACY;
 1080         if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
 1081             IEEE80211_IS_CHAN_2GHZ(chan))
 1082                 capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 1083         if (ic->ic_flags & IEEE80211_F_SHSLOT)
 1084                 capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
 1085         return capinfo;
 1086 }
 1087 
 1088 /*
 1089  * Send a management frame.  The node is for the destination (or ic_bss
 1090  * when in station mode).  Nodes other than ic_bss have their reference
 1091  * count bumped to reflect our use for an indeterminant time.
 1092  */
 1093 int
 1094 ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
 1095         int type, int arg)
 1096 {
 1097 #define senderr(_x, _v) do { ic->ic_stats._v++; ret = _x; goto bad; } while (0)
 1098         struct mbuf *m;
 1099         u_int8_t *frm;
 1100         u_int16_t capinfo;
 1101         int has_challenge, is_shared_key, ret, timer, status;
 1102 
 1103         KASSERT(ni != NULL, ("null node"));
 1104 
 1105         /*
 1106          * Hold a reference on the node so it doesn't go away until after
 1107          * the xmit is complete all the way in the driver.  On error we
 1108          * will remove our reference.
 1109          */
 1110         IEEE80211_DPRINTF(ic, IEEE80211_MSG_NODE,
 1111                 "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n",
 1112                 __func__, __LINE__,
 1113                 ni, ether_sprintf(ni->ni_macaddr),
 1114                 ieee80211_node_refcnt(ni)+1);
 1115         ieee80211_ref_node(ni);
 1116 
 1117         timer = 0;
 1118         switch (type) {
 1119         case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
 1120                 /*
 1121                  * probe response frame format
 1122                  *      [8] time stamp
 1123                  *      [2] beacon interval
 1124                  *      [2] cabability information
 1125                  *      [tlv] ssid
 1126                  *      [tlv] supported rates
 1127                  *      [tlv] parameter set (FH/DS)
 1128                  *      [tlv] parameter set (IBSS)
 1129                  *      [tlv] extended rate phy (ERP)
 1130                  *      [tlv] extended supported rates
 1131                  *      [tlv] WPA
 1132                  *      [tlv] WME (optional)
 1133                  */
 1134                 m = ieee80211_getmgtframe(&frm,
 1135                          8
 1136                        + sizeof(u_int16_t)
 1137                        + sizeof(u_int16_t)
 1138                        + 2 + IEEE80211_NWID_LEN
 1139                        + 2 + IEEE80211_RATE_SIZE
 1140                        + 7      /* max(7,3) */
 1141                        + 6
 1142                        + 3
 1143                        + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 1144                        /* XXX !WPA1+WPA2 fits w/o a cluster */
 1145                        + (ic->ic_flags & IEEE80211_F_WPA ?
 1146                                 2*sizeof(struct ieee80211_ie_wpa) : 0)
 1147                        + sizeof(struct ieee80211_wme_param)
 1148                 );
 1149                 if (m == NULL)
 1150                         senderr(ENOMEM, is_tx_nobuf);
 1151 
 1152                 memset(frm, 0, 8);      /* timestamp should be filled later */
 1153                 frm += 8;
 1154                 *(u_int16_t *)frm = htole16(ic->ic_bss->ni_intval);
 1155                 frm += 2;
 1156                 capinfo = getcapinfo(ic, ic->ic_curchan);
 1157                 *(u_int16_t *)frm = htole16(capinfo);
 1158                 frm += 2;
 1159 
 1160                 frm = ieee80211_add_ssid(frm, ic->ic_bss->ni_essid,
 1161                                 ic->ic_bss->ni_esslen);
 1162                 frm = ieee80211_add_rates(frm, &ni->ni_rates);
 1163 
 1164                 if (ic->ic_phytype == IEEE80211_T_FH) {
 1165                         *frm++ = IEEE80211_ELEMID_FHPARMS;
 1166                         *frm++ = 5;
 1167                         *frm++ = ni->ni_fhdwell & 0x00ff;
 1168                         *frm++ = (ni->ni_fhdwell >> 8) & 0x00ff;
 1169                         *frm++ = IEEE80211_FH_CHANSET(
 1170                             ieee80211_chan2ieee(ic, ic->ic_curchan));
 1171                         *frm++ = IEEE80211_FH_CHANPAT(
 1172                             ieee80211_chan2ieee(ic, ic->ic_curchan));
 1173                         *frm++ = ni->ni_fhindex;
 1174                 } else {
 1175                         *frm++ = IEEE80211_ELEMID_DSPARMS;
 1176                         *frm++ = 1;
 1177                         *frm++ = ieee80211_chan2ieee(ic, ic->ic_curchan);
 1178                 }
 1179 
 1180                 if (ic->ic_opmode == IEEE80211_M_IBSS) {
 1181                         *frm++ = IEEE80211_ELEMID_IBSSPARMS;
 1182                         *frm++ = 2;
 1183                         *frm++ = 0; *frm++ = 0;         /* TODO: ATIM window */
 1184                 }
 1185                 if (ic->ic_flags & IEEE80211_F_WPA)
 1186                         frm = ieee80211_add_wpa(frm, ic);
 1187                 if (ic->ic_curmode == IEEE80211_MODE_11G)
 1188                         frm = ieee80211_add_erp(frm, ic);
 1189                 frm = ieee80211_add_xrates(frm, &ni->ni_rates);
 1190                 if (ic->ic_flags & IEEE80211_F_WME)
 1191                         frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
 1192                 m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1193                 break;
 1194 
 1195         case IEEE80211_FC0_SUBTYPE_AUTH:
 1196                 status = arg >> 16;
 1197                 arg &= 0xffff;
 1198                 has_challenge = ((arg == IEEE80211_AUTH_SHARED_CHALLENGE ||
 1199                     arg == IEEE80211_AUTH_SHARED_RESPONSE) &&
 1200                     ni->ni_challenge != NULL);
 1201 
 1202                 /*
 1203                  * Deduce whether we're doing open authentication or
 1204                  * shared key authentication.  We do the latter if
 1205                  * we're in the middle of a shared key authentication
 1206                  * handshake or if we're initiating an authentication
 1207                  * request and configured to use shared key.
 1208                  */
 1209                 is_shared_key = has_challenge ||
 1210                      arg >= IEEE80211_AUTH_SHARED_RESPONSE ||
 1211                      (arg == IEEE80211_AUTH_SHARED_REQUEST &&
 1212                       ic->ic_bss->ni_authmode == IEEE80211_AUTH_SHARED);
 1213 
 1214                 m = ieee80211_getmgtframe(&frm,
 1215                           3 * sizeof(u_int16_t)
 1216                         + (has_challenge && status == IEEE80211_STATUS_SUCCESS ?
 1217                                 sizeof(u_int16_t)+IEEE80211_CHALLENGE_LEN : 0)
 1218                 );
 1219                 if (m == NULL)
 1220                         senderr(ENOMEM, is_tx_nobuf);
 1221 
 1222                 ((u_int16_t *)frm)[0] =
 1223                     (is_shared_key) ? htole16(IEEE80211_AUTH_ALG_SHARED)
 1224                                     : htole16(IEEE80211_AUTH_ALG_OPEN);
 1225                 ((u_int16_t *)frm)[1] = htole16(arg);   /* sequence number */
 1226                 ((u_int16_t *)frm)[2] = htole16(status);/* status */
 1227 
 1228                 if (has_challenge && status == IEEE80211_STATUS_SUCCESS) {
 1229                         ((u_int16_t *)frm)[3] =
 1230                             htole16((IEEE80211_CHALLENGE_LEN << 8) |
 1231                             IEEE80211_ELEMID_CHALLENGE);
 1232                         memcpy(&((u_int16_t *)frm)[4], ni->ni_challenge,
 1233                             IEEE80211_CHALLENGE_LEN);
 1234                         m->m_pkthdr.len = m->m_len =
 1235                                 4 * sizeof(u_int16_t) + IEEE80211_CHALLENGE_LEN;
 1236                         if (arg == IEEE80211_AUTH_SHARED_RESPONSE) {
 1237                                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
 1238                                     "[%s] request encrypt frame (%s)\n",
 1239                                     ether_sprintf(ni->ni_macaddr), __func__);
 1240                                 m->m_flags |= M_LINK0; /* WEP-encrypt, please */
 1241                         }
 1242                 } else
 1243                         m->m_pkthdr.len = m->m_len = 3 * sizeof(u_int16_t);
 1244 
 1245                 /* XXX not right for shared key */
 1246                 if (status == IEEE80211_STATUS_SUCCESS)
 1247                         IEEE80211_NODE_STAT(ni, tx_auth);
 1248                 else
 1249                         IEEE80211_NODE_STAT(ni, tx_auth_fail);
 1250 
 1251                 if (ic->ic_opmode == IEEE80211_M_STA)
 1252                         timer = IEEE80211_TRANS_WAIT;
 1253                 break;
 1254 
 1255         case IEEE80211_FC0_SUBTYPE_DEAUTH:
 1256                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_AUTH,
 1257                         "[%s] send station deauthenticate (reason %d)\n",
 1258                         ether_sprintf(ni->ni_macaddr), arg);
 1259                 m = ieee80211_getmgtframe(&frm, sizeof(u_int16_t));
 1260                 if (m == NULL)
 1261                         senderr(ENOMEM, is_tx_nobuf);
 1262                 *(u_int16_t *)frm = htole16(arg);       /* reason */
 1263                 m->m_pkthdr.len = m->m_len = sizeof(u_int16_t);
 1264 
 1265                 IEEE80211_NODE_STAT(ni, tx_deauth);
 1266                 IEEE80211_NODE_STAT_SET(ni, tx_deauth_code, arg);
 1267 
 1268                 ieee80211_node_unauthorize(ni);         /* port closed */
 1269                 break;
 1270 
 1271         case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
 1272         case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
 1273                 /*
 1274                  * asreq frame format
 1275                  *      [2] capability information
 1276                  *      [2] listen interval
 1277                  *      [6*] current AP address (reassoc only)
 1278                  *      [tlv] ssid
 1279                  *      [tlv] supported rates
 1280                  *      [tlv] extended supported rates
 1281                  *      [tlv] WME
 1282                  *      [tlv] user-specified ie's
 1283                  */
 1284                 m = ieee80211_getmgtframe(&frm,
 1285                          sizeof(u_int16_t)
 1286                        + sizeof(u_int16_t)
 1287                        + IEEE80211_ADDR_LEN
 1288                        + 2 + IEEE80211_NWID_LEN
 1289                        + 2 + IEEE80211_RATE_SIZE
 1290                        + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 1291                        + sizeof(struct ieee80211_wme_info)
 1292                        + (ic->ic_opt_ie != NULL ? ic->ic_opt_ie_len : 0)
 1293                 );
 1294                 if (m == NULL)
 1295                         senderr(ENOMEM, is_tx_nobuf);
 1296 
 1297                 KASSERT(ic->ic_opmode == IEEE80211_M_STA,
 1298                     ("wrong mode %u", ic->ic_opmode));
 1299                 capinfo = IEEE80211_CAPINFO_ESS;
 1300                 if (ic->ic_flags & IEEE80211_F_PRIVACY)
 1301                         capinfo |= IEEE80211_CAPINFO_PRIVACY;
 1302                 /*
 1303                  * NB: Some 11a AP's reject the request when
 1304                  *     short premable is set.
 1305                  */
 1306                 if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
 1307                     IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
 1308                         capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 1309                 if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) &&
 1310                     (ic->ic_caps & IEEE80211_C_SHSLOT))
 1311                         capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
 1312                 *(u_int16_t *)frm = htole16(capinfo);
 1313                 frm += 2;
 1314 
 1315                 *(u_int16_t *)frm = htole16(ic->ic_lintval);
 1316                 frm += 2;
 1317 
 1318                 if (type == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
 1319                         IEEE80211_ADDR_COPY(frm, ic->ic_bss->ni_bssid);
 1320                         frm += IEEE80211_ADDR_LEN;
 1321                 }
 1322 
 1323                 frm = ieee80211_add_ssid(frm, ni->ni_essid, ni->ni_esslen);
 1324                 frm = ieee80211_add_rates(frm, &ni->ni_rates);
 1325                 frm = ieee80211_add_xrates(frm, &ni->ni_rates);
 1326                 if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
 1327                         frm = ieee80211_add_wme_info(frm, &ic->ic_wme);
 1328                 if (ic->ic_opt_ie != NULL) {
 1329                         memcpy(frm, ic->ic_opt_ie, ic->ic_opt_ie_len);
 1330                         frm += ic->ic_opt_ie_len;
 1331                 }
 1332                 m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1333 
 1334                 timer = IEEE80211_TRANS_WAIT;
 1335                 break;
 1336 
 1337         case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
 1338         case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
 1339                 /*
 1340                  * asreq frame format
 1341                  *      [2] capability information
 1342                  *      [2] status
 1343                  *      [2] association ID
 1344                  *      [tlv] supported rates
 1345                  *      [tlv] extended supported rates
 1346                  *      [tlv] WME (if enabled and STA enabled)
 1347                  */
 1348                 m = ieee80211_getmgtframe(&frm,
 1349                          sizeof(u_int16_t)
 1350                        + sizeof(u_int16_t)
 1351                        + sizeof(u_int16_t)
 1352                        + 2 + IEEE80211_RATE_SIZE
 1353                        + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 1354                        + sizeof(struct ieee80211_wme_param)
 1355                 );
 1356                 if (m == NULL)
 1357                         senderr(ENOMEM, is_tx_nobuf);
 1358 
 1359                 capinfo = getcapinfo(ic, ic->ic_curchan);
 1360                 *(u_int16_t *)frm = htole16(capinfo);
 1361                 frm += 2;
 1362 
 1363                 *(u_int16_t *)frm = htole16(arg);       /* status */
 1364                 frm += 2;
 1365 
 1366                 if (arg == IEEE80211_STATUS_SUCCESS) {
 1367                         *(u_int16_t *)frm = htole16(ni->ni_associd);
 1368                         IEEE80211_NODE_STAT(ni, tx_assoc);
 1369                 } else
 1370                         IEEE80211_NODE_STAT(ni, tx_assoc_fail);
 1371                 frm += 2;
 1372 
 1373                 frm = ieee80211_add_rates(frm, &ni->ni_rates);
 1374                 frm = ieee80211_add_xrates(frm, &ni->ni_rates);
 1375                 if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL)
 1376                         frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
 1377                 m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1378                 break;
 1379 
 1380         case IEEE80211_FC0_SUBTYPE_DISASSOC:
 1381                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ASSOC,
 1382                         "[%s] send station disassociate (reason %d)\n",
 1383                         ether_sprintf(ni->ni_macaddr), arg);
 1384                 m = ieee80211_getmgtframe(&frm, sizeof(u_int16_t));
 1385                 if (m == NULL)
 1386                         senderr(ENOMEM, is_tx_nobuf);
 1387                 *(u_int16_t *)frm = htole16(arg);       /* reason */
 1388                 m->m_pkthdr.len = m->m_len = sizeof(u_int16_t);
 1389 
 1390                 IEEE80211_NODE_STAT(ni, tx_disassoc);
 1391                 IEEE80211_NODE_STAT_SET(ni, tx_disassoc_code, arg);
 1392                 break;
 1393 
 1394         default:
 1395                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
 1396                         "[%s] invalid mgmt frame type %u\n",
 1397                         ether_sprintf(ni->ni_macaddr), type);
 1398                 senderr(EINVAL, is_tx_unknownmgt);
 1399                 /* NOTREACHED */
 1400         }
 1401         ret = ieee80211_mgmt_output(ic, ni, m, type, timer);
 1402         if (ret != 0) {
 1403 bad:
 1404                 ieee80211_free_node(ni);
 1405         }
 1406         return ret;
 1407 #undef senderr
 1408 }
 1409 
 1410 /*
 1411  * Allocate a beacon frame and fillin the appropriate bits.
 1412  */
 1413 struct mbuf *
 1414 ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni,
 1415         struct ieee80211_beacon_offsets *bo)
 1416 {
 1417         struct ifnet *ifp = ic->ic_ifp;
 1418         struct ieee80211_frame *wh;
 1419         struct mbuf *m;
 1420         int pktlen;
 1421         u_int8_t *frm, *efrm;
 1422         u_int16_t capinfo;
 1423         struct ieee80211_rateset *rs;
 1424 
 1425         /*
 1426          * beacon frame format
 1427          *      [8] time stamp
 1428          *      [2] beacon interval
 1429          *      [2] cabability information
 1430          *      [tlv] ssid
 1431          *      [tlv] supported rates
 1432          *      [3] parameter set (DS)
 1433          *      [tlv] parameter set (IBSS/TIM)
 1434          *      [tlv] extended rate phy (ERP)
 1435          *      [tlv] extended supported rates
 1436          *      [tlv] WME parameters
 1437          *      [tlv] WPA/RSN parameters
 1438          * XXX Vendor-specific OIDs (e.g. Atheros)
 1439          * NB: we allocate the max space required for the TIM bitmap.
 1440          */
 1441         rs = &ni->ni_rates;
 1442         pktlen =   8                                    /* time stamp */
 1443                  + sizeof(u_int16_t)                    /* beacon interval */
 1444                  + sizeof(u_int16_t)                    /* capabilities */
 1445                  + 2 + ni->ni_esslen                    /* ssid */
 1446                  + 2 + IEEE80211_RATE_SIZE              /* supported rates */
 1447                  + 2 + 1                                /* DS parameters */
 1448                  + 2 + 4 + ic->ic_tim_len               /* DTIM/IBSSPARMS */
 1449                  + 2 + 1                                /* ERP */
 1450                  + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
 1451                  + (ic->ic_caps & IEEE80211_C_WME ?     /* WME */
 1452                         sizeof(struct ieee80211_wme_param) : 0)
 1453                  + (ic->ic_caps & IEEE80211_C_WPA ?     /* WPA 1+2 */
 1454                         2*sizeof(struct ieee80211_ie_wpa) : 0)
 1455                  ;
 1456         m = ieee80211_getmgtframe(&frm, pktlen);
 1457         if (m == NULL) {
 1458                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
 1459                         "%s: cannot get buf; size %u\n", __func__, pktlen);
 1460                 ic->ic_stats.is_tx_nobuf++;
 1461                 return NULL;
 1462         }
 1463 
 1464         memset(frm, 0, 8);      /* XXX timestamp is set by hardware/driver */
 1465         frm += 8;
 1466         *(u_int16_t *)frm = htole16(ni->ni_intval);
 1467         frm += 2;
 1468         capinfo = getcapinfo(ic, ni->ni_chan);
 1469         bo->bo_caps = (u_int16_t *)frm;
 1470         *(u_int16_t *)frm = htole16(capinfo);
 1471         frm += 2;
 1472         *frm++ = IEEE80211_ELEMID_SSID;
 1473         if ((ic->ic_flags & IEEE80211_F_HIDESSID) == 0) {
 1474                 *frm++ = ni->ni_esslen;
 1475                 memcpy(frm, ni->ni_essid, ni->ni_esslen);
 1476                 frm += ni->ni_esslen;
 1477         } else
 1478                 *frm++ = 0;
 1479         frm = ieee80211_add_rates(frm, rs);
 1480         if (ic->ic_curmode != IEEE80211_MODE_FH) {
 1481                 *frm++ = IEEE80211_ELEMID_DSPARMS;
 1482                 *frm++ = 1;
 1483                 *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan);
 1484         }
 1485         bo->bo_tim = frm;
 1486         if (ic->ic_opmode == IEEE80211_M_IBSS) {
 1487                 *frm++ = IEEE80211_ELEMID_IBSSPARMS;
 1488                 *frm++ = 2;
 1489                 *frm++ = 0; *frm++ = 0;         /* TODO: ATIM window */
 1490                 bo->bo_tim_len = 0;
 1491         } else if (ic->ic_opmode == IEEE80211_M_HOSTAP) {
 1492                 struct ieee80211_tim_ie *tie = (struct ieee80211_tim_ie *) frm;
 1493 
 1494                 tie->tim_ie = IEEE80211_ELEMID_TIM;
 1495                 tie->tim_len = 4;       /* length */
 1496                 tie->tim_count = 0;     /* DTIM count */ 
 1497                 tie->tim_period = ic->ic_dtim_period;   /* DTIM period */
 1498                 tie->tim_bitctl = 0;    /* bitmap control */
 1499                 tie->tim_bitmap[0] = 0; /* Partial Virtual Bitmap */
 1500                 frm += sizeof(struct ieee80211_tim_ie);
 1501                 bo->bo_tim_len = 1;
 1502         }
 1503         bo->bo_trailer = frm;
 1504         if (ic->ic_flags & IEEE80211_F_WME) {
 1505                 bo->bo_wme = frm;
 1506                 frm = ieee80211_add_wme_param(frm, &ic->ic_wme);
 1507                 ic->ic_flags &= ~IEEE80211_F_WMEUPDATE;
 1508         }
 1509         if (ic->ic_flags & IEEE80211_F_WPA)
 1510                 frm = ieee80211_add_wpa(frm, ic);
 1511         if (ic->ic_curmode == IEEE80211_MODE_11G) {
 1512                 bo->bo_erp = frm;
 1513                 frm = ieee80211_add_erp(frm, ic);
 1514         }
 1515         efrm = ieee80211_add_xrates(frm, rs);
 1516         bo->bo_trailer_len = efrm - bo->bo_trailer;
 1517         m->m_pkthdr.len = m->m_len = efrm - mtod(m, u_int8_t *);
 1518 
 1519         M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
 1520         KASSERT(m != NULL, ("no space for 802.11 header?"));
 1521         wh = mtod(m, struct ieee80211_frame *);
 1522         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
 1523             IEEE80211_FC0_SUBTYPE_BEACON;
 1524         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
 1525         *(u_int16_t *)wh->i_dur = 0;
 1526         IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
 1527         IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
 1528         IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
 1529         *(u_int16_t *)wh->i_seq = 0;
 1530 
 1531         return m;
 1532 }
 1533 
 1534 /*
 1535  * Update the dynamic parts of a beacon frame based on the current state.
 1536  */
 1537 int
 1538 ieee80211_beacon_update(struct ieee80211com *ic, struct ieee80211_node *ni,
 1539         struct ieee80211_beacon_offsets *bo, struct mbuf *m, int mcast)
 1540 {
 1541         int len_changed = 0;
 1542         u_int16_t capinfo;
 1543 
 1544         IEEE80211_BEACON_LOCK(ic);
 1545         /* XXX faster to recalculate entirely or just changes? */
 1546         capinfo = getcapinfo(ic, ni->ni_chan);
 1547         *bo->bo_caps = htole16(capinfo);
 1548 
 1549         if (ic->ic_flags & IEEE80211_F_WME) {
 1550                 struct ieee80211_wme_state *wme = &ic->ic_wme;
 1551 
 1552                 /*
 1553                  * Check for agressive mode change.  When there is
 1554                  * significant high priority traffic in the BSS
 1555                  * throttle back BE traffic by using conservative
 1556                  * parameters.  Otherwise BE uses agressive params
 1557                  * to optimize performance of legacy/non-QoS traffic.
 1558                  */
 1559                 if (wme->wme_flags & WME_F_AGGRMODE) {
 1560                         if (wme->wme_hipri_traffic >
 1561                             wme->wme_hipri_switch_thresh) {
 1562                                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
 1563                                     "%s: traffic %u, disable aggressive mode\n",
 1564                                     __func__, wme->wme_hipri_traffic);
 1565                                 wme->wme_flags &= ~WME_F_AGGRMODE;
 1566                                 ieee80211_wme_updateparams_locked(ic);
 1567                                 wme->wme_hipri_traffic =
 1568                                         wme->wme_hipri_switch_hysteresis;
 1569                         } else
 1570                                 wme->wme_hipri_traffic = 0;
 1571                 } else {
 1572                         if (wme->wme_hipri_traffic <=
 1573                             wme->wme_hipri_switch_thresh) {
 1574                                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_WME,
 1575                                     "%s: traffic %u, enable aggressive mode\n",
 1576                                     __func__, wme->wme_hipri_traffic);
 1577                                 wme->wme_flags |= WME_F_AGGRMODE;
 1578                                 ieee80211_wme_updateparams_locked(ic);
 1579                                 wme->wme_hipri_traffic = 0;
 1580                         } else
 1581                                 wme->wme_hipri_traffic =
 1582                                         wme->wme_hipri_switch_hysteresis;
 1583                 }
 1584                 if (ic->ic_flags & IEEE80211_F_WMEUPDATE) {
 1585                         (void) ieee80211_add_wme_param(bo->bo_wme, wme);
 1586                         ic->ic_flags &= ~IEEE80211_F_WMEUPDATE;
 1587                 }
 1588         }
 1589 
 1590         if (ic->ic_opmode == IEEE80211_M_HOSTAP) {      /* NB: no IBSS support*/
 1591                 struct ieee80211_tim_ie *tie =
 1592                         (struct ieee80211_tim_ie *) bo->bo_tim;
 1593                 if (ic->ic_flags & IEEE80211_F_TIMUPDATE) {
 1594                         u_int timlen, timoff, i;
 1595                         /* 
 1596                          * ATIM/DTIM needs updating.  If it fits in the
 1597                          * current space allocated then just copy in the
 1598                          * new bits.  Otherwise we need to move any trailing
 1599                          * data to make room.  Note that we know there is
 1600                          * contiguous space because ieee80211_beacon_allocate
 1601                          * insures there is space in the mbuf to write a
 1602                          * maximal-size virtual bitmap (based on ic_max_aid).
 1603                          */
 1604                         /*
 1605                          * Calculate the bitmap size and offset, copy any
 1606                          * trailer out of the way, and then copy in the
 1607                          * new bitmap and update the information element.
 1608                          * Note that the tim bitmap must contain at least
 1609                          * one byte and any offset must be even.
 1610                          */
 1611                         if (ic->ic_ps_pending != 0) {
 1612                                 timoff = 128;           /* impossibly large */
 1613                                 for (i = 0; i < ic->ic_tim_len; i++)
 1614                                         if (ic->ic_tim_bitmap[i]) {
 1615                                                 timoff = i &~ 1;
 1616                                                 break;
 1617                                         }
 1618                                 KASSERT(timoff != 128, ("tim bitmap empty!"));
 1619                                 for (i = ic->ic_tim_len-1; i >= timoff; i--)
 1620                                         if (ic->ic_tim_bitmap[i])
 1621                                                 break;
 1622                                 timlen = 1 + (i - timoff);
 1623                         } else {
 1624                                 timoff = 0;
 1625                                 timlen = 1;
 1626                         }
 1627                         if (timlen != bo->bo_tim_len) {
 1628                                 /* copy up/down trailer */
 1629                                 int adjust = tie->tim_bitmap+timlen
 1630                                            - bo->bo_trailer;
 1631                                 ovbcopy(bo->bo_trailer, bo->bo_trailer+adjust,
 1632                                         bo->bo_trailer_len);
 1633                                 bo->bo_trailer += adjust;
 1634                                 bo->bo_wme += adjust;
 1635                                 bo->bo_erp += adjust;
 1636                                 bo->bo_tim_len = timlen;
 1637 
 1638                                 /* update information element */
 1639                                 tie->tim_len = 3 + timlen;
 1640                                 tie->tim_bitctl = timoff;
 1641                                 len_changed = 1;
 1642                         }
 1643                         memcpy(tie->tim_bitmap, ic->ic_tim_bitmap + timoff,
 1644                                 bo->bo_tim_len);
 1645 
 1646                         ic->ic_flags &= ~IEEE80211_F_TIMUPDATE;
 1647 
 1648                         IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
 1649                                 "%s: TIM updated, pending %u, off %u, len %u\n",
 1650                                 __func__, ic->ic_ps_pending, timoff, timlen);
 1651                 }
 1652                 /* count down DTIM period */
 1653                 if (tie->tim_count == 0)
 1654                         tie->tim_count = tie->tim_period - 1;
 1655                 else
 1656                         tie->tim_count--;
 1657                 /* update state for buffered multicast frames on DTIM */
 1658                 if (mcast && tie->tim_count == 0)
 1659                         tie->tim_bitctl |= 1;
 1660                 else
 1661                         tie->tim_bitctl &= ~1;
 1662                 if (ic->ic_flags_ext & IEEE80211_FEXT_ERPUPDATE) {
 1663                         /*
 1664                          * ERP element needs updating.
 1665                          */
 1666                         (void) ieee80211_add_erp(bo->bo_erp, ic);
 1667                         ic->ic_flags_ext &= ~IEEE80211_FEXT_ERPUPDATE;
 1668                 }
 1669         }
 1670         IEEE80211_BEACON_UNLOCK(ic);
 1671 
 1672         return len_changed;
 1673 }
 1674 
 1675 /*
 1676  * Save an outbound packet for a node in power-save sleep state.
 1677  * The new packet is placed on the node's saved queue, and the TIM
 1678  * is changed, if necessary.
 1679  */
 1680 void
 1681 ieee80211_pwrsave(struct ieee80211com *ic, struct ieee80211_node *ni, 
 1682                   struct mbuf *m)
 1683 {
 1684         int qlen, age;
 1685 
 1686         IEEE80211_NODE_SAVEQ_LOCK(ni);
 1687         if (_IF_QFULL(&ni->ni_savedq)) {
 1688                 _IF_DROP(&ni->ni_savedq);
 1689                 IEEE80211_NODE_SAVEQ_UNLOCK(ni);
 1690                 IEEE80211_DPRINTF(ic, IEEE80211_MSG_ANY,
 1691                         "[%s] pwr save q overflow, drops %d (size %d)\n",
 1692                         ether_sprintf(ni->ni_macaddr), 
 1693                         ni->ni_savedq.ifq_drops, IEEE80211_PS_MAX_QUEUE);
 1694 #ifdef IEEE80211_DEBUG
 1695                 if (ieee80211_msg_dumppkts(ic))
 1696                         ieee80211_dump_pkt(mtod(m, caddr_t), m->m_len, -1, -1);
 1697 #endif
 1698                 m_freem(m);
 1699                 return;
 1700         }
 1701         /*
 1702          * Tag the frame with it's expiry time and insert
 1703          * it in the queue.  The aging interval is 4 times
 1704          * the listen interval specified by the station. 
 1705          * Frames that sit around too long are reclaimed
 1706          * using this information.
 1707          */
 1708         /* XXX handle overflow? */
 1709         age = ((ni->ni_intval * ic->ic_bintval) << 2) / 1024; /* TU -> secs */
 1710         _IEEE80211_NODE_SAVEQ_ENQUEUE(ni, m, qlen, age);
 1711         IEEE80211_NODE_SAVEQ_UNLOCK(ni);
 1712 
 1713         IEEE80211_DPRINTF(ic, IEEE80211_MSG_POWER,
 1714                 "[%s] save frame with age %d, %u now queued\n",
 1715                 ether_sprintf(ni->ni_macaddr), age, qlen);
 1716 
 1717         if (qlen == 1)
 1718                 ic->ic_set_tim(ni, 1);
 1719 }

Cache object: 82dbadacd689ef51cc85040b55852bc6


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