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 /*      $OpenBSD: ieee80211_output.c,v 1.137 2022/03/14 15:07:24 stsp Exp $     */
    2 /*      $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $     */
    3 
    4 /*-
    5  * Copyright (c) 2001 Atsushi Onoe
    6  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
    7  * Copyright (c) 2007-2009 Damien Bergamini
    8  * All rights reserved.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. The name of the author may not be used to endorse or promote products
   19  *    derived from this software without specific prior written permission.
   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 "bpfilter.h"
   34 #include "vlan.h"
   35 
   36 #include <sys/param.h>
   37 #include <sys/systm.h>
   38 #include <sys/mbuf.h>
   39 #include <sys/kernel.h>
   40 #include <sys/socket.h>
   41 #include <sys/sockio.h>
   42 #include <sys/endian.h>
   43 #include <sys/errno.h>
   44 #include <sys/sysctl.h>
   45 
   46 #include <net/if.h>
   47 #include <net/if_dl.h>
   48 #include <net/if_media.h>
   49 #include <net/if_llc.h>
   50 #include <net/bpf.h>
   51 
   52 #include <netinet/in.h>
   53 #include <netinet/if_ether.h>
   54 #include <netinet/ip.h>
   55 #ifdef INET6
   56 #include <netinet/ip6.h>
   57 #endif
   58 
   59 #if NVLAN > 0
   60 #include <net/if_vlan_var.h>
   61 #endif
   62 
   63 #include <net80211/ieee80211_var.h>
   64 #include <net80211/ieee80211_priv.h>
   65 
   66 int     ieee80211_mgmt_output(struct ifnet *, struct ieee80211_node *,
   67             struct mbuf *, int);
   68 int     ieee80211_can_use_ampdu(struct ieee80211com *,
   69             struct ieee80211_node *);
   70 u_int8_t *ieee80211_add_rsn_body(u_int8_t *, struct ieee80211com *,
   71             const struct ieee80211_node *, int);
   72 struct  mbuf *ieee80211_getmgmt(int, int, u_int);
   73 struct  mbuf *ieee80211_get_probe_req(struct ieee80211com *,
   74             struct ieee80211_node *);
   75 #ifndef IEEE80211_STA_ONLY
   76 struct  mbuf *ieee80211_get_probe_resp(struct ieee80211com *);
   77 #endif
   78 struct  mbuf *ieee80211_get_auth(struct ieee80211com *,
   79             struct ieee80211_node *, u_int16_t, u_int16_t);
   80 struct  mbuf *ieee80211_get_deauth(struct ieee80211com *,
   81             struct ieee80211_node *, u_int16_t);
   82 struct  mbuf *ieee80211_get_assoc_req(struct ieee80211com *,
   83             struct ieee80211_node *, int);
   84 #ifndef IEEE80211_STA_ONLY
   85 struct  mbuf *ieee80211_get_assoc_resp(struct ieee80211com *,
   86             struct ieee80211_node *, u_int16_t);
   87 #endif
   88 struct  mbuf *ieee80211_get_disassoc(struct ieee80211com *,
   89             struct ieee80211_node *, u_int16_t);
   90 struct  mbuf *ieee80211_get_addba_req(struct ieee80211com *,
   91             struct ieee80211_node *, u_int8_t);
   92 struct  mbuf *ieee80211_get_addba_resp(struct ieee80211com *,
   93             struct ieee80211_node *, u_int8_t, u_int8_t, u_int16_t);
   94 struct  mbuf *ieee80211_get_delba(struct ieee80211com *,
   95             struct ieee80211_node *, u_int8_t, u_int8_t, u_int16_t);
   96 uint8_t *ieee80211_add_wme_info(uint8_t *, struct ieee80211com *);
   97 #ifndef IEEE80211_STA_ONLY
   98 uint8_t *ieee80211_add_wme_param(uint8_t *, struct ieee80211com *);
   99 #endif
  100 struct  mbuf *ieee80211_get_sa_query(struct ieee80211com *,
  101             struct ieee80211_node *, u_int8_t);
  102 struct  mbuf *ieee80211_get_action(struct ieee80211com *,
  103             struct ieee80211_node *, u_int8_t, u_int8_t, int);
  104 
  105 /*
  106  * IEEE 802.11 output routine. Normally this will directly call the
  107  * Ethernet output routine because 802.11 encapsulation is called
  108  * later by the driver. This function can be used to send raw frames
  109  * if the mbuf has been tagged with a 802.11 data link type.
  110  */
  111 int
  112 ieee80211_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
  113     struct rtentry *rt)
  114 {
  115         struct ieee80211_frame *wh;
  116         struct m_tag *mtag;
  117         int error = 0;
  118 
  119         /* Interface has to be up and running */
  120         if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
  121             (IFF_UP | IFF_RUNNING)) {
  122                 error = ENETDOWN;
  123                 goto bad;
  124         }
  125 
  126         /* Try to get the DLT from a mbuf tag */
  127         if ((mtag = m_tag_find(m, PACKET_TAG_DLT, NULL)) != NULL) {
  128                 struct ieee80211com *ic = (void *)ifp;
  129                 u_int dlt = *(u_int *)(mtag + 1);
  130 
  131                 /* Fallback to ethernet for non-802.11 linktypes */
  132                 if (!(dlt == DLT_IEEE802_11 || dlt == DLT_IEEE802_11_RADIO))
  133                         goto fallback;
  134 
  135                 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min))
  136                         return (EINVAL);
  137                 wh = mtod(m, struct ieee80211_frame *);
  138                 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
  139                     IEEE80211_FC0_VERSION_0)
  140                         return (EINVAL);
  141                 if (!(ic->ic_caps & IEEE80211_C_RAWCTL) &&
  142                     (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
  143                     IEEE80211_FC0_TYPE_CTL)
  144                         return (EINVAL);
  145 
  146                 return (if_enqueue(ifp, m));
  147         }
  148 
  149  fallback:
  150         return (ether_output(ifp, m, dst, rt));
  151 
  152  bad:
  153         m_freem(m);
  154         return (error);
  155 }
  156 
  157 const char *
  158 ieee80211_action_name(struct ieee80211_frame *wh)
  159 {
  160         const u_int8_t *frm = (const uint8_t *)&wh[1];
  161         const char *categ_ba_name[3] = { "addba_req", "addba_resp", "delba" };
  162 
  163         if (frm[0] == IEEE80211_CATEG_BA && frm[1] < nitems(categ_ba_name))
  164                 return categ_ba_name[frm[1]];
  165 
  166         return "action";
  167 }
  168 
  169 /*
  170  * Send a management frame to the specified node.  The node pointer
  171  * must have a reference as the pointer will be passed to the driver
  172  * and potentially held for a long time.  If the frame is successfully
  173  * dispatched to the driver, then it is responsible for freeing the
  174  * reference (and potentially free'ing up any associated storage).
  175  */
  176 int
  177 ieee80211_mgmt_output(struct ifnet *ifp, struct ieee80211_node *ni,
  178     struct mbuf *m, int type)
  179 {
  180         struct ieee80211com *ic = (void *)ifp;
  181         struct ieee80211_frame *wh;
  182 
  183         if (ni == NULL)
  184                 panic("null node");
  185         ni->ni_inact = 0;
  186 
  187         /*
  188          * We want to pass the node down to the driver's start
  189          * routine.  We could stick this in an m_tag and tack that
  190          * on to the mbuf.  However that's rather expensive to do
  191          * for every frame so instead we stuff it in a special pkthdr
  192          * field.
  193          */
  194         M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
  195         if (m == NULL)
  196                 return ENOMEM;
  197         m->m_pkthdr.ph_cookie = ni;
  198 
  199         wh = mtod(m, struct ieee80211_frame *);
  200         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | type;
  201         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
  202         *(u_int16_t *)&wh->i_dur[0] = 0;
  203         *(u_int16_t *)&wh->i_seq[0] =
  204             htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
  205         ni->ni_txseq = (ni->ni_txseq + 1) & 0xfff;
  206         IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
  207         IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
  208         IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
  209 
  210         /* check if protection is required for this mgmt frame */
  211         if ((ic->ic_caps & IEEE80211_C_MFP) &&
  212             (type == IEEE80211_FC0_SUBTYPE_DISASSOC ||
  213              type == IEEE80211_FC0_SUBTYPE_DEAUTH ||
  214              type == IEEE80211_FC0_SUBTYPE_ACTION)) {
  215                 /*
  216                  * Hack: we should not set the Protected bit in outgoing
  217                  * group management frames, however it is used as an
  218                  * indication to the drivers that they must encrypt the
  219                  * frame.  Drivers should clear this bit from group
  220                  * management frames (software crypto code will do it).
  221                  * XXX could use an mbuf flag..
  222                  */
  223                 if (IEEE80211_IS_MULTICAST(wh->i_addr1) ||
  224                     (ni->ni_flags & IEEE80211_NODE_TXMGMTPROT))
  225                         wh->i_fc[1] |= IEEE80211_FC1_PROTECTED;
  226         }
  227 
  228         if (ifp->if_flags & IFF_DEBUG) {
  229                 /* avoid to print too many frames */
  230                 if (
  231 #ifndef IEEE80211_STA_ONLY
  232                     ic->ic_opmode == IEEE80211_M_IBSS ||
  233 #endif
  234 #ifdef IEEE80211_DEBUG
  235                     ieee80211_debug > 1 ||
  236 #endif
  237                     (type & IEEE80211_FC0_SUBTYPE_MASK) !=
  238                     IEEE80211_FC0_SUBTYPE_PROBE_RESP) {
  239                         const char *subtype_name;
  240                         if ((type & IEEE80211_FC0_SUBTYPE_MASK) ==
  241                             IEEE80211_FC0_SUBTYPE_ACTION)
  242                                 subtype_name = ieee80211_action_name(wh);
  243                         else
  244                                 subtype_name = ieee80211_mgt_subtype_name[
  245                                     (type & IEEE80211_FC0_SUBTYPE_MASK) >>
  246                                     IEEE80211_FC0_SUBTYPE_SHIFT];
  247                         printf("%s: sending %s to %s on channel %u mode %s\n",
  248                             ifp->if_xname, subtype_name,
  249                             ether_sprintf(ni->ni_macaddr),
  250                             ieee80211_chan2ieee(ic, ni->ni_chan),
  251                             ieee80211_phymode_name[ic->ic_curmode]);
  252                 }
  253         }
  254 
  255 #ifndef IEEE80211_STA_ONLY
  256         if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
  257             ieee80211_pwrsave(ic, m, ni) != 0)
  258                 return 0;
  259 #endif
  260         mq_enqueue(&ic->ic_mgtq, m);
  261         ifp->if_timer = 1;
  262         if_start(ifp);
  263         return 0;
  264 }
  265 
  266 /*-
  267  * EDCA tables are computed using the following formulas:
  268  *
  269  * 1) EDCATable (non-AP QSTA)
  270  *
  271  * AC     CWmin            CWmax           AIFSN  TXOP limit(ms)
  272  * -------------------------------------------------------------
  273  * AC_BK  aCWmin           aCWmax          7      0
  274  * AC_BE  aCWmin           aCWmax          3      0
  275  * AC_VI  (aCWmin+1)/2-1   aCWmin          2      agn=3.008 b=6.016 others=0
  276  * AC_VO  (aCWmin+1)/4-1   (aCWmin+1)/2-1  2      agn=1.504 b=3.264 others=0
  277  *
  278  * 2) QAPEDCATable (QAP)
  279  *
  280  * AC     CWmin            CWmax           AIFSN  TXOP limit(ms)
  281  * -------------------------------------------------------------
  282  * AC_BK  aCWmin           aCWmax          7      0
  283  * AC_BE  aCWmin           4*(aCWmin+1)-1  3      0
  284  * AC_VI  (aCWmin+1)/2-1   aCWmin          1      agn=3.008 b=6.016 others=0
  285  * AC_VO  (aCWmin+1)/4-1   (aCWmin+1)/2-1  1      agn=1.504 b=3.264 others=0
  286  *
  287  * and the following aCWmin/aCWmax values:
  288  *
  289  * PHY          aCWmin  aCWmax
  290  * ---------------------------
  291  * 11A          15      1023
  292  * 11B          31      1023
  293  * 11G          15*     1023    (*) aCWmin(1)
  294  * 11N          15      1023
  295  */
  296 const struct ieee80211_edca_ac_params
  297     ieee80211_edca_table[IEEE80211_MODE_MAX][EDCA_NUM_AC] = {
  298         [IEEE80211_MODE_11B] = {
  299                 [EDCA_AC_BK] = { 5, 10, 7,   0 },
  300                 [EDCA_AC_BE] = { 5, 10, 3,   0 },
  301                 [EDCA_AC_VI] = { 4,  5, 2, 188 },
  302                 [EDCA_AC_VO] = { 3,  4, 2, 102 }
  303         },
  304         [IEEE80211_MODE_11A] = {
  305                 [EDCA_AC_BK] = { 4, 10, 7,   0 },
  306                 [EDCA_AC_BE] = { 4, 10, 3,   0 },
  307                 [EDCA_AC_VI] = { 3,  4, 2,  94 },
  308                 [EDCA_AC_VO] = { 2,  3, 2,  47 }
  309         },
  310         [IEEE80211_MODE_11G] = {
  311                 [EDCA_AC_BK] = { 4, 10, 7,   0 },
  312                 [EDCA_AC_BE] = { 4, 10, 3,   0 },
  313                 [EDCA_AC_VI] = { 3,  4, 2,  94 },
  314                 [EDCA_AC_VO] = { 2,  3, 2,  47 }
  315         },
  316         [IEEE80211_MODE_11N] = {
  317                 [EDCA_AC_BK] = { 4, 10, 7,   0 },
  318                 [EDCA_AC_BE] = { 4, 10, 3,   0 },
  319                 [EDCA_AC_VI] = { 3,  4, 2,  94 },
  320                 [EDCA_AC_VO] = { 2,  3, 2,  47 }
  321         },
  322         [IEEE80211_MODE_11AC] = {
  323                 [EDCA_AC_BK] = { 4, 10, 7,   0 },
  324                 [EDCA_AC_BE] = { 4, 10, 3,   0 },
  325                 [EDCA_AC_VI] = { 3,  4, 2,  94 },
  326                 [EDCA_AC_VO] = { 2,  3, 2,  47 }
  327         },
  328 };
  329 
  330 #ifndef IEEE80211_STA_ONLY
  331 const struct ieee80211_edca_ac_params
  332     ieee80211_qap_edca_table[IEEE80211_MODE_MAX][EDCA_NUM_AC] = {
  333         [IEEE80211_MODE_11B] = {
  334                 [EDCA_AC_BK] = { 5, 10, 7,   0 },
  335                 [EDCA_AC_BE] = { 5,  7, 3,   0 },
  336                 [EDCA_AC_VI] = { 4,  5, 1, 188 },
  337                 [EDCA_AC_VO] = { 3,  4, 1, 102 }
  338         },
  339         [IEEE80211_MODE_11A] = {
  340                 [EDCA_AC_BK] = { 4, 10, 7,   0 },
  341                 [EDCA_AC_BE] = { 4,  6, 3,   0 },
  342                 [EDCA_AC_VI] = { 3,  4, 1,  94 },
  343                 [EDCA_AC_VO] = { 2,  3, 1,  47 }
  344         },
  345         [IEEE80211_MODE_11G] = {
  346                 [EDCA_AC_BK] = { 4, 10, 7,   0 },
  347                 [EDCA_AC_BE] = { 4,  6, 3,   0 },
  348                 [EDCA_AC_VI] = { 3,  4, 1,  94 },
  349                 [EDCA_AC_VO] = { 2,  3, 1,  47 }
  350         },
  351         [IEEE80211_MODE_11N] = {
  352                 [EDCA_AC_BK] = { 4, 10, 7,   0 },
  353                 [EDCA_AC_BE] = { 4,  6, 3,   0 },
  354                 [EDCA_AC_VI] = { 3,  4, 1,  94 },
  355                 [EDCA_AC_VO] = { 2,  3, 1,  47 }
  356         },
  357         [IEEE80211_MODE_11AC] = {
  358                 [EDCA_AC_BK] = { 4, 10, 7,   0 },
  359                 [EDCA_AC_BE] = { 4,  6, 3,   0 },
  360                 [EDCA_AC_VI] = { 3,  4, 1,  94 },
  361                 [EDCA_AC_VO] = { 2,  3, 1,  47 }
  362         },
  363 };
  364 #endif  /* IEEE80211_STA_ONLY */
  365 
  366 /*
  367  * Return the EDCA Access Category to be used for transmitting a frame with
  368  * user-priority `up'.
  369  */
  370 enum ieee80211_edca_ac
  371 ieee80211_up_to_ac(struct ieee80211com *ic, int up)
  372 {
  373         /* see Table 9-1 */
  374         static const enum ieee80211_edca_ac up_to_ac[] = {
  375                 EDCA_AC_BE,     /* BE */
  376                 EDCA_AC_BK,     /* BK */
  377                 EDCA_AC_BK,     /* -- */
  378                 EDCA_AC_BE,     /* EE */
  379                 EDCA_AC_VI,     /* CL */
  380                 EDCA_AC_VI,     /* VI */
  381                 EDCA_AC_VO,     /* VO */
  382                 EDCA_AC_VO      /* NC */
  383         };
  384         enum ieee80211_edca_ac ac;
  385 
  386         ac = (up <= 7) ? up_to_ac[up] : EDCA_AC_BE;
  387 
  388 #ifndef IEEE80211_STA_ONLY
  389         if (ic->ic_opmode == IEEE80211_M_HOSTAP)
  390                 return ac;
  391 #endif
  392         /*
  393          * We do not support the admission control procedure defined in
  394          * IEEE Std 802.11-2012 section 9.19.4.2.3. The spec says that
  395          * non-AP QSTAs that don't support this procedure shall use EDCA
  396          * parameters of a lower priority AC that does not require
  397          * admission control.
  398          */
  399         while (ac != EDCA_AC_BK && ic->ic_edca_ac[ac].ac_acm) {
  400                 switch (ac) {
  401                 case EDCA_AC_BK:
  402                         /* can't get there */
  403                         break;
  404                 case EDCA_AC_BE:
  405                         /* BE shouldn't require admission control */
  406                         ac = EDCA_AC_BK;
  407                         break;
  408                 case EDCA_AC_VI:
  409                         ac = EDCA_AC_BE;
  410                         break;
  411                 case EDCA_AC_VO:
  412                         ac = EDCA_AC_VI;
  413                         break;
  414                 }
  415         }
  416         return ac;
  417 }
  418 
  419 /*
  420  * Get mbuf's user-priority: if mbuf is not VLAN tagged, select user-priority
  421  * based on the DSCP (Differentiated Services Codepoint) field.
  422  */
  423 int
  424 ieee80211_classify(struct ieee80211com *ic, struct mbuf *m)
  425 {
  426         struct ether_header eh;
  427         u_int8_t ds_field;
  428 #if NVLAN > 0
  429         if (m->m_flags & M_VLANTAG)     /* use VLAN 802.1D user-priority */
  430                 return EVL_PRIOFTAG(m->m_pkthdr.ether_vtag);
  431 #endif
  432         m_copydata(m, 0, sizeof(eh), (caddr_t)&eh);
  433         if (eh.ether_type == htons(ETHERTYPE_IP)) {
  434                 struct ip ip;
  435                 m_copydata(m, sizeof(eh), sizeof(ip), (caddr_t)&ip);
  436                 if (ip.ip_v != 4)
  437                         return 0;
  438                 ds_field = ip.ip_tos;
  439         }
  440 #ifdef INET6
  441         else if (eh.ether_type == htons(ETHERTYPE_IPV6)) {
  442                 struct ip6_hdr ip6;
  443                 u_int32_t flowlabel;
  444                 m_copydata(m, sizeof(eh), sizeof(ip6), (caddr_t)&ip6);
  445                 flowlabel = ntohl(ip6.ip6_flow);
  446                 if ((flowlabel >> 28) != 6)
  447                         return 0;
  448                 ds_field = (flowlabel >> 20) & 0xff;
  449         }
  450 #endif  /* INET6 */
  451         else    /* neither IPv4 nor IPv6 */
  452                 return 0;
  453 
  454         /*
  455          * Map Differentiated Services Codepoint field (see RFC2474).
  456          * Preserves backward compatibility with IP Precedence field.
  457          */
  458         switch (ds_field & 0xfc) {
  459         case IPTOS_PREC_PRIORITY:
  460                 return EDCA_AC_VI;
  461         case IPTOS_PREC_IMMEDIATE:
  462                 return EDCA_AC_BK;
  463         case IPTOS_PREC_FLASH:
  464         case IPTOS_PREC_FLASHOVERRIDE:
  465         case IPTOS_PREC_CRITIC_ECP:
  466         case IPTOS_PREC_INTERNETCONTROL:
  467         case IPTOS_PREC_NETCONTROL:
  468                 return EDCA_AC_VO;
  469         default:
  470                 return EDCA_AC_BE;
  471         }
  472 }
  473 
  474 int
  475 ieee80211_can_use_ampdu(struct ieee80211com *ic, struct ieee80211_node *ni)
  476 {
  477         return (ni->ni_flags & IEEE80211_NODE_HT) &&
  478             (ic->ic_caps & IEEE80211_C_TX_AMPDU) &&
  479             !(ic->ic_opmode == IEEE80211_M_STA && ni != ic->ic_bss) &&
  480             /*
  481              * Don't use A-MPDU on non-encrypted networks. There are devices
  482              * with buggy firmware which allow an attacker to inject 802.11
  483              * frames into a wifi network by embedding rogue A-MPDU subframes
  484              * in an arbitrary data payload (e.g. PNG images) which may end
  485              * up appearing as actual frames after de-aggregation by a buggy
  486              * device; see https://github.com/rpp0/aggr-inject for details.
  487              * WPA2 prevents this injection attack since the attacker would
  488              * need to inject frames which get decrypted correctly.
  489              */
  490             ((ic->ic_flags & IEEE80211_F_RSNON) &&
  491               (ni->ni_rsnprotos & IEEE80211_PROTO_RSN));
  492 }
  493 
  494 void
  495 ieee80211_tx_compressed_bar(struct ieee80211com *ic, struct ieee80211_node *ni,
  496     int tid, uint16_t ssn)
  497 {
  498         struct ifnet *ifp = &ic->ic_if;
  499         struct mbuf *m;
  500 
  501         m = ieee80211_get_compressed_bar(ic, ni, tid, ssn);
  502         if (m == NULL)
  503                 return;
  504 
  505         ieee80211_ref_node(ni);
  506         if (mq_enqueue(&ic->ic_mgtq, m) == 0)
  507                 if_start(ifp);
  508         else
  509                 ieee80211_release_node(ic, ni);
  510 }
  511 
  512 /*
  513  * Encapsulate an outbound data frame.  The mbuf chain is updated and
  514  * a reference to the destination node is returned.  If an error is
  515  * encountered NULL is returned and the node reference will also be NULL.
  516  *
  517  * NB: The caller is responsible for free'ing a returned node reference.
  518  *     The convention is ic_bss is not reference counted; the caller must
  519  *     maintain that.
  520  */
  521 struct mbuf *
  522 ieee80211_encap(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node **pni)
  523 {
  524         struct ieee80211com *ic = (void *)ifp;
  525         struct ether_header eh;
  526         struct ieee80211_frame *wh;
  527         struct ieee80211_node *ni = NULL;
  528         struct llc *llc;
  529         struct m_tag *mtag;
  530         u_int8_t *addr;
  531         u_int dlt, hdrlen;
  532         int addqos, tid;
  533 
  534         /* Handle raw frames if mbuf is tagged as 802.11 */
  535         if ((mtag = m_tag_find(m, PACKET_TAG_DLT, NULL)) != NULL) {
  536                 dlt = *(u_int *)(mtag + 1);
  537 
  538                 if (!(dlt == DLT_IEEE802_11 || dlt == DLT_IEEE802_11_RADIO))
  539                         goto fallback;
  540 
  541                 wh = mtod(m, struct ieee80211_frame *);
  542                 switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
  543                 case IEEE80211_FC1_DIR_NODS:
  544                 case IEEE80211_FC1_DIR_FROMDS:
  545                         addr = wh->i_addr1;
  546                         break;
  547                 case IEEE80211_FC1_DIR_DSTODS:
  548                 case IEEE80211_FC1_DIR_TODS:
  549                         addr = wh->i_addr3;
  550                         break;
  551                 default:
  552                         goto bad;
  553                 }
  554 
  555                 ni = ieee80211_find_txnode(ic, addr);
  556                 if (ni == NULL)
  557                         ni = ieee80211_ref_node(ic->ic_bss);
  558                 if (ni == NULL) {
  559                         printf("%s: no node for dst %s, "
  560                             "discard raw tx frame\n", ifp->if_xname,
  561                             ether_sprintf(addr));
  562                         ic->ic_stats.is_tx_nonode++;
  563                         goto bad;
  564                 }
  565                 ni->ni_inact = 0;
  566 
  567                 *pni = ni;
  568                 return (m);
  569         }
  570 
  571  fallback:
  572         if (m->m_len < sizeof(struct ether_header)) {
  573                 m = m_pullup(m, sizeof(struct ether_header));
  574                 if (m == NULL) {
  575                         ic->ic_stats.is_tx_nombuf++;
  576                         goto bad;
  577                 }
  578         }
  579         memcpy(&eh, mtod(m, caddr_t), sizeof(struct ether_header));
  580 
  581         ni = ieee80211_find_txnode(ic, eh.ether_dhost);
  582         if (ni == NULL) {
  583                 DPRINTF(("no node for dst %s, discard frame\n",
  584                     ether_sprintf(eh.ether_dhost)));
  585                 ic->ic_stats.is_tx_nonode++;
  586                 goto bad;
  587         }
  588 
  589 #ifndef IEEE80211_STA_ONLY
  590         if (ic->ic_opmode == IEEE80211_M_HOSTAP && ni != ic->ic_bss &&
  591             ni->ni_state != IEEE80211_STA_ASSOC) {
  592                 ic->ic_stats.is_tx_nonode++;
  593                 goto bad;
  594         }
  595 #endif
  596 
  597         if ((ic->ic_flags & IEEE80211_F_RSNON) &&
  598             !ni->ni_port_valid &&
  599             eh.ether_type != htons(ETHERTYPE_EAPOL)) {
  600                 DPRINTF(("port not valid: %s\n",
  601                     ether_sprintf(eh.ether_dhost)));
  602                 ic->ic_stats.is_tx_noauth++;
  603                 goto bad;
  604         }
  605 
  606         if ((ic->ic_flags & IEEE80211_F_COUNTERM) &&
  607             ni->ni_rsncipher == IEEE80211_CIPHER_TKIP)
  608                 /* XXX TKIP countermeasures! */;
  609 
  610         ni->ni_inact = 0;
  611 
  612         if ((ic->ic_flags & IEEE80211_F_QOS) &&
  613             (ni->ni_flags & IEEE80211_NODE_QOS) &&
  614             /* do not QoS-encapsulate EAPOL frames */
  615             eh.ether_type != htons(ETHERTYPE_EAPOL)) {
  616                 struct ieee80211_tx_ba *ba;
  617                 tid = ieee80211_classify(ic, m);
  618                 ba = &ni->ni_tx_ba[tid];
  619                 /* We use QoS data frames for aggregation only. */
  620                 if (ba->ba_state != IEEE80211_BA_AGREED) {
  621                         hdrlen = sizeof(struct ieee80211_frame);
  622                         addqos = 0;
  623                         if (ieee80211_can_use_ampdu(ic, ni))
  624                                 ieee80211_node_trigger_addba_req(ni, tid);
  625                 } else {
  626                         hdrlen = sizeof(struct ieee80211_qosframe);
  627                         addqos = 1;
  628                 }
  629         } else {
  630                 hdrlen = sizeof(struct ieee80211_frame);
  631                 addqos = 0;
  632         }
  633         m_adj(m, sizeof(struct ether_header) - LLC_SNAPFRAMELEN);
  634         llc = mtod(m, struct llc *);
  635         llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
  636         llc->llc_control = LLC_UI;
  637         llc->llc_snap.org_code[0] = 0;
  638         llc->llc_snap.org_code[1] = 0;
  639         llc->llc_snap.org_code[2] = 0;
  640         llc->llc_snap.ether_type = eh.ether_type;
  641         M_PREPEND(m, hdrlen, M_DONTWAIT);
  642         if (m == NULL) {
  643                 ic->ic_stats.is_tx_nombuf++;
  644                 goto bad;
  645         }
  646         wh = mtod(m, struct ieee80211_frame *);
  647         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
  648         *(u_int16_t *)&wh->i_dur[0] = 0;
  649         if (addqos) {
  650                 struct ieee80211_qosframe *qwh =
  651                     (struct ieee80211_qosframe *)wh;
  652                 u_int16_t qos = tid;
  653 
  654                 if (ic->ic_tid_noack & (1 << tid))
  655                         qos |= IEEE80211_QOS_ACK_POLICY_NOACK;
  656                 else {
  657                         /* Use HT immediate block-ack. */
  658                         qos |= IEEE80211_QOS_ACK_POLICY_NORMAL;
  659                 }
  660                 qwh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS;
  661                 *(u_int16_t *)qwh->i_qos = htole16(qos);
  662                 *(u_int16_t *)qwh->i_seq =
  663                     htole16(ni->ni_qos_txseqs[tid] << IEEE80211_SEQ_SEQ_SHIFT);
  664                 ni->ni_qos_txseqs[tid] = (ni->ni_qos_txseqs[tid] + 1) & 0xfff;
  665         } else {
  666                 *(u_int16_t *)&wh->i_seq[0] =
  667                     htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
  668                 ni->ni_txseq = (ni->ni_txseq + 1) & 0xfff;
  669         }
  670         switch (ic->ic_opmode) {
  671         case IEEE80211_M_STA:
  672                 wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
  673                 IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_bssid);
  674                 IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
  675                 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost);
  676                 break;
  677 #ifndef IEEE80211_STA_ONLY
  678         case IEEE80211_M_IBSS:
  679         case IEEE80211_M_AHDEMO:
  680                 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
  681                 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
  682                 IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
  683                 IEEE80211_ADDR_COPY(wh->i_addr3, ic->ic_bss->ni_bssid);
  684                 break;
  685         case IEEE80211_M_HOSTAP:
  686                 wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
  687                 IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
  688                 IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid);
  689                 IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost);
  690                 break;
  691 #endif
  692         default:
  693                 /* should not get there */
  694                 goto bad;
  695         }
  696 
  697         if ((ic->ic_flags & IEEE80211_F_WEPON) ||
  698             ((ic->ic_flags & IEEE80211_F_RSNON) &&
  699              (ni->ni_flags & IEEE80211_NODE_TXPROT)))
  700                 wh->i_fc[1] |= IEEE80211_FC1_PROTECTED;
  701 
  702 #ifndef IEEE80211_STA_ONLY
  703         if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
  704             ieee80211_pwrsave(ic, m, ni) != 0) {
  705                 *pni = NULL;
  706                 return NULL;
  707         }
  708 #endif
  709         *pni = ni;
  710         return m;
  711 bad:
  712         m_freem(m);
  713         if (ni != NULL)
  714                 ieee80211_release_node(ic, ni);
  715         *pni = NULL;
  716         return NULL;
  717 }
  718 
  719 /*
  720  * Add a Capability Information field to a frame (see 7.3.1.4).
  721  */
  722 u_int8_t *
  723 ieee80211_add_capinfo(u_int8_t *frm, struct ieee80211com *ic,
  724     const struct ieee80211_node *ni)
  725 {
  726         u_int16_t capinfo;
  727 
  728 #ifndef IEEE80211_STA_ONLY
  729         if (ic->ic_opmode == IEEE80211_M_IBSS)
  730                 capinfo = IEEE80211_CAPINFO_IBSS;
  731         else if (ic->ic_opmode == IEEE80211_M_HOSTAP)
  732                 capinfo = IEEE80211_CAPINFO_ESS;
  733         else
  734 #endif
  735                 capinfo = 0;
  736 #ifndef IEEE80211_STA_ONLY
  737         if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
  738             (ic->ic_flags & (IEEE80211_F_WEPON | IEEE80211_F_RSNON)))
  739                 capinfo |= IEEE80211_CAPINFO_PRIVACY;
  740 #endif
  741         /* NB: some 11a AP's reject the request when short preamble is set */
  742         if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
  743             IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
  744                 capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
  745         if (ic->ic_flags & IEEE80211_F_SHSLOT)
  746                 capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
  747         LE_WRITE_2(frm, capinfo);
  748         return frm + 2;
  749 }
  750 
  751 /*
  752  * Add an SSID element to a frame (see 7.3.2.1).
  753  */
  754 u_int8_t *
  755 ieee80211_add_ssid(u_int8_t *frm, const u_int8_t *ssid, u_int len)
  756 {
  757         *frm++ = IEEE80211_ELEMID_SSID;
  758         *frm++ = len;
  759         memcpy(frm, ssid, len);
  760         return frm + len;
  761 }
  762 
  763 /*
  764  * Add a supported rates element to a frame (see 7.3.2.2).
  765  */
  766 u_int8_t *
  767 ieee80211_add_rates(u_int8_t *frm, const struct ieee80211_rateset *rs)
  768 {
  769         int nrates;
  770 
  771         *frm++ = IEEE80211_ELEMID_RATES;
  772         nrates = min(rs->rs_nrates, IEEE80211_RATE_SIZE);
  773         *frm++ = nrates;
  774         memcpy(frm, rs->rs_rates, nrates);
  775         return frm + nrates;
  776 }
  777 
  778 #ifndef IEEE80211_STA_ONLY
  779 /*
  780  * Add a DS Parameter Set element to a frame (see 7.3.2.4).
  781  */
  782 u_int8_t *
  783 ieee80211_add_ds_params(u_int8_t *frm, struct ieee80211com *ic,
  784     const struct ieee80211_node *ni)
  785 {
  786         *frm++ = IEEE80211_ELEMID_DSPARMS;
  787         *frm++ = 1;
  788         *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan);
  789         return frm;
  790 }
  791 
  792 /*
  793  * Add a TIM element to a frame (see 7.3.2.6 and Annex L).
  794  */
  795 u_int8_t *
  796 ieee80211_add_tim(u_int8_t *frm, struct ieee80211com *ic)
  797 {
  798         u_int i, offset = 0, len;
  799 
  800         /* find first non-zero octet in the virtual bit map */
  801         for (i = 0; i < ic->ic_tim_len && ic->ic_tim_bitmap[i] == 0; i++);
  802 
  803         /* clear the lsb as it is reserved for the broadcast indication bit */
  804         if (i < ic->ic_tim_len)
  805                 offset = i & ~1;
  806 
  807         /* find last non-zero octet in the virtual bit map */
  808         for (i = ic->ic_tim_len - 1; i > 0 && ic->ic_tim_bitmap[i] == 0; i--);
  809 
  810         len = i - offset + 1;
  811 
  812         *frm++ = IEEE80211_ELEMID_TIM;
  813         *frm++ = len + 3;               /* length */
  814         *frm++ = ic->ic_dtim_count;     /* DTIM count */
  815         *frm++ = ic->ic_dtim_period;    /* DTIM period */
  816 
  817         /* Bitmap Control */
  818         *frm = offset;
  819         /* set broadcast/multicast indication bit if necessary */
  820         if (ic->ic_dtim_count == 0 && ic->ic_tim_mcast_pending)
  821                 *frm |= 0x01;
  822         frm++;
  823 
  824         /* Partial Virtual Bitmap */
  825         memcpy(frm, &ic->ic_tim_bitmap[offset], len);
  826         return frm + len;
  827 }
  828 
  829 /*
  830  * Add an IBSS Parameter Set element to a frame (see 7.3.2.7).
  831  */
  832 u_int8_t *
  833 ieee80211_add_ibss_params(u_int8_t *frm, const struct ieee80211_node *ni)
  834 {
  835         *frm++ = IEEE80211_ELEMID_IBSSPARMS;
  836         *frm++ = 2;
  837         LE_WRITE_2(frm, 0);     /* TODO: ATIM window */
  838         return frm + 2;
  839 }
  840 
  841 /*
  842  * Add an EDCA Parameter Set element to a frame (see 7.3.2.29).
  843  */
  844 u_int8_t *
  845 ieee80211_add_edca_params(u_int8_t *frm, struct ieee80211com *ic)
  846 {
  847         const struct ieee80211_edca_ac_params *edca;
  848         int aci;
  849 
  850         *frm++ = IEEE80211_ELEMID_EDCAPARMS;
  851         *frm++ = 18;    /* length */
  852         *frm++ = 0;     /* QoS Info */
  853         *frm++ = 0;     /* reserved */
  854 
  855         /* setup AC Parameter Records */
  856         edca = ieee80211_edca_table[ic->ic_curmode];
  857         for (aci = 0; aci < EDCA_NUM_AC; aci++) {
  858                 const struct ieee80211_edca_ac_params *ac = &edca[aci];
  859 
  860                 *frm++ = (aci << 5) | ((ac->ac_acm & 0x1) << 4) |
  861                          (ac->ac_aifsn & 0xf);
  862                 *frm++ = (ac->ac_ecwmax << 4) |
  863                          (ac->ac_ecwmin & 0xf);
  864                 LE_WRITE_2(frm, ac->ac_txoplimit); frm += 2;
  865         }
  866         return frm;
  867 }
  868 
  869 /*
  870  * Add an ERP element to a frame (see 7.3.2.13).
  871  */
  872 u_int8_t *
  873 ieee80211_add_erp(u_int8_t *frm, struct ieee80211com *ic)
  874 {
  875         u_int8_t erp;
  876         int nonerpsta = 0;
  877 
  878         *frm++ = IEEE80211_ELEMID_ERP;
  879         *frm++ = 1;
  880         erp = 0;
  881         /*
  882          * The NonERP_Present bit shall be set to 1 when a NonERP STA
  883          * is associated with the BSS.
  884          */
  885         ieee80211_iterate_nodes(ic, ieee80211_count_nonerpsta, &nonerpsta);
  886         if (nonerpsta != 0)
  887                 erp |= IEEE80211_ERP_NON_ERP_PRESENT;
  888         /*
  889          * If one or more NonERP STAs are associated in the BSS, the
  890          * Use_Protection bit shall be set to 1 in transmitted ERP
  891          * Information Elements.
  892          */
  893         if (ic->ic_flags & IEEE80211_F_USEPROT)
  894                 erp |= IEEE80211_ERP_USE_PROTECTION;
  895         /*
  896          * The Barker_Preamble_Mode bit shall be set to 1 by the ERP
  897          * Information Element sender if one or more associated NonERP
  898          * STAs are not short preamble capable.
  899          */
  900         if (!(ic->ic_flags & IEEE80211_F_SHPREAMBLE))
  901                 erp |= IEEE80211_ERP_BARKER_MODE;
  902         *frm++ = erp;
  903         return frm;
  904 }
  905 #endif  /* IEEE80211_STA_ONLY */
  906 
  907 /*
  908  * Add a QoS Capability element to a frame (see 7.3.2.35).
  909  */
  910 u_int8_t *
  911 ieee80211_add_qos_capability(u_int8_t *frm, struct ieee80211com *ic)
  912 {
  913         *frm++ = IEEE80211_ELEMID_QOS_CAP;
  914         *frm++ = 1;
  915         *frm++ = 0;     /* QoS Info */
  916         return frm;
  917 }
  918 
  919 /*
  920  * Add a Wifi-Alliance WME (aka WMM) info element to a frame.
  921  * WME is a requirement for Wifi-Alliance compliance and some
  922  * 11n APs will not negotiate HT if this element is missing.
  923  */
  924 uint8_t *
  925 ieee80211_add_wme_info(uint8_t *frm, struct ieee80211com *ic)
  926 {
  927         *frm++ = IEEE80211_ELEMID_VENDOR;
  928         *frm++ = 7;
  929         memcpy(frm, MICROSOFT_OUI, 3); frm += 3;
  930         *frm++ = 2; /* OUI type */
  931         *frm++ = 0; /* OUI subtype */
  932         *frm++ = 1; /* version */
  933         *frm++ = 0; /* info */
  934 
  935         return frm;
  936 }
  937 
  938 #ifndef IEEE80211_STA_ONLY
  939 /*
  940  * Add a Wifi-Alliance WMM (aka WME) parameter element to a frame.
  941  */
  942 uint8_t *
  943 ieee80211_add_wme_param(uint8_t *frm, struct ieee80211com *ic)
  944 {
  945         const struct ieee80211_edca_ac_params *edca;
  946         int aci;
  947 
  948         *frm++ = IEEE80211_ELEMID_VENDOR;
  949         *frm++ = 24;
  950         memcpy(frm, MICROSOFT_OUI, 3); frm += 3;
  951         *frm++ = 2; /* OUI type */
  952         *frm++ = 1; /* OUI subtype */
  953         *frm++ = 1; /* version */
  954         *frm++ = 0; /* info */
  955         *frm++ = 0; /* reserved */
  956 
  957         /* setup AC Parameter Records */
  958         edca = ieee80211_edca_table[ic->ic_curmode];
  959         for (aci = 0; aci < EDCA_NUM_AC; aci++) {
  960                 const struct ieee80211_edca_ac_params *ac = &edca[aci];
  961 
  962                 *frm++ = (aci << 5) | ((ac->ac_acm & 0x1) << 4) |
  963                          (ac->ac_aifsn & 0xf);
  964                 *frm++ = (ac->ac_ecwmax << 4) |
  965                          (ac->ac_ecwmin & 0xf);
  966                 LE_WRITE_2(frm, ac->ac_txoplimit); frm += 2;
  967         }
  968 
  969         return frm;
  970 }
  971 #endif
  972 
  973 /*
  974  * Add an RSN element to a frame (see 802.11-2012 8.4.2.27)
  975  */
  976 u_int8_t *
  977 ieee80211_add_rsn_body(u_int8_t *frm, struct ieee80211com *ic,
  978     const struct ieee80211_node *ni, int wpa)
  979 {
  980         const u_int8_t *oui = wpa ? MICROSOFT_OUI : IEEE80211_OUI;
  981         u_int8_t *pcount;
  982         u_int16_t count, rsncaps;
  983 
  984         /* write Version field */
  985         LE_WRITE_2(frm, 1); frm += 2;
  986 
  987         /* write Group Data Cipher Suite field (see 802.11-2012 Table 8-99) */
  988         memcpy(frm, oui, 3); frm += 3;
  989         switch (ni->ni_rsngroupcipher) {
  990         case IEEE80211_CIPHER_WEP40:
  991                 *frm++ = 1;
  992                 break;
  993         case IEEE80211_CIPHER_TKIP:
  994                 *frm++ = 2;
  995                 break;
  996         case IEEE80211_CIPHER_CCMP:
  997                 *frm++ = 4;
  998                 break;
  999         case IEEE80211_CIPHER_WEP104:
 1000                 *frm++ = 5;
 1001                 break;
 1002         default:
 1003                 /* can't get there */
 1004                 panic("invalid group data cipher!");
 1005         }
 1006 
 1007         pcount = frm; frm += 2;
 1008         count = 0;
 1009         /* write Pairwise Cipher Suite List */
 1010         if (ni->ni_rsnciphers & IEEE80211_CIPHER_USEGROUP) {
 1011                 memcpy(frm, oui, 3); frm += 3;
 1012                 *frm++ = 0;
 1013                 count++;
 1014         }
 1015         if (ni->ni_rsnciphers & IEEE80211_CIPHER_TKIP) {
 1016                 memcpy(frm, oui, 3); frm += 3;
 1017                 *frm++ = 2;
 1018                 count++;
 1019         }
 1020         if (ni->ni_rsnciphers & IEEE80211_CIPHER_CCMP) {
 1021                 memcpy(frm, oui, 3); frm += 3;
 1022                 *frm++ = 4;
 1023                 count++;
 1024         }
 1025         /* write Pairwise Cipher Suite Count field */
 1026         LE_WRITE_2(pcount, count);
 1027 
 1028         pcount = frm; frm += 2;
 1029         count = 0;
 1030         /* write AKM Suite List (see Table 20dc) */
 1031         if (ni->ni_rsnakms & IEEE80211_AKM_8021X) {
 1032                 memcpy(frm, oui, 3); frm += 3;
 1033                 *frm++ = 1;
 1034                 count++;
 1035         }
 1036         if (ni->ni_rsnakms & IEEE80211_AKM_PSK) {
 1037                 memcpy(frm, oui, 3); frm += 3;
 1038                 *frm++ = 2;
 1039                 count++;
 1040         }
 1041         if (!wpa && (ni->ni_rsnakms & IEEE80211_AKM_SHA256_8021X)) {
 1042                 memcpy(frm, oui, 3); frm += 3;
 1043                 *frm++ = 5;
 1044                 count++;
 1045         }
 1046         if (!wpa && (ni->ni_rsnakms & IEEE80211_AKM_SHA256_PSK)) {
 1047                 memcpy(frm, oui, 3); frm += 3;
 1048                 *frm++ = 6;
 1049                 count++;
 1050         }
 1051         /* write AKM Suite List Count field */
 1052         LE_WRITE_2(pcount, count);
 1053 
 1054         if (wpa)
 1055                 return frm;
 1056 
 1057         /* write RSN Capabilities field */
 1058         rsncaps = (ni->ni_rsncaps & (IEEE80211_RSNCAP_PTKSA_RCNT_MASK |
 1059             IEEE80211_RSNCAP_GTKSA_RCNT_MASK));
 1060         if (ic->ic_caps & IEEE80211_C_MFP) {
 1061                 rsncaps |= IEEE80211_RSNCAP_MFPC;
 1062                 if (ic->ic_flags & IEEE80211_F_MFPR)
 1063                         rsncaps |= IEEE80211_RSNCAP_MFPR;
 1064         }
 1065         if (ic->ic_flags & IEEE80211_F_PBAR)
 1066                 rsncaps |= IEEE80211_RSNCAP_PBAC;
 1067         LE_WRITE_2(frm, rsncaps); frm += 2;
 1068 
 1069         if (ni->ni_flags & IEEE80211_NODE_PMKID) {
 1070                 /* write PMKID Count field */
 1071                 LE_WRITE_2(frm, 1); frm += 2;
 1072                 /* write PMKID List (only 1) */
 1073                 memcpy(frm, ni->ni_pmkid, IEEE80211_PMKID_LEN);
 1074                 frm += IEEE80211_PMKID_LEN;
 1075         }
 1076 
 1077         if (!(ic->ic_caps & IEEE80211_C_MFP))
 1078                 return frm;
 1079 
 1080         if ((ni->ni_flags & IEEE80211_NODE_PMKID) == 0) {
 1081                 /* no PMKID (PMKID Count=0) */
 1082                 LE_WRITE_2(frm, 0); frm += 2;
 1083         }
 1084 
 1085         /* write Group Integrity Cipher Suite field */
 1086         memcpy(frm, oui, 3); frm += 3;
 1087         switch (ic->ic_rsngroupmgmtcipher) {
 1088         case IEEE80211_CIPHER_BIP:
 1089                 *frm++ = 6;
 1090                 break;
 1091         default:
 1092                 /* can't get there */
 1093                 panic("invalid integrity group cipher!");
 1094         }
 1095         return frm;
 1096 }
 1097 
 1098 u_int8_t *
 1099 ieee80211_add_rsn(u_int8_t *frm, struct ieee80211com *ic,
 1100     const struct ieee80211_node *ni)
 1101 {
 1102         u_int8_t *plen;
 1103 
 1104         *frm++ = IEEE80211_ELEMID_RSN;
 1105         plen = frm++;   /* length filled in later */
 1106         frm = ieee80211_add_rsn_body(frm, ic, ni, 0);
 1107 
 1108         /* write length field */
 1109         *plen = frm - plen - 1;
 1110         return frm;
 1111 }
 1112 
 1113 /*
 1114  * Add a vendor-specific WPA element to a frame.
 1115  * This is required for compatibility with Wi-Fi Alliance WPA.
 1116  */
 1117 u_int8_t *
 1118 ieee80211_add_wpa(u_int8_t *frm, struct ieee80211com *ic,
 1119     const struct ieee80211_node *ni)
 1120 {
 1121         u_int8_t *plen;
 1122 
 1123         *frm++ = IEEE80211_ELEMID_VENDOR;
 1124         plen = frm++;   /* length filled in later */
 1125         memcpy(frm, MICROSOFT_OUI, 3); frm += 3;
 1126         *frm++ = 1;     /* WPA */
 1127         frm = ieee80211_add_rsn_body(frm, ic, ni, 1);
 1128 
 1129         /* write length field */
 1130         *plen = frm - plen - 1;
 1131         return frm;
 1132 }
 1133 
 1134 /*
 1135  * Add an extended supported rates element to a frame (see 7.3.2.14).
 1136  */
 1137 u_int8_t *
 1138 ieee80211_add_xrates(u_int8_t *frm, const struct ieee80211_rateset *rs)
 1139 {
 1140         int nrates;
 1141 
 1142         KASSERT(rs->rs_nrates > IEEE80211_RATE_SIZE);
 1143 
 1144         *frm++ = IEEE80211_ELEMID_XRATES;
 1145         nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
 1146         *frm++ = nrates;
 1147         memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
 1148         return frm + nrates;
 1149 }
 1150 
 1151 /*
 1152  * Add an HT Capabilities element to a frame (see 7.3.2.57).
 1153  */
 1154 u_int8_t *
 1155 ieee80211_add_htcaps(u_int8_t *frm, struct ieee80211com *ic)
 1156 {
 1157         *frm++ = IEEE80211_ELEMID_HTCAPS;
 1158         *frm++ = 26;
 1159         LE_WRITE_2(frm, ic->ic_htcaps); frm += 2;
 1160         *frm++ = ic->ic_ampdu_params;
 1161         memcpy(frm, ic->ic_sup_mcs, 10); frm += 10;
 1162         LE_WRITE_2(frm, (ic->ic_max_rxrate & IEEE80211_MCS_RX_RATE_HIGH));
 1163         frm += 2;
 1164         *frm++ = ic->ic_tx_mcs_set;
 1165         *frm++ = 0; /* reserved */
 1166         *frm++ = 0; /* reserved */
 1167         *frm++ = 0; /* reserved */
 1168         LE_WRITE_2(frm, ic->ic_htxcaps); frm += 2;
 1169         LE_WRITE_4(frm, ic->ic_txbfcaps); frm += 4;
 1170         *frm++ = ic->ic_aselcaps;
 1171         return frm;
 1172 }
 1173 
 1174 #ifndef IEEE80211_STA_ONLY
 1175 /*
 1176  * Add an HT Operation element to a frame (see 7.3.2.58).
 1177  */
 1178 u_int8_t *
 1179 ieee80211_add_htop(u_int8_t *frm, struct ieee80211com *ic)
 1180 {
 1181         *frm++ = IEEE80211_ELEMID_HTOP;
 1182         *frm++ = 22;
 1183         *frm++ = ieee80211_chan2ieee(ic, ic->ic_bss->ni_chan);
 1184         *frm++ = ic->ic_bss->ni_htop0;
 1185         LE_WRITE_2(frm, ic->ic_bss->ni_htop1); frm += 2;
 1186         LE_WRITE_2(frm, ic->ic_bss->ni_htop2); frm += 2;
 1187         memset(frm, 0, 16); frm += 16;
 1188         return frm;
 1189 }
 1190 #endif  /* !IEEE80211_STA_ONLY */
 1191 
 1192 /*
 1193  * Add a VHT Capabilities element to a frame (see 802.11ac-2013 8.4.2.160.2).
 1194  */
 1195 u_int8_t *
 1196 ieee80211_add_vhtcaps(u_int8_t *frm, struct ieee80211com *ic)
 1197 {
 1198         *frm++ = IEEE80211_ELEMID_VHTCAPS;
 1199         *frm++ = 12;
 1200         LE_WRITE_4(frm, ic->ic_vhtcaps); frm += 4;
 1201         LE_WRITE_2(frm, ic->ic_vht_rxmcs); frm += 2;
 1202         LE_WRITE_2(frm, ic->ic_vht_rx_max_lgi_mbit_s); frm += 2;
 1203         LE_WRITE_2(frm, ic->ic_vht_txmcs); frm += 2;
 1204         LE_WRITE_2(frm, ic->ic_vht_tx_max_lgi_mbit_s); frm += 2;
 1205         return frm;
 1206 }
 1207 
 1208 #ifndef IEEE80211_STA_ONLY
 1209 /*
 1210  * Add a Timeout Interval element to a frame (see 7.3.2.49).
 1211  */
 1212 u_int8_t *
 1213 ieee80211_add_tie(u_int8_t *frm, u_int8_t type, u_int32_t value)
 1214 {
 1215         *frm++ = IEEE80211_ELEMID_TIE;
 1216         *frm++ = 5;     /* length */
 1217         *frm++ = type;  /* Timeout Interval type */
 1218         LE_WRITE_4(frm, value);
 1219         return frm + 4;
 1220 }
 1221 #endif
 1222 
 1223 struct mbuf *
 1224 ieee80211_getmgmt(int flags, int type, u_int pktlen)
 1225 {
 1226         struct mbuf *m;
 1227 
 1228         /* reserve space for 802.11 header */
 1229         pktlen += sizeof(struct ieee80211_frame);
 1230 
 1231         if (pktlen > MCLBYTES)
 1232                 panic("management frame too large: %u", pktlen);
 1233         MGETHDR(m, flags, type);
 1234         if (m == NULL)
 1235                 return NULL;
 1236         if (pktlen > MHLEN) {
 1237                 MCLGET(m, flags);
 1238                 if (!(m->m_flags & M_EXT))
 1239                         return m_free(m);
 1240         }
 1241         m->m_data += sizeof(struct ieee80211_frame);
 1242         return m;
 1243 }
 1244 
 1245 /*-
 1246  * Probe request frame format:
 1247  * [tlv] SSID
 1248  * [tlv] Supported rates
 1249  * [tlv] Extended Supported Rates (802.11g)
 1250  * [tlv] HT Capabilities (802.11n)
 1251  */
 1252 struct mbuf *
 1253 ieee80211_get_probe_req(struct ieee80211com *ic, struct ieee80211_node *ni)
 1254 {
 1255         const struct ieee80211_rateset *rs =
 1256             &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
 1257         struct mbuf *m;
 1258         u_int8_t *frm;
 1259 
 1260         m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA,
 1261             2 + ic->ic_des_esslen +
 1262             2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
 1263             ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
 1264                 2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
 1265             ((ic->ic_flags & IEEE80211_F_HTON) ? 28 + 9 : 0) +
 1266             ((ic->ic_flags & IEEE80211_F_VHTON) ? 14 : 0));
 1267         if (m == NULL)
 1268                 return NULL;
 1269 
 1270         frm = mtod(m, u_int8_t *);
 1271         frm = ieee80211_add_ssid(frm, ic->ic_des_essid, ic->ic_des_esslen);
 1272         frm = ieee80211_add_rates(frm, rs);
 1273         if (rs->rs_nrates > IEEE80211_RATE_SIZE)
 1274                 frm = ieee80211_add_xrates(frm, rs);
 1275         if (ic->ic_flags & IEEE80211_F_HTON) {
 1276                 frm = ieee80211_add_htcaps(frm, ic);
 1277                 frm = ieee80211_add_wme_info(frm, ic);
 1278         }
 1279         if (ic->ic_flags & IEEE80211_F_VHTON)
 1280                 frm = ieee80211_add_htcaps(frm, ic);
 1281 
 1282         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1283 
 1284         return m;
 1285 }
 1286 
 1287 #ifndef IEEE80211_STA_ONLY
 1288 /*-
 1289  * Probe response frame format:
 1290  * [8]   Timestamp
 1291  * [2]   Beacon interval
 1292  * [2]   Capability
 1293  * [tlv] Service Set Identifier (SSID)
 1294  * [tlv] Supported rates
 1295  * [tlv] DS Parameter Set (802.11g)
 1296  * [tlv] ERP Information (802.11g)
 1297  * [tlv] Extended Supported Rates (802.11g)
 1298  * [tlv] RSN (802.11i)
 1299  * [tlv] EDCA Parameter Set (802.11e)
 1300  * [tlv] HT Capabilities (802.11n)
 1301  * [tlv] HT Operation (802.11n)
 1302  */
 1303 struct mbuf *
 1304 ieee80211_get_probe_resp(struct ieee80211com *ic)
 1305 {
 1306         const struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates;
 1307         struct mbuf *m;
 1308         u_int8_t *frm;
 1309 
 1310         m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA,
 1311             8 + 2 + 2 +
 1312             2 + ic->ic_bss->ni_esslen +
 1313             2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
 1314             2 + 1 +
 1315             ((ic->ic_opmode == IEEE80211_M_IBSS) ? 2 + 2 : 0) +
 1316             ((ic->ic_curmode == IEEE80211_MODE_11G) ? 2 + 1 : 0) +
 1317             ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
 1318                 2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
 1319             (((ic->ic_flags & IEEE80211_F_RSNON) &&
 1320               (ic->ic_bss->ni_rsnprotos & IEEE80211_PROTO_RSN)) ?
 1321                 2 + IEEE80211_RSNIE_MAXLEN : 0) +
 1322             ((ic->ic_flags & IEEE80211_F_QOS) ? 2 + 18 : 0) +
 1323             (((ic->ic_flags & IEEE80211_F_RSNON) &&
 1324               (ic->ic_bss->ni_rsnprotos & IEEE80211_PROTO_WPA)) ?
 1325                 2 + IEEE80211_WPAIE_MAXLEN : 0) +
 1326             ((ic->ic_flags & IEEE80211_F_HTON) ? 28 + 24 + 26 : 0));
 1327         if (m == NULL)
 1328                 return NULL;
 1329 
 1330         frm = mtod(m, u_int8_t *);
 1331         memset(frm, 0, 8); frm += 8;    /* timestamp is set by hardware */
 1332         LE_WRITE_2(frm, ic->ic_bss->ni_intval); frm += 2;
 1333         frm = ieee80211_add_capinfo(frm, ic, ic->ic_bss);
 1334         frm = ieee80211_add_ssid(frm, ic->ic_bss->ni_essid,
 1335             ic->ic_bss->ni_esslen);
 1336         frm = ieee80211_add_rates(frm, rs);
 1337         frm = ieee80211_add_ds_params(frm, ic, ic->ic_bss);
 1338         if (ic->ic_opmode == IEEE80211_M_IBSS)
 1339                 frm = ieee80211_add_ibss_params(frm, ic->ic_bss);
 1340         if (ic->ic_curmode == IEEE80211_MODE_11G)
 1341                 frm = ieee80211_add_erp(frm, ic);
 1342         if (rs->rs_nrates > IEEE80211_RATE_SIZE)
 1343                 frm = ieee80211_add_xrates(frm, rs);
 1344         if ((ic->ic_flags & IEEE80211_F_RSNON) &&
 1345             (ic->ic_bss->ni_rsnprotos & IEEE80211_PROTO_RSN))
 1346                 frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
 1347         if (ic->ic_flags & IEEE80211_F_QOS)
 1348                 frm = ieee80211_add_edca_params(frm, ic);
 1349         if ((ic->ic_flags & IEEE80211_F_RSNON) &&
 1350             (ic->ic_bss->ni_rsnprotos & IEEE80211_PROTO_WPA))
 1351                 frm = ieee80211_add_wpa(frm, ic, ic->ic_bss);
 1352         if (ic->ic_flags & IEEE80211_F_HTON) {
 1353                 frm = ieee80211_add_htcaps(frm, ic);
 1354                 frm = ieee80211_add_htop(frm, ic);
 1355                 frm = ieee80211_add_wme_param(frm, ic);
 1356         }
 1357 
 1358         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1359 
 1360         return m;
 1361 }
 1362 #endif  /* IEEE80211_STA_ONLY */
 1363 
 1364 /*-
 1365  * Authentication frame format:
 1366  * [2] Authentication algorithm number
 1367  * [2] Authentication transaction sequence number
 1368  * [2] Status code
 1369  */
 1370 struct mbuf *
 1371 ieee80211_get_auth(struct ieee80211com *ic, struct ieee80211_node *ni,
 1372     u_int16_t status, u_int16_t seq)
 1373 {
 1374         struct mbuf *m;
 1375         u_int8_t *frm;
 1376 
 1377         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1378         if (m == NULL)
 1379                 return NULL;
 1380         m_align(m, 2 * 3);
 1381         m->m_pkthdr.len = m->m_len = 2 * 3;
 1382 
 1383         frm = mtod(m, u_int8_t *);
 1384         LE_WRITE_2(frm, IEEE80211_AUTH_ALG_OPEN); frm += 2;
 1385         LE_WRITE_2(frm, seq); frm += 2;
 1386         LE_WRITE_2(frm, status);
 1387 
 1388         return m;
 1389 }
 1390 
 1391 /*-
 1392  * Deauthentication frame format:
 1393  * [2] Reason code
 1394  */
 1395 struct mbuf *
 1396 ieee80211_get_deauth(struct ieee80211com *ic, struct ieee80211_node *ni,
 1397     u_int16_t reason)
 1398 {
 1399         struct mbuf *m;
 1400 
 1401         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1402         if (m == NULL)
 1403                 return NULL;
 1404         m_align(m, 2);
 1405         m->m_pkthdr.len = m->m_len = 2;
 1406 
 1407         *mtod(m, u_int16_t *) = htole16(reason);
 1408 
 1409         return m;
 1410 }
 1411 
 1412 /*-
 1413  * (Re)Association request frame format:
 1414  * [2]   Capability information
 1415  * [2]   Listen interval
 1416  * [6*]  Current AP address (Reassociation only)
 1417  * [tlv] SSID
 1418  * [tlv] Supported rates
 1419  * [tlv] Extended Supported Rates (802.11g)
 1420  * [tlv] RSN (802.11i)
 1421  * [tlv] QoS Capability (802.11e)
 1422  * [tlv] HT Capabilities (802.11n)
 1423  */
 1424 struct mbuf *
 1425 ieee80211_get_assoc_req(struct ieee80211com *ic, struct ieee80211_node *ni,
 1426     int type)
 1427 {
 1428         const struct ieee80211_rateset *rs = &ni->ni_rates;
 1429         struct mbuf *m;
 1430         u_int8_t *frm;
 1431         u_int16_t capinfo;
 1432 
 1433         m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA,
 1434             2 + 2 +
 1435             ((type == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) ?
 1436                 IEEE80211_ADDR_LEN : 0) +
 1437             2 + ni->ni_esslen +
 1438             2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
 1439             ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
 1440                 2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
 1441             (((ic->ic_flags & IEEE80211_F_RSNON) &&
 1442               (ni->ni_rsnprotos & IEEE80211_PROTO_RSN)) ?
 1443                 2 + IEEE80211_RSNIE_MAXLEN : 0) +
 1444             ((ni->ni_flags & IEEE80211_NODE_QOS) ? 2 + 1 : 0) +
 1445             (((ic->ic_flags & IEEE80211_F_RSNON) &&
 1446               (ni->ni_rsnprotos & IEEE80211_PROTO_WPA)) ?
 1447                 2 + IEEE80211_WPAIE_MAXLEN : 0) +
 1448             ((ic->ic_flags & IEEE80211_F_HTON) ? 28 + 9 : 0) +
 1449             ((ic->ic_flags & IEEE80211_F_VHTON) ? 14 : 0));
 1450         if (m == NULL)
 1451                 return NULL;
 1452 
 1453         frm = mtod(m, u_int8_t *);
 1454         capinfo = IEEE80211_CAPINFO_ESS;
 1455         if (ic->ic_flags & IEEE80211_F_WEPON)
 1456                 capinfo |= IEEE80211_CAPINFO_PRIVACY;
 1457         if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
 1458             IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
 1459                 capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
 1460         if (ic->ic_caps & IEEE80211_C_SHSLOT)
 1461                 capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
 1462         LE_WRITE_2(frm, capinfo); frm += 2;
 1463         LE_WRITE_2(frm, ic->ic_lintval); frm += 2;
 1464         if (type == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
 1465                 IEEE80211_ADDR_COPY(frm, ic->ic_bss->ni_bssid);
 1466                 frm += IEEE80211_ADDR_LEN;
 1467         }
 1468         frm = ieee80211_add_ssid(frm, ni->ni_essid, ni->ni_esslen);
 1469         frm = ieee80211_add_rates(frm, rs);
 1470         if (rs->rs_nrates > IEEE80211_RATE_SIZE)
 1471                 frm = ieee80211_add_xrates(frm, rs);
 1472         if ((ic->ic_flags & IEEE80211_F_RSNON) &&
 1473             (ni->ni_rsnprotos & IEEE80211_PROTO_RSN))
 1474                 frm = ieee80211_add_rsn(frm, ic, ni);
 1475         if (ni->ni_flags & IEEE80211_NODE_QOS)
 1476                 frm = ieee80211_add_qos_capability(frm, ic);
 1477         if ((ic->ic_flags & IEEE80211_F_RSNON) &&
 1478             (ni->ni_rsnprotos & IEEE80211_PROTO_WPA))
 1479                 frm = ieee80211_add_wpa(frm, ic, ni);
 1480         if (ic->ic_flags & IEEE80211_F_HTON) {
 1481                 frm = ieee80211_add_htcaps(frm, ic);
 1482                 frm = ieee80211_add_wme_info(frm, ic);
 1483         }
 1484         if (ic->ic_flags & IEEE80211_F_VHTON)
 1485                 frm = ieee80211_add_vhtcaps(frm, ic);
 1486 
 1487         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1488 
 1489         return m;
 1490 }
 1491 
 1492 #ifndef IEEE80211_STA_ONLY
 1493 /*-
 1494  * (Re)Association response frame format:
 1495  * [2]   Capability information
 1496  * [2]   Status code
 1497  * [2]   Association ID (AID)
 1498  * [tlv] Supported rates
 1499  * [tlv] Extended Supported Rates (802.11g)
 1500  * [tlv] EDCA Parameter Set (802.11e)
 1501  * [tlv] Timeout Interval (802.11w)
 1502  * [tlv] HT Capabilities (802.11n)
 1503  * [tlv] HT Operation (802.11n)
 1504  */
 1505 struct mbuf *
 1506 ieee80211_get_assoc_resp(struct ieee80211com *ic, struct ieee80211_node *ni,
 1507     u_int16_t status)
 1508 {
 1509         const struct ieee80211_rateset *rs = &ni->ni_rates;
 1510         struct mbuf *m;
 1511         u_int8_t *frm;
 1512 
 1513         m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA,
 1514             2 + 2 + 2 +
 1515             2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
 1516             ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
 1517                 2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
 1518             ((ni->ni_flags & IEEE80211_NODE_QOS) ? 2 + 18 : 0) +
 1519             ((status == IEEE80211_STATUS_TRY_AGAIN_LATER) ? 2 + 7 : 0) +
 1520             ((ic->ic_flags & IEEE80211_F_HTON) ? 28 + 24 + 26 : 0));
 1521         if (m == NULL)
 1522                 return NULL;
 1523 
 1524         frm = mtod(m, u_int8_t *);
 1525         frm = ieee80211_add_capinfo(frm, ic, ni);
 1526         LE_WRITE_2(frm, status); frm += 2;
 1527         if (status == IEEE80211_STATUS_SUCCESS)
 1528                 LE_WRITE_2(frm, ni->ni_associd);
 1529         else
 1530                 LE_WRITE_2(frm, 0);
 1531         frm += 2;
 1532         frm = ieee80211_add_rates(frm, rs);
 1533         if (rs->rs_nrates > IEEE80211_RATE_SIZE)
 1534                 frm = ieee80211_add_xrates(frm, rs);
 1535         if (ni->ni_flags & IEEE80211_NODE_QOS)
 1536                 frm = ieee80211_add_edca_params(frm, ic);
 1537         if ((ni->ni_flags & IEEE80211_NODE_MFP) &&
 1538             status == IEEE80211_STATUS_TRY_AGAIN_LATER) {
 1539                 /* Association Comeback Time */
 1540                 frm = ieee80211_add_tie(frm, 3, 1000 /* XXX */);
 1541         }
 1542         if (ic->ic_flags & IEEE80211_F_HTON) {
 1543                 frm = ieee80211_add_htcaps(frm, ic);
 1544                 frm = ieee80211_add_htop(frm, ic);
 1545                 frm = ieee80211_add_wme_param(frm, ic);
 1546         }
 1547 
 1548         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1549 
 1550         return m;
 1551 }
 1552 #endif  /* IEEE80211_STA_ONLY */
 1553 
 1554 /*-
 1555  * Disassociation frame format:
 1556  * [2] Reason code
 1557  */
 1558 struct mbuf *
 1559 ieee80211_get_disassoc(struct ieee80211com *ic, struct ieee80211_node *ni,
 1560     u_int16_t reason)
 1561 {
 1562         struct mbuf *m;
 1563 
 1564         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1565         if (m == NULL)
 1566                 return NULL;
 1567         m_align(m, 2);
 1568         m->m_pkthdr.len = m->m_len = 2;
 1569 
 1570         *mtod(m, u_int16_t *) = htole16(reason);
 1571 
 1572         return m;
 1573 }
 1574 
 1575 /*-
 1576  * ADDBA Request frame format:
 1577  * [1] Category
 1578  * [1] Action
 1579  * [1] Dialog Token
 1580  * [2] Block Ack Parameter Set
 1581  * [2] Block Ack Timeout Value
 1582  * [2] Block Ack Starting Sequence Control
 1583  */
 1584 struct mbuf *
 1585 ieee80211_get_addba_req(struct ieee80211com *ic, struct ieee80211_node *ni,
 1586     u_int8_t tid)
 1587 {
 1588         struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
 1589         struct mbuf *m;
 1590         u_int8_t *frm;
 1591 
 1592         m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA, 9);
 1593         if (m == NULL)
 1594                 return m;
 1595 
 1596         frm = mtod(m, u_int8_t *);
 1597         *frm++ = IEEE80211_CATEG_BA;
 1598         *frm++ = IEEE80211_ACTION_ADDBA_REQ;
 1599         *frm++ = ba->ba_token;
 1600         LE_WRITE_2(frm, ba->ba_params); frm += 2;
 1601         LE_WRITE_2(frm, ba->ba_timeout_val / IEEE80211_DUR_TU); frm += 2;
 1602         LE_WRITE_2(frm, ba->ba_winstart << IEEE80211_SEQ_SEQ_SHIFT); frm += 2;
 1603 
 1604         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1605 
 1606         return m;
 1607 }
 1608 
 1609 /* Move Tx BA window forward to the specified SSN. */
 1610 void
 1611 ieee80211_output_ba_move_window(struct ieee80211com *ic,
 1612     struct ieee80211_node *ni, uint8_t tid, uint16_t ssn)
 1613 {
 1614         struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
 1615         uint16_t s = ba->ba_winstart;
 1616 
 1617         while (SEQ_LT(s, ssn) && ba->ba_bitmap) {
 1618                 s = (s + 1) % 0xfff;
 1619                 ba->ba_bitmap >>= 1;
 1620         }
 1621 
 1622         ba->ba_winstart = (ssn & 0xfff);
 1623         ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff;
 1624 }
 1625 
 1626 /*
 1627  * Move Tx BA window forward up to the first hole in the bitmap
 1628  * or up to the specified SSN, whichever comes first.
 1629  * After calling this function, frames before the start of the
 1630  * potentially changed BA window should be discarded.
 1631  */
 1632 void
 1633 ieee80211_output_ba_move_window_to_first_unacked(struct ieee80211com *ic,
 1634     struct ieee80211_node *ni, uint8_t tid, uint16_t ssn)
 1635 {
 1636         struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
 1637         uint16_t s = ba->ba_winstart;
 1638         uint64_t bitmap = ba->ba_bitmap;
 1639         int can_move_window = 0;
 1640 
 1641         while (bitmap && SEQ_LT(s, ssn)) {
 1642                 if ((bitmap & 1) == 0)
 1643                         break;
 1644                 s = (s + 1) % 0xfff;
 1645                 bitmap >>= 1;
 1646                 can_move_window = 1;
 1647         }
 1648 
 1649         if (can_move_window)
 1650                 ieee80211_output_ba_move_window(ic, ni, tid, s);
 1651 }
 1652 
 1653 /* Record an ACK for a frame with a given SSN within the Tx BA window. */
 1654 void
 1655 ieee80211_output_ba_record_ack(struct ieee80211com *ic,
 1656     struct ieee80211_node *ni, uint8_t tid, uint16_t ssn)
 1657 {
 1658         struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid];
 1659         int i = 0;
 1660         uint16_t s = ba->ba_winstart;
 1661 
 1662         KASSERT(!SEQ_LT(ssn, ba->ba_winstart));
 1663         KASSERT(!SEQ_LT(ba->ba_winend, ssn));
 1664 
 1665         while (SEQ_LT(s, ssn)) {
 1666                 s = (s + 1) % 0xfff;
 1667                 i++;
 1668         }
 1669         if (i < ba->ba_winsize)
 1670                 ba->ba_bitmap |= (1 << i);
 1671 }
 1672 
 1673 /*-
 1674  * ADDBA Response frame format:
 1675  * [1] Category
 1676  * [1] Action
 1677  * [1] Dialog Token
 1678  * [2] Status Code
 1679  * [2] Block Ack Parameter Set
 1680  * [2] Block Ack Timeout Value
 1681  */
 1682 struct mbuf *
 1683 ieee80211_get_addba_resp(struct ieee80211com *ic, struct ieee80211_node *ni,
 1684     u_int8_t tid, u_int8_t token, u_int16_t status)
 1685 {
 1686         struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
 1687         struct mbuf *m;
 1688         u_int8_t *frm;
 1689         u_int16_t params;
 1690 
 1691         m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA, 9);
 1692         if (m == NULL)
 1693                 return m;
 1694 
 1695         frm = mtod(m, u_int8_t *);
 1696         *frm++ = IEEE80211_CATEG_BA;
 1697         *frm++ = IEEE80211_ACTION_ADDBA_RESP;
 1698         *frm++ = token;
 1699         LE_WRITE_2(frm, status); frm += 2;
 1700         if (status == 0)
 1701                 params = ba->ba_params;
 1702         else
 1703                 params = tid << IEEE80211_ADDBA_TID_SHIFT;
 1704         LE_WRITE_2(frm, params); frm += 2;
 1705         if (status == 0)
 1706                 LE_WRITE_2(frm, ba->ba_timeout_val / IEEE80211_DUR_TU);
 1707         else
 1708                 LE_WRITE_2(frm, 0);
 1709         frm += 2;
 1710 
 1711         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1712 
 1713         return m;
 1714 }
 1715 
 1716 /*-
 1717  * DELBA frame format:
 1718  * [1] Category
 1719  * [1] Action
 1720  * [2] DELBA Parameter Set
 1721  * [2] Reason Code
 1722  */
 1723 struct mbuf *
 1724 ieee80211_get_delba(struct ieee80211com *ic, struct ieee80211_node *ni,
 1725     u_int8_t tid, u_int8_t dir, u_int16_t reason)
 1726 {
 1727         struct mbuf *m;
 1728         u_int8_t *frm;
 1729         u_int16_t params;
 1730 
 1731         m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA, 6);
 1732         if (m == NULL)
 1733                 return m;
 1734 
 1735         frm = mtod(m, u_int8_t *);
 1736         *frm++ = IEEE80211_CATEG_BA;
 1737         *frm++ = IEEE80211_ACTION_DELBA;
 1738         params = tid << 12;
 1739         if (dir)
 1740                 params |= IEEE80211_DELBA_INITIATOR;
 1741         LE_WRITE_2(frm, params); frm += 2;
 1742         LE_WRITE_2(frm, reason); frm += 2;
 1743 
 1744         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1745 
 1746         return m;
 1747 }
 1748 
 1749 /*-
 1750  * SA Query Request/Response frame format:
 1751  * [1]  Category
 1752  * [1]  Action
 1753  * [16] Transaction Identifier
 1754  */
 1755 struct mbuf *
 1756 ieee80211_get_sa_query(struct ieee80211com *ic, struct ieee80211_node *ni,
 1757     u_int8_t action)
 1758 {
 1759         struct mbuf *m;
 1760         u_int8_t *frm;
 1761 
 1762         m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA, 4);
 1763         if (m == NULL)
 1764                 return NULL;
 1765 
 1766         frm = mtod(m, u_int8_t *);
 1767         *frm++ = IEEE80211_CATEG_SA_QUERY;
 1768         *frm++ = action;        /* ACTION_SA_QUERY_REQ/RESP */
 1769         LE_WRITE_2(frm, ni->ni_sa_query_trid); frm += 2;
 1770 
 1771         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 1772 
 1773         return m;
 1774 }
 1775 
 1776 struct mbuf *
 1777 ieee80211_get_action(struct ieee80211com *ic, struct ieee80211_node *ni,
 1778     u_int8_t categ, u_int8_t action, int arg)
 1779 {
 1780         struct mbuf *m = NULL;
 1781 
 1782         switch (categ) {
 1783         case IEEE80211_CATEG_BA:
 1784                 switch (action) {
 1785                 case IEEE80211_ACTION_ADDBA_REQ:
 1786                         m = ieee80211_get_addba_req(ic, ni, arg & 0xffff);
 1787                         break;
 1788                 case IEEE80211_ACTION_ADDBA_RESP:
 1789                         m = ieee80211_get_addba_resp(ic, ni, arg & 0xff,
 1790                             arg >> 8, arg >> 16);
 1791                         break;
 1792                 case IEEE80211_ACTION_DELBA:
 1793                         m = ieee80211_get_delba(ic, ni, arg & 0xff, arg >> 8,
 1794                             arg >> 16);
 1795                         break;
 1796                 }
 1797                 break;
 1798         case IEEE80211_CATEG_SA_QUERY:
 1799                 switch (action) {
 1800 #ifndef IEEE80211_STA_ONLY
 1801                 case IEEE80211_ACTION_SA_QUERY_REQ:
 1802 #endif
 1803                 case IEEE80211_ACTION_SA_QUERY_RESP:
 1804                         m = ieee80211_get_sa_query(ic, ni, action);
 1805                         break;
 1806                 }
 1807                 break;
 1808         }
 1809         return m;
 1810 }
 1811 
 1812 /*
 1813  * Send a management frame.  The node is for the destination (or ic_bss
 1814  * when in station mode).  Nodes other than ic_bss have their reference
 1815  * count bumped to reflect our use for an indeterminant time.
 1816  */
 1817 int
 1818 ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
 1819     int type, int arg1, int arg2)
 1820 {
 1821 #define senderr(_x, _v) do { ic->ic_stats._v++; ret = _x; goto bad; } while (0)
 1822         struct ifnet *ifp = &ic->ic_if;
 1823         struct mbuf *m;
 1824         int ret, timer;
 1825 
 1826         if (ni == NULL)
 1827                 panic("null node");
 1828 
 1829         /*
 1830          * Hold a reference on the node so it doesn't go away until after
 1831          * the xmit is complete all the way in the driver.  On error we
 1832          * will remove our reference.
 1833          */
 1834         ieee80211_ref_node(ni);
 1835         timer = 0;
 1836         switch (type) {
 1837         case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
 1838                 if ((m = ieee80211_get_probe_req(ic, ni)) == NULL)
 1839                         senderr(ENOMEM, is_tx_nombuf);
 1840 
 1841                 timer = IEEE80211_TRANS_WAIT;
 1842                 break;
 1843 #ifndef IEEE80211_STA_ONLY
 1844         case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
 1845                 if ((m = ieee80211_get_probe_resp(ic)) == NULL)
 1846                         senderr(ENOMEM, is_tx_nombuf);
 1847                 break;
 1848 #endif
 1849         case IEEE80211_FC0_SUBTYPE_AUTH:
 1850                 m = ieee80211_get_auth(ic, ni, arg1 >> 16, arg1 & 0xffff);
 1851                 if (m == NULL)
 1852                         senderr(ENOMEM, is_tx_nombuf);
 1853 
 1854                 if (ic->ic_opmode == IEEE80211_M_STA)
 1855                         timer = IEEE80211_TRANS_WAIT;
 1856                 break;
 1857 
 1858         case IEEE80211_FC0_SUBTYPE_DEAUTH:
 1859                 if ((m = ieee80211_get_deauth(ic, ni, arg1)) == NULL)
 1860                         senderr(ENOMEM, is_tx_nombuf);
 1861 #ifndef IEEE80211_STA_ONLY
 1862                 if ((ifp->if_flags & IFF_DEBUG) &&
 1863                     (ic->ic_opmode == IEEE80211_M_HOSTAP ||
 1864                     ic->ic_opmode == IEEE80211_M_IBSS))
 1865                         printf("%s: station %s deauthenticate (reason %d)\n",
 1866                             ifp->if_xname, ether_sprintf(ni->ni_macaddr),
 1867                             arg1);
 1868 #endif
 1869                 break;
 1870 
 1871         case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
 1872         case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
 1873                 if ((m = ieee80211_get_assoc_req(ic, ni, type)) == NULL)
 1874                         senderr(ENOMEM, is_tx_nombuf);
 1875 
 1876                 timer = IEEE80211_TRANS_WAIT;
 1877                 break;
 1878 #ifndef IEEE80211_STA_ONLY
 1879         case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
 1880         case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
 1881                 if ((m = ieee80211_get_assoc_resp(ic, ni, arg1)) == NULL)
 1882                         senderr(ENOMEM, is_tx_nombuf);
 1883                 break;
 1884 #endif
 1885         case IEEE80211_FC0_SUBTYPE_DISASSOC:
 1886                 if ((m = ieee80211_get_disassoc(ic, ni, arg1)) == NULL)
 1887                         senderr(ENOMEM, is_tx_nombuf);
 1888 #ifndef IEEE80211_STA_ONLY
 1889                 if ((ifp->if_flags & IFF_DEBUG) &&
 1890                     (ic->ic_opmode == IEEE80211_M_HOSTAP ||
 1891                     ic->ic_opmode == IEEE80211_M_IBSS))
 1892                         printf("%s: station %s disassociate (reason %d)\n",
 1893                             ifp->if_xname, ether_sprintf(ni->ni_macaddr),
 1894                             arg1);
 1895 #endif
 1896                 break;
 1897 
 1898         case IEEE80211_FC0_SUBTYPE_ACTION:
 1899                 m = ieee80211_get_action(ic, ni, arg1 >> 16, arg1 & 0xffff,
 1900                     arg2);
 1901                 if (m == NULL)
 1902                         senderr(ENOMEM, is_tx_nombuf);
 1903                 break;
 1904 
 1905         default:
 1906                 DPRINTF(("invalid mgmt frame type %u\n", type));
 1907                 senderr(EINVAL, is_tx_unknownmgt);
 1908                 /* NOTREACHED */
 1909         }
 1910 
 1911         ret = ieee80211_mgmt_output(ifp, ni, m, type);
 1912         if (ret == 0) {
 1913                 if (timer)
 1914                         ic->ic_mgt_timer = timer;
 1915         } else {
 1916 bad:
 1917                 ieee80211_release_node(ic, ni);
 1918         }
 1919         return ret;
 1920 #undef senderr
 1921 }
 1922 
 1923 /*
 1924  * Build a RTS (Request To Send) control frame (see 7.2.1.1).
 1925  */
 1926 struct mbuf *
 1927 ieee80211_get_rts(struct ieee80211com *ic, const struct ieee80211_frame *wh,
 1928     u_int16_t dur)
 1929 {
 1930         struct ieee80211_frame_rts *rts;
 1931         struct mbuf *m;
 1932 
 1933         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1934         if (m == NULL)
 1935                 return NULL;
 1936 
 1937         m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_rts);
 1938 
 1939         rts = mtod(m, struct ieee80211_frame_rts *);
 1940         rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL |
 1941             IEEE80211_FC0_SUBTYPE_RTS;
 1942         rts->i_fc[1] = IEEE80211_FC1_DIR_NODS;
 1943         *(u_int16_t *)rts->i_dur = htole16(dur);
 1944         IEEE80211_ADDR_COPY(rts->i_ra, wh->i_addr1);
 1945         IEEE80211_ADDR_COPY(rts->i_ta, wh->i_addr2);
 1946 
 1947         return m;
 1948 }
 1949 
 1950 /*
 1951  * Build a CTS-to-self (Clear To Send) control frame (see 7.2.1.2).
 1952  */
 1953 struct mbuf *
 1954 ieee80211_get_cts_to_self(struct ieee80211com *ic, u_int16_t dur)
 1955 {
 1956         struct ieee80211_frame_cts *cts;
 1957         struct mbuf *m;
 1958 
 1959         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1960         if (m == NULL)
 1961                 return NULL;
 1962 
 1963         m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_cts);
 1964 
 1965         cts = mtod(m, struct ieee80211_frame_cts *);
 1966         cts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL |
 1967             IEEE80211_FC0_SUBTYPE_CTS;
 1968         cts->i_fc[1] = IEEE80211_FC1_DIR_NODS;
 1969         *(u_int16_t *)cts->i_dur = htole16(dur);
 1970         IEEE80211_ADDR_COPY(cts->i_ra, ic->ic_myaddr);
 1971 
 1972         return m;
 1973 }
 1974 
 1975 /*
 1976  * Build a compressed Block Ack Request control frame.
 1977  */
 1978 struct mbuf *
 1979 ieee80211_get_compressed_bar(struct ieee80211com *ic,
 1980     struct ieee80211_node *ni, int tid, uint16_t ssn)
 1981 {
 1982         struct ieee80211_frame_min *wh;
 1983         uint8_t *frm;
 1984         uint16_t ctl;
 1985         struct mbuf *m;
 1986 
 1987         MGETHDR(m, M_DONTWAIT, MT_DATA);
 1988         if (m == NULL)
 1989                 return NULL;
 1990 
 1991         m->m_pkthdr.len = m->m_len = sizeof(struct ieee80211_frame_min) +
 1992             sizeof(ctl) + sizeof(ssn);
 1993 
 1994         wh = mtod(m, struct ieee80211_frame_min *);
 1995         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL |
 1996             IEEE80211_FC0_SUBTYPE_BAR;
 1997         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
 1998         *(u_int16_t *)wh->i_dur = 0;
 1999         IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
 2000         IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
 2001         frm = (uint8_t *)&wh[1];
 2002 
 2003         ctl = IEEE80211_BA_COMPRESSED | (tid << IEEE80211_BA_TID_INFO_SHIFT);
 2004         LE_WRITE_2(frm, ctl);
 2005         frm += 2;
 2006 
 2007         LE_WRITE_2(frm, ssn << IEEE80211_SEQ_SEQ_SHIFT);
 2008         frm += 2;
 2009 
 2010         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 2011         m->m_pkthdr.ph_cookie = ni;
 2012 
 2013         return m;
 2014 }
 2015 
 2016 #ifndef IEEE80211_STA_ONLY
 2017 /*-
 2018  * Beacon frame format:
 2019  * [8]   Timestamp
 2020  * [2]   Beacon interval
 2021  * [2]   Capability
 2022  * [tlv] Service Set Identifier (SSID)
 2023  * [tlv] Supported rates
 2024  * [tlv] DS Parameter Set (802.11g)
 2025  * [tlv] IBSS Parameter Set
 2026  * [tlv] Traffic Indication Map (TIM)
 2027  * [tlv] ERP Information (802.11g)
 2028  * [tlv] Extended Supported Rates (802.11g)
 2029  * [tlv] RSN (802.11i)
 2030  * [tlv] EDCA Parameter Set (802.11e)
 2031  * [tlv] HT Capabilities (802.11n)
 2032  * [tlv] HT Operation (802.11n)
 2033  */
 2034 struct mbuf *
 2035 ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni)
 2036 {
 2037         const struct ieee80211_rateset *rs = &ni->ni_rates;
 2038         struct ieee80211_frame *wh;
 2039         struct mbuf *m;
 2040         u_int8_t *frm;
 2041 
 2042         m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA,
 2043             8 + 2 + 2 +
 2044             2 + ((ic->ic_userflags & IEEE80211_F_HIDENWID) ?
 2045             0 : ni->ni_esslen) +
 2046             2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
 2047             2 + 1 +
 2048             2 + ((ic->ic_opmode == IEEE80211_M_IBSS) ? 2 : 254) +
 2049             ((ic->ic_curmode == IEEE80211_MODE_11G) ? 2 + 1 : 0) +
 2050             ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
 2051                 2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
 2052             (((ic->ic_flags & IEEE80211_F_RSNON) &&
 2053               (ni->ni_rsnprotos & IEEE80211_PROTO_RSN)) ?
 2054                 2 + IEEE80211_RSNIE_MAXLEN : 0) +
 2055             ((ic->ic_flags & IEEE80211_F_QOS) ? 2 + 18 : 0) +
 2056             (((ic->ic_flags & IEEE80211_F_RSNON) &&
 2057               (ni->ni_rsnprotos & IEEE80211_PROTO_WPA)) ?
 2058                 2 + IEEE80211_WPAIE_MAXLEN : 0) +
 2059             ((ic->ic_flags & IEEE80211_F_HTON) ? 28 + 24 + 26 : 0));
 2060         if (m == NULL)
 2061                 return NULL;
 2062 
 2063         M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
 2064         if (m == NULL)
 2065                 return NULL;
 2066         wh = mtod(m, struct ieee80211_frame *);
 2067         wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
 2068             IEEE80211_FC0_SUBTYPE_BEACON;
 2069         wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
 2070         *(u_int16_t *)wh->i_dur = 0;
 2071         IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
 2072         IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
 2073         IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
 2074         *(u_int16_t *)wh->i_seq = 0;
 2075 
 2076         frm = (u_int8_t *)&wh[1];
 2077         memset(frm, 0, 8); frm += 8;    /* timestamp is set by hardware */
 2078         LE_WRITE_2(frm, ni->ni_intval); frm += 2;
 2079         frm = ieee80211_add_capinfo(frm, ic, ni);
 2080         if (ic->ic_userflags & IEEE80211_F_HIDENWID)
 2081                 frm = ieee80211_add_ssid(frm, NULL, 0);
 2082         else
 2083                 frm = ieee80211_add_ssid(frm, ni->ni_essid, ni->ni_esslen);
 2084         frm = ieee80211_add_rates(frm, rs);
 2085         frm = ieee80211_add_ds_params(frm, ic, ni);
 2086         if (ic->ic_opmode == IEEE80211_M_IBSS)
 2087                 frm = ieee80211_add_ibss_params(frm, ni);
 2088         else
 2089                 frm = ieee80211_add_tim(frm, ic);
 2090         if (ic->ic_curmode == IEEE80211_MODE_11G)
 2091                 frm = ieee80211_add_erp(frm, ic);
 2092         if (rs->rs_nrates > IEEE80211_RATE_SIZE)
 2093                 frm = ieee80211_add_xrates(frm, rs);
 2094         if ((ic->ic_flags & IEEE80211_F_RSNON) &&
 2095             (ni->ni_rsnprotos & IEEE80211_PROTO_RSN))
 2096                 frm = ieee80211_add_rsn(frm, ic, ni);
 2097         if (ic->ic_flags & IEEE80211_F_QOS)
 2098                 frm = ieee80211_add_edca_params(frm, ic);
 2099         if ((ic->ic_flags & IEEE80211_F_RSNON) &&
 2100             (ni->ni_rsnprotos & IEEE80211_PROTO_WPA))
 2101                 frm = ieee80211_add_wpa(frm, ic, ni);
 2102         if (ic->ic_flags & IEEE80211_F_HTON) {
 2103                 frm = ieee80211_add_htcaps(frm, ic);
 2104                 frm = ieee80211_add_htop(frm, ic);
 2105                 frm = ieee80211_add_wme_param(frm, ic);
 2106         }
 2107 
 2108         m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
 2109         m->m_pkthdr.ph_cookie = ni;
 2110 
 2111         return m;
 2112 }
 2113 
 2114 /*
 2115  * Check if an outgoing MSDU or management frame should be buffered into
 2116  * the AP for power management.  Return 1 if the frame was buffered into
 2117  * the AP, or 0 if the frame shall be transmitted immediately.
 2118  */
 2119 int
 2120 ieee80211_pwrsave(struct ieee80211com *ic, struct mbuf *m,
 2121     struct ieee80211_node *ni)
 2122 {
 2123         const struct ieee80211_frame *wh;
 2124         int pssta = 0;
 2125 
 2126         KASSERT(ic->ic_opmode == IEEE80211_M_HOSTAP);
 2127         if (!(ic->ic_caps & IEEE80211_C_APPMGT))
 2128                 return 0;
 2129 
 2130         wh = mtod(m, struct ieee80211_frame *);
 2131         if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
 2132                 /*
 2133                  * Buffer group addressed MSDUs with the Order bit clear
 2134                  * if any associated STAs are in PS mode.
 2135                  */
 2136                 ieee80211_iterate_nodes(ic, ieee80211_count_pssta, &pssta);
 2137                 if ((wh->i_fc[1] & IEEE80211_FC1_ORDER) || pssta == 0)
 2138                         return 0;
 2139                 ic->ic_tim_mcast_pending = 1;
 2140         } else {
 2141                 /*
 2142                  * Buffer MSDUs, A-MSDUs or management frames destined for
 2143                  * PS STAs.
 2144                  */
 2145                 if (ni->ni_pwrsave == IEEE80211_PS_AWAKE ||
 2146                     (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
 2147                     IEEE80211_FC0_TYPE_CTL)
 2148                         return 0;
 2149                 if (mq_empty(&ni->ni_savedq))
 2150                         (*ic->ic_set_tim)(ic, ni->ni_associd, 1);
 2151         }
 2152         /* NB: ni == ic->ic_bss for broadcast/multicast */
 2153         /*
 2154          * Similar to ieee80211_mgmt_output, store the node in a
 2155          * special pkthdr field.
 2156          */
 2157         m->m_pkthdr.ph_cookie = ni;
 2158         mq_enqueue(&ni->ni_savedq, m);
 2159         return 1;
 2160 }
 2161 #endif  /* IEEE80211_STA_ONLY */

Cache object: 021101c9fd162793c781baed06dc36f7


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