[BACK]Return to ieee80211_output.c CVS log [TXT][DIR] Up to [local] / sys / net80211

Annotation of sys/net80211/ieee80211_output.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: ieee80211_output.c,v 1.55 2007/08/05 21:41:11 claudio 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 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/proc.h>
                     45: #include <sys/sysctl.h>
                     46:
                     47: #include <net/if.h>
                     48: #include <net/if_dl.h>
                     49: #include <net/if_media.h>
                     50: #include <net/if_arp.h>
                     51: #include <net/if_llc.h>
                     52: #include <net/bpf.h>
                     53:
                     54: #ifdef INET
                     55: #include <netinet/in.h>
                     56: #include <netinet/if_ether.h>
                     57: #include <netinet/in_systm.h>
                     58: #include <netinet/ip.h>
                     59: #endif
                     60:
                     61: #if NVLAN > 0
                     62: #include <net/if_types.h>
                     63: #include <net/if_vlan_var.h>
                     64: #endif
                     65:
                     66: #include <net80211/ieee80211_var.h>
                     67:
                     68: #include <dev/rndvar.h>
                     69:
                     70: enum   ieee80211_edca_ac ieee80211_up_to_ac(struct ieee80211com *, int);
                     71: int    ieee80211_classify(struct ieee80211com *, struct mbuf *);
                     72: int    ieee80211_mgmt_output(struct ifnet *, struct ieee80211_node *,
                     73:            struct mbuf *, int);
                     74: u_int8_t *ieee80211_add_rsn_body(u_int8_t *, struct ieee80211com *,
                     75:            const struct ieee80211_node *, int);
                     76: struct mbuf *ieee80211_getmbuf(int, int, u_int);
                     77: struct mbuf *ieee80211_get_probe_req(struct ieee80211com *,
                     78:            struct ieee80211_node *);
                     79: struct mbuf *ieee80211_get_probe_resp(struct ieee80211com *,
                     80:            struct ieee80211_node *);
                     81: struct mbuf *ieee80211_get_auth(struct ieee80211com *,
                     82:            struct ieee80211_node *, u_int16_t, u_int16_t);
                     83: struct mbuf *ieee80211_get_deauth(struct ieee80211com *,
                     84:            struct ieee80211_node *, u_int16_t);
                     85: struct mbuf *ieee80211_get_assoc_req(struct ieee80211com *,
                     86:            struct ieee80211_node *, int);
                     87: struct mbuf *ieee80211_get_assoc_resp(struct ieee80211com *,
                     88:            struct ieee80211_node *, u_int16_t);
                     89: struct mbuf *ieee80211_get_disassoc(struct ieee80211com *,
                     90:            struct ieee80211_node *, u_int16_t);
                     91: int    ieee80211_send_eapol_key(struct ieee80211com *, struct mbuf *,
                     92:            struct ieee80211_node *);
                     93: u_int8_t *ieee80211_add_gtk_kde(u_int8_t *, const struct ieee80211_key *);
                     94: u_int8_t *ieee80211_add_pmkid_kde(u_int8_t *, const u_int8_t *);
                     95: struct mbuf *ieee80211_get_eapol_key(int, int, u_int);
                     96:
                     97:
                     98: /*
                     99:  * IEEE 802.11 output routine. Normally this will directly call the
                    100:  * Ethernet output routine because 802.11 encapsulation is called
                    101:  * later by the driver. This function can be used to send raw frames
                    102:  * if the mbuf has been tagged with a 802.11 data link type.
                    103:  */
                    104: int
                    105: ieee80211_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
                    106:     struct rtentry *rt)
                    107: {
                    108:        u_int dlt = 0;
                    109:        int s, error = 0;
                    110:        struct m_tag *mtag;
                    111:
                    112:        /* Interface has to be up and running */
                    113:        if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
                    114:            (IFF_UP | IFF_RUNNING)) {
                    115:                error = ENETDOWN;
                    116:                goto bad;
                    117:        }
                    118:
                    119:        /* Try to get the DLT from a mbuf tag */
                    120:        if ((mtag = m_tag_find(m, PACKET_TAG_DLT, NULL)) != NULL) {
                    121:                dlt = *(u_int *)(mtag + 1);
                    122:
                    123:                /* Fallback to ethernet for non-802.11 linktypes */
                    124:                if (!(dlt == DLT_IEEE802_11 || dlt == DLT_IEEE802_11_RADIO))
                    125:                        goto fallback;
                    126:
                    127:                /*
                    128:                 * Queue message on interface without adding any
                    129:                 * further headers, and start output if interface not
                    130:                 * yet active.
                    131:                 */
                    132:                s = splnet();
                    133:                IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
                    134:                if (error) {
                    135:                        /* mbuf is already freed */
                    136:                        splx(s);
                    137:                        printf("%s: failed to queue raw tx frame\n",
                    138:                            ifp->if_xname);
                    139:                        return (error);
                    140:                }
                    141:                ifp->if_obytes += m->m_pkthdr.len;
                    142:                if (m->m_flags & M_MCAST)
                    143:                        ifp->if_omcasts++;
                    144:                if ((ifp->if_flags & IFF_OACTIVE) == 0)
                    145:                        (*ifp->if_start)(ifp);
                    146:                splx(s);
                    147:
                    148:                return (error);
                    149:        }
                    150:
                    151:  fallback:
                    152:        return (ether_output(ifp, m, dst, rt));
                    153:
                    154:  bad:
                    155:        if (m)
                    156:                m_freem(m);
                    157:        return (error);
                    158: }
                    159:
                    160: /*
                    161:  * Send a management frame to the specified node.  The node pointer
                    162:  * must have a reference as the pointer will be passed to the driver
                    163:  * and potentially held for a long time.  If the frame is successfully
                    164:  * dispatched to the driver, then it is responsible for freeing the
                    165:  * reference (and potentially free'ing up any associated storage).
                    166:  */
                    167: int
                    168: ieee80211_mgmt_output(struct ifnet *ifp, struct ieee80211_node *ni,
                    169:     struct mbuf *m, int type)
                    170: {
                    171:        struct ieee80211com *ic = (void *)ifp;
                    172:        struct ieee80211_frame *wh;
                    173:
                    174:        if (ni == NULL)
                    175:                panic("null node");
                    176:        ni->ni_inact = 0;
                    177:
                    178:        /*
                    179:         * Yech, hack alert!  We want to pass the node down to the
                    180:         * driver's start routine.  We could stick this in an m_tag
                    181:         * and tack that on to the mbuf.  However that's rather
                    182:         * expensive to do for every frame so instead we stuff it in
                    183:         * the rcvif field since outbound frames do not (presently)
                    184:         * use this.
                    185:         */
                    186:        M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
                    187:        if (m == NULL)
                    188:                return ENOMEM;
                    189:        m->m_pkthdr.rcvif = (void *)ni;
                    190:
                    191:        wh = mtod(m, struct ieee80211_frame *);
                    192:        wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | type;
                    193:        wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
                    194:        *(u_int16_t *)&wh->i_dur[0] = 0;
                    195:        *(u_int16_t *)&wh->i_seq[0] =
                    196:            htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
                    197:        ni->ni_txseq++;
                    198:        IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
                    199:        IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
                    200:        IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
                    201:
                    202:        if (ifp->if_flags & IFF_DEBUG) {
                    203:                /* avoid to print too many frames */
                    204:                if (ic->ic_opmode == IEEE80211_M_IBSS ||
                    205: #ifdef IEEE80211_DEBUG
                    206:                    ieee80211_debug > 1 ||
                    207: #endif
                    208:                    (type & IEEE80211_FC0_SUBTYPE_MASK) !=
                    209:                    IEEE80211_FC0_SUBTYPE_PROBE_RESP)
                    210:                        printf("%s: sending %s to %s on channel %u mode %s\n",
                    211:                            ifp->if_xname,
                    212:                            ieee80211_mgt_subtype_name[
                    213:                            (type & IEEE80211_FC0_SUBTYPE_MASK)
                    214:                            >> IEEE80211_FC0_SUBTYPE_SHIFT],
                    215:                            ether_sprintf(ni->ni_macaddr),
                    216:                            ieee80211_chan2ieee(ic, ni->ni_chan),
                    217:                            ieee80211_phymode_name[
                    218:                            ieee80211_chan2mode(ic, ni->ni_chan)]);
                    219:        }
                    220:
                    221:        IF_ENQUEUE(&ic->ic_mgtq, m);
                    222:        ifp->if_timer = 1;
                    223:        (*ifp->if_start)(ifp);
                    224:        return 0;
                    225: }
                    226:
                    227: /*-
                    228:  * EDCA tables are computed using the following formulas:
                    229:  *
                    230:  * 1) EDCATable (non-AP QSTA)
                    231:  *
                    232:  * AC     CWmin           CWmax           AIFSN  TXOP limit(ms)
                    233:  * -------------------------------------------------------------
                    234:  * AC_BK  aCWmin          aCWmax          7      0
                    235:  * AC_BE  aCWmin          aCWmax          3      0
                    236:  * AC_VI  (aCWmin+1)/2-1   aCWmin         2      agn=3.008 b=6.016 others=0
                    237:  * AC_VO  (aCWmin+1)/4-1   (aCWmin+1)/2-1  2     agn=1.504 b=3.264 others=0
                    238:  *
                    239:  * 2) QAPEDCATable (QAP)
                    240:  *
                    241:  * AC     CWmin           CWmax           AIFSN  TXOP limit(ms)
                    242:  * -------------------------------------------------------------
                    243:  * AC_BK  aCWmin          aCWmax          7      0
                    244:  * AC_BE  aCWmin          4*(aCWmin+1)-1  3      0
                    245:  * AC_VI  (aCWmin+1)/2-1   aCWmin         1      agn=3.008 b=6.016 others=0
                    246:  * AC_VO  (aCWmin+1)/4-1   (aCWmin+1)/2-1  1     agn=1.504 b=3.264 others=0
                    247:  *
                    248:  * and the following aCWmin/aCWmax values:
                    249:  *
                    250:  * PHY         aCWmin  aCWmax
                    251:  * ---------------------------
                    252:  * 11A         15      1023
                    253:  * 11B         31      1023
                    254:  * 11G         15*     1023    (*) aCWmin(1)
                    255:  * FH          15      1023
                    256:  * Turbo A/G   7       1023    (Atheros proprietary mode)
                    257:  */
                    258: static const struct ieee80211_edca_ac_params
                    259:     ieee80211_edca_table[IEEE80211_MODE_MAX][EDCA_NUM_AC] = {
                    260:        [IEEE80211_MODE_FH] = {
                    261:                [EDCA_AC_BK] = { 4, 10, 7,   0 },
                    262:                [EDCA_AC_BE] = { 4, 10, 3,   0 },
                    263:                [EDCA_AC_VI] = { 3,  4, 2,   0 },
                    264:                [EDCA_AC_VO] = { 2,  3, 2,   0 }
                    265:        },
                    266:        [IEEE80211_MODE_11B] = {
                    267:                [EDCA_AC_BK] = { 5, 10, 7,   0 },
                    268:                [EDCA_AC_BE] = { 5, 10, 3,   0 },
                    269:                [EDCA_AC_VI] = { 4,  5, 2, 188 },
                    270:                [EDCA_AC_VO] = { 3,  4, 2, 102 }
                    271:        },
                    272:        [IEEE80211_MODE_11A] = {
                    273:                [EDCA_AC_BK] = { 4, 10, 7,   0 },
                    274:                [EDCA_AC_BE] = { 4, 10, 3,   0 },
                    275:                [EDCA_AC_VI] = { 3,  4, 2,  94 },
                    276:                [EDCA_AC_VO] = { 2,  3, 2,  47 }
                    277:        },
                    278:        [IEEE80211_MODE_11G] = {
                    279:                [EDCA_AC_BK] = { 4, 10, 7,   0 },
                    280:                [EDCA_AC_BE] = { 4, 10, 3,   0 },
                    281:                [EDCA_AC_VI] = { 3,  4, 2,  94 },
                    282:                [EDCA_AC_VO] = { 2,  3, 2,  47 }
                    283:        },
                    284:        [IEEE80211_MODE_TURBO] = {
                    285:                [EDCA_AC_BK] = { 3, 10, 7,   0 },
                    286:                [EDCA_AC_BE] = { 3, 10, 2,   0 },
                    287:                [EDCA_AC_VI] = { 2,  3, 2,  94 },
                    288:                [EDCA_AC_VO] = { 2,  2, 1,  47 }
                    289:        }
                    290: };
                    291:
                    292: static const struct ieee80211_edca_ac_params
                    293:     ieee80211_qap_edca_table[IEEE80211_MODE_MAX][EDCA_NUM_AC] = {
                    294:        [IEEE80211_MODE_FH] = {
                    295:                [EDCA_AC_BK] = { 4, 10, 7,   0 },
                    296:                [EDCA_AC_BE] = { 4,  6, 3,   0 },
                    297:                [EDCA_AC_VI] = { 3,  4, 1,   0 },
                    298:                [EDCA_AC_VO] = { 2,  3, 1,   0 }
                    299:        },
                    300:        [IEEE80211_MODE_11B] = {
                    301:                [EDCA_AC_BK] = { 5, 10, 7,   0 },
                    302:                [EDCA_AC_BE] = { 5,  7, 3,   0 },
                    303:                [EDCA_AC_VI] = { 4,  5, 1, 188 },
                    304:                [EDCA_AC_VO] = { 3,  4, 1, 102 }
                    305:        },
                    306:        [IEEE80211_MODE_11A] = {
                    307:                [EDCA_AC_BK] = { 4, 10, 7,   0 },
                    308:                [EDCA_AC_BE] = { 4,  6, 3,   0 },
                    309:                [EDCA_AC_VI] = { 3,  4, 1,  94 },
                    310:                [EDCA_AC_VO] = { 2,  3, 1,  47 }
                    311:        },
                    312:        [IEEE80211_MODE_11G] = {
                    313:                [EDCA_AC_BK] = { 4, 10, 7,   0 },
                    314:                [EDCA_AC_BE] = { 4,  6, 3,   0 },
                    315:                [EDCA_AC_VI] = { 3,  4, 1,  94 },
                    316:                [EDCA_AC_VO] = { 2,  3, 1,  47 }
                    317:        },
                    318:        [IEEE80211_MODE_TURBO] = {
                    319:                [EDCA_AC_BK] = { 3, 10, 7,   0 },
                    320:                [EDCA_AC_BE] = { 3,  5, 2,   0 },
                    321:                [EDCA_AC_VI] = { 2,  3, 1,  94 },
                    322:                [EDCA_AC_VO] = { 2,  2, 1,  47 }
                    323:        }
                    324: };
                    325:
                    326: /*
                    327:  * Return the EDCA Access Category to be used for transmitting a frame with
                    328:  * user-priority `up'.
                    329:  */
                    330: enum ieee80211_edca_ac
                    331: ieee80211_up_to_ac(struct ieee80211com *ic, int up)
                    332: {
                    333:        /* IEEE Std 802.11e-2005, table 20i */
                    334:        static const enum ieee80211_edca_ac up_to_ac[] = {
                    335:                EDCA_AC_BE,     /* BE */
                    336:                EDCA_AC_BK,     /* BK */
                    337:                EDCA_AC_BK,     /* -- */
                    338:                EDCA_AC_BE,     /* EE */
                    339:                EDCA_AC_VI,     /* CL */
                    340:                EDCA_AC_VI,     /* VI */
                    341:                EDCA_AC_VO,     /* VO */
                    342:                EDCA_AC_VO      /* NC */
                    343:        };
                    344:        enum ieee80211_edca_ac ac;
                    345:
                    346:        ac = (up <= 7) ? up_to_ac[up] : EDCA_AC_BE;
                    347:
                    348:        if (ic->ic_opmode == IEEE80211_M_HOSTAP)
                    349:                return ac;
                    350:
                    351:        /*
                    352:         * We do not support the admission control procedure defined in
                    353:         * IEEE Std 802.11e-2005 section 9.9.3.1.2.  The spec says that
                    354:         * non-AP QSTAs that don't support this procedure shall use EDCA
                    355:         * parameters of a lower priority AC that does not require
                    356:         * admission control.
                    357:         */
                    358:        while (ac != EDCA_AC_BK && ic->ic_edca_ac[ac].ac_acm) {
                    359:                switch (ac) {
                    360:                case EDCA_AC_BK:
                    361:                        /* can't get there */
                    362:                        break;
                    363:                case EDCA_AC_BE:
                    364:                        /* BE shouldn't require admission control */
                    365:                        ac = EDCA_AC_BK;
                    366:                        break;
                    367:                case EDCA_AC_VI:
                    368:                        ac = EDCA_AC_BE;
                    369:                        break;
                    370:                case EDCA_AC_VO:
                    371:                        ac = EDCA_AC_VI;
                    372:                        break;
                    373:                }
                    374:        }
                    375:        return ac;
                    376: }
                    377:
                    378: /*
                    379:  * Get mbuf's user-priority: if mbuf is not VLAN tagged, select user-priority
                    380:  * based on the DSCP (Differentiated Services Codepoint) field.
                    381:  */
                    382: int
                    383: ieee80211_classify(struct ieee80211com *ic, struct mbuf *m)
                    384: {
                    385: #ifdef INET
                    386:        const struct ether_header *eh;
                    387: #endif
                    388: #if NVLAN > 0
                    389:        if ((m->m_flags & M_PROTO1) == M_PROTO1 && m->m_pkthdr.rcvif != NULL) {
                    390:                const struct ifvlan *ifv = m->m_pkthdr.rcvif->if_softc;
                    391:
                    392:                /* use VLAN 802.1D user-priority */
                    393:                if (ifv->ifv_prio <= 7)
                    394:                        return ifv->ifv_prio;
                    395:        }
                    396: #endif
                    397: #ifdef INET
                    398:        eh = mtod(m, struct ether_header *);
                    399:        if (eh->ether_type == htons(ETHERTYPE_IP)) {
                    400:                const struct ip *ip = (const struct ip *)(eh + 1);
                    401:                /*
                    402:                 * Map Differentiated Services Codepoint field (see RFC2474).
                    403:                 * Preserves backward compatibility with IP Precedence field.
                    404:                 */
                    405:                switch (ip->ip_tos & 0xfc) {
                    406:                case IPTOS_PREC_PRIORITY:
                    407:                        return 2;
                    408:                case IPTOS_PREC_IMMEDIATE:
                    409:                        return 1;
                    410:                case IPTOS_PREC_FLASH:
                    411:                        return 3;
                    412:                case IPTOS_PREC_FLASHOVERRIDE:
                    413:                        return 4;
                    414:                case IPTOS_PREC_CRITIC_ECP:
                    415:                        return 5;
                    416:                case IPTOS_PREC_INTERNETCONTROL:
                    417:                        return 6;
                    418:                case IPTOS_PREC_NETCONTROL:
                    419:                        return 7;
                    420:                }
                    421:        }
                    422: #endif
                    423:        return 0;       /* default to Best-Effort */
                    424: }
                    425:
                    426: /*
                    427:  * Encapsulate an outbound data frame.  The mbuf chain is updated and
                    428:  * a reference to the destination node is returned.  If an error is
                    429:  * encountered NULL is returned and the node reference will also be NULL.
                    430:  *
                    431:  * NB: The caller is responsible for free'ing a returned node reference.
                    432:  *     The convention is ic_bss is not reference counted; the caller must
                    433:  *     maintain that.
                    434:  */
                    435: struct mbuf *
                    436: ieee80211_encap(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node **pni)
                    437: {
                    438:        struct ieee80211com *ic = (void *)ifp;
                    439:        struct ether_header eh;
                    440:        struct ieee80211_frame *wh;
                    441:        struct ieee80211_node *ni = NULL;
                    442:        struct llc *llc;
                    443:        struct m_tag *mtag;
                    444:        u_int8_t *addr;
                    445:        u_int dlt, hdrlen;
                    446:        int addqos, tid;
                    447:
                    448:        /* Handle raw frames if mbuf is tagged as 802.11 */
                    449:        if ((mtag = m_tag_find(m, PACKET_TAG_DLT, NULL)) != NULL) {
                    450:                dlt = *(u_int *)(mtag + 1);
                    451:
                    452:                if (!(dlt == DLT_IEEE802_11 || dlt == DLT_IEEE802_11_RADIO))
                    453:                        goto fallback;
                    454:
                    455:                wh = mtod(m, struct ieee80211_frame *);
                    456:
                    457:                if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min))
                    458:                        goto bad;
                    459:
                    460:                if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
                    461:                    IEEE80211_FC0_VERSION_0)
                    462:                        goto bad;
                    463:
                    464:                switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
                    465:                case IEEE80211_FC1_DIR_NODS:
                    466:                case IEEE80211_FC1_DIR_FROMDS:
                    467:                        addr = wh->i_addr1;
                    468:                        break;
                    469:                case IEEE80211_FC1_DIR_DSTODS:
                    470:                case IEEE80211_FC1_DIR_TODS:
                    471:                        addr = wh->i_addr3;
                    472:                        break;
                    473:                default:
                    474:                        goto bad;
                    475:                }
                    476:
                    477:                ni = ieee80211_find_txnode(ic, addr);
                    478:                if (ni == NULL)
                    479:                        ni = ieee80211_ref_node(ic->ic_bss);
                    480:                if (ni == NULL) {
                    481:                        printf("%s: no node for dst %s, "
                    482:                            "discard raw tx frame\n", ifp->if_xname,
                    483:                            ether_sprintf(addr));
                    484:                        ic->ic_stats.is_tx_nonode++;
                    485:                        goto bad;
                    486:                }
                    487:                ni->ni_inact = 0;
                    488:
                    489:                *pni = ni;
                    490:                return (m);
                    491:        }
                    492:
                    493:  fallback:
                    494:        if (m->m_len < sizeof(struct ether_header)) {
                    495:                m = m_pullup(m, sizeof(struct ether_header));
                    496:                if (m == NULL) {
                    497:                        ic->ic_stats.is_tx_nombuf++;
                    498:                        goto bad;
                    499:                }
                    500:        }
                    501:        memcpy(&eh, mtod(m, caddr_t), sizeof(struct ether_header));
                    502:
                    503:        ni = ieee80211_find_txnode(ic, eh.ether_dhost);
                    504:        if (ni == NULL) {
                    505:                IEEE80211_DPRINTF(("%s: no node for dst %s, discard frame\n",
                    506:                    __func__, ether_sprintf(eh.ether_dhost)));
                    507:                ic->ic_stats.is_tx_nonode++;
                    508:                goto bad;
                    509:        }
                    510: #if 0
                    511:        if (!ni->ni_port_valid && eh.ether_type != htons(ETHERTYPE_PAE)) {
                    512:                IEEE80211_DPRINTF(("%s: port not valid: %s\n",
                    513:                    __func__, ether_sprintf(eh.ether_dhost)));
                    514:                ic->ic_stats.is_tx_noauth++;
                    515:                goto bad;
                    516:        }
                    517: #endif
                    518:        ni->ni_inact = 0;
                    519:
                    520:        if ((ic->ic_flags & IEEE80211_F_QOS) &&
                    521:            (ni->ni_flags & IEEE80211_NODE_QOS) &&
                    522:            /* do not QoS-encapsulate EAPOL frames */
                    523:            eh.ether_type != htons(ETHERTYPE_PAE)) {
                    524:                tid = ieee80211_classify(ic, m);
                    525:                hdrlen = sizeof(struct ieee80211_qosframe);
                    526:                addqos = 1;
                    527:        } else {
                    528:                hdrlen = sizeof(struct ieee80211_frame);
                    529:                addqos = 0;
                    530:        }
                    531:        m_adj(m, sizeof(struct ether_header) - sizeof(struct llc));
                    532:        llc = mtod(m, struct llc *);
                    533:        llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
                    534:        llc->llc_control = LLC_UI;
                    535:        llc->llc_snap.org_code[0] = 0;
                    536:        llc->llc_snap.org_code[1] = 0;
                    537:        llc->llc_snap.org_code[2] = 0;
                    538:        llc->llc_snap.ether_type = eh.ether_type;
                    539:        M_PREPEND(m, hdrlen, M_DONTWAIT);
                    540:        if (m == NULL) {
                    541:                ic->ic_stats.is_tx_nombuf++;
                    542:                goto bad;
                    543:        }
                    544:        wh = mtod(m, struct ieee80211_frame *);
                    545:        wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA;
                    546:        *(u_int16_t *)&wh->i_dur[0] = 0;
                    547:        if (addqos) {
                    548:                struct ieee80211_qosframe *qwh =
                    549:                    (struct ieee80211_qosframe *)wh;
                    550:                qwh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_QOS;
                    551:                qwh->i_qos[0] = tid & IEEE80211_QOS_TID;
                    552:                qwh->i_qos[1] = 0;      /* no TXOP requested */
                    553:                *(u_int16_t *)&qwh->i_seq[0] =
                    554:                    htole16(ni->ni_qos_txseqs[tid] << IEEE80211_SEQ_SEQ_SHIFT);
                    555:                ni->ni_qos_txseqs[tid]++;
                    556:        } else {
                    557:                *(u_int16_t *)&wh->i_seq[0] =
                    558:                    htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);
                    559:                ni->ni_txseq++;
                    560:        }
                    561:        switch (ic->ic_opmode) {
                    562:        case IEEE80211_M_STA:
                    563:                wh->i_fc[1] = IEEE80211_FC1_DIR_TODS;
                    564:                IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_bssid);
                    565:                IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
                    566:                IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost);
                    567:                break;
                    568:        case IEEE80211_M_IBSS:
                    569:        case IEEE80211_M_AHDEMO:
                    570:                wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
                    571:                IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
                    572:                IEEE80211_ADDR_COPY(wh->i_addr2, eh.ether_shost);
                    573:                IEEE80211_ADDR_COPY(wh->i_addr3, ic->ic_bss->ni_bssid);
                    574:                break;
                    575:        case IEEE80211_M_HOSTAP:
                    576:                wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
                    577:                IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
                    578:                IEEE80211_ADDR_COPY(wh->i_addr2, ni->ni_bssid);
                    579:                IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost);
                    580:                break;
                    581:        case IEEE80211_M_MONITOR:
                    582:                goto bad;
                    583:        }
                    584:        if (ic->ic_flags & IEEE80211_F_WEPON)
                    585:                wh->i_fc[1] |= IEEE80211_FC1_WEP;
                    586:        *pni = ni;
                    587:        return m;
                    588: bad:
                    589:        if (m != NULL)
                    590:                m_freem(m);
                    591:        if (ni != NULL)
                    592:                ieee80211_release_node(ic, ni);
                    593:        *pni = NULL;
                    594:        return NULL;
                    595: }
                    596:
                    597: /* unaligned little endian access */
                    598: #define LE_WRITE_2(p, v) do {                  \
                    599:        ((u_int8_t *)(p))[0] = (v) & 0xff;      \
                    600:        ((u_int8_t *)(p))[1] = (v) >> 8;        \
                    601: } while (0)
                    602:
                    603: /*
                    604:  * Add a Capability Information field to a frame (see 7.3.1.4).
                    605:  */
                    606: u_int8_t *
                    607: ieee80211_add_capinfo(u_int8_t *frm, struct ieee80211com *ic,
                    608:     const struct ieee80211_node *ni)
                    609: {
                    610:        u_int16_t capinfo;
                    611:
                    612:        if (ic->ic_opmode == IEEE80211_M_IBSS)
                    613:                capinfo = IEEE80211_CAPINFO_IBSS;
                    614:        else if (ic->ic_opmode == IEEE80211_M_HOSTAP)
                    615:                capinfo = IEEE80211_CAPINFO_ESS;
                    616:        else
                    617:                capinfo = 0;
                    618:        if (ic->ic_flags & IEEE80211_F_WEPON)
                    619:                capinfo |= IEEE80211_CAPINFO_PRIVACY;
                    620:        /* NB: some 11a AP's reject the request when short preamble is set */
                    621:        if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
                    622:            IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
                    623:                capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
                    624:        if (ic->ic_flags & IEEE80211_F_SHSLOT)
                    625:                capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
                    626:        LE_WRITE_2(frm, capinfo);
                    627:        return frm + 2;
                    628: }
                    629:
                    630: /*
                    631:  * Add an SSID element to a frame (see 7.3.2.1).
                    632:  */
                    633: u_int8_t *
                    634: ieee80211_add_ssid(u_int8_t *frm, const u_int8_t *ssid, u_int len)
                    635: {
                    636:        *frm++ = IEEE80211_ELEMID_SSID;
                    637:        *frm++ = len;
                    638:        memcpy(frm, ssid, len);
                    639:        return frm + len;
                    640: }
                    641:
                    642: /*
                    643:  * Add a supported rates element to a frame (see 7.3.2.2).
                    644:  */
                    645: u_int8_t *
                    646: ieee80211_add_rates(u_int8_t *frm, const struct ieee80211_rateset *rs)
                    647: {
                    648:        int nrates;
                    649:
                    650:        *frm++ = IEEE80211_ELEMID_RATES;
                    651:        nrates = min(rs->rs_nrates, IEEE80211_RATE_SIZE);
                    652:        *frm++ = nrates;
                    653:        memcpy(frm, rs->rs_rates, nrates);
                    654:        return frm + nrates;
                    655: }
                    656:
                    657: /*
                    658:  * Add a FH Parameter Set element to a frame (see 7.3.2.3).
                    659:  */
                    660: u_int8_t *
                    661: ieee80211_add_fh_params(u_int8_t *frm, struct ieee80211com *ic,
                    662:     const struct ieee80211_node *ni)
                    663: {
                    664:        u_int chan = ieee80211_chan2ieee(ic, ni->ni_chan);
                    665:
                    666:        *frm++ = IEEE80211_ELEMID_FHPARMS;
                    667:        *frm++ = 5;
                    668:        LE_WRITE_2(frm, ni->ni_fhdwell); frm += 2;
                    669:        *frm++ = IEEE80211_FH_CHANSET(chan);
                    670:        *frm++ = IEEE80211_FH_CHANPAT(chan);
                    671:        *frm++ = ni->ni_fhindex;
                    672:        return frm;
                    673: }
                    674:
                    675: /*
                    676:  * Add a DS Parameter Set element to a frame (see 7.3.2.4).
                    677:  */
                    678: u_int8_t *
                    679: ieee80211_add_ds_params(u_int8_t *frm, struct ieee80211com *ic,
                    680:     const struct ieee80211_node *ni)
                    681: {
                    682:        *frm++ = IEEE80211_ELEMID_DSPARMS;
                    683:        *frm++ = 1;
                    684:        *frm++ = ieee80211_chan2ieee(ic, ni->ni_chan);
                    685:        return frm;
                    686: }
                    687:
                    688: /*
                    689:  * Add a TIM element to a frame (see 7.3.2.6 and Annex L).
                    690:  */
                    691: u_int8_t *
                    692: ieee80211_add_tim(u_int8_t *frm, struct ieee80211com *ic)
                    693: {
                    694:        u_int i, offset = 0, len;
                    695:
                    696:        /* find first non-zero octet in the virtual bit map */
                    697:        for (i = 0; i < ic->ic_tim_len && ic->ic_tim_bitmap[i] == 0; i++);
                    698:
                    699:        /* clear the lsb as it is reserved for the broadcast indication bit */
                    700:        if (i < ic->ic_tim_len)
                    701:                offset = i & ~1;
                    702:
                    703:        /* find last non-zero octet in the virtual bit map */
                    704:        for (i = ic->ic_tim_len - 1; i > 0 && ic->ic_tim_bitmap[i] == 0; i--);
                    705:
                    706:        len = i - offset + 1;
                    707:
                    708:        *frm++ = IEEE80211_ELEMID_TIM;
                    709:        *frm++ = len + 3;               /* length */
                    710:        *frm++ = ic->ic_dtim_count;     /* DTIM count */
                    711:        *frm++ = ic->ic_dtim_period;    /* DTIM period */
                    712:
                    713:        /* Bitmap Control */
                    714:        *frm = offset;
                    715:        /* set broadcast/multicast indication bit if necessary */
                    716:        if (ic->ic_dtim_count == 0 && ic->ic_tim_mcast)
                    717:                *frm |= 0x01;
                    718:        frm++;
                    719:
                    720:        /* Partial Virtual Bitmap */
                    721:        memcpy(frm, &ic->ic_tim_bitmap[offset], len);
                    722:        return frm + len;
                    723: }
                    724:
                    725: /*
                    726:  * Add an IBSS Parameter Set element to a frame (see 7.3.2.7).
                    727:  */
                    728: u_int8_t *
                    729: ieee80211_add_ibss_params(u_int8_t *frm, const struct ieee80211_node *ni)
                    730: {
                    731:        *frm++ = IEEE80211_ELEMID_IBSSPARMS;
                    732:        *frm++ = 2;
                    733:        LE_WRITE_2(frm, 0);     /* TODO: ATIM window */
                    734:        return frm + 2;
                    735: }
                    736:
                    737: /*
                    738:  * Add an EDCA Parameter Set element to a frame (see 7.3.2.29).
                    739:  */
                    740: u_int8_t *
                    741: ieee80211_add_edca_params(u_int8_t *frm, struct ieee80211com *ic)
                    742: {
                    743:        const struct ieee80211_edca_ac_params *edca;
                    744:        int aci;
                    745:
                    746:        *frm++ = IEEE80211_ELEMID_EDCAPARMS;
                    747:        *frm++ = 18;    /* length */
                    748:        *frm++ = 0;     /* QoS Info */
                    749:        *frm++ = 0;     /* reserved */
                    750:
                    751:        /* setup AC Parameter Records */
                    752:        edca = ieee80211_qap_edca_table[ic->ic_curmode];
                    753:        for (aci = 0; aci < EDCA_NUM_AC; aci++) {
                    754:                const struct ieee80211_edca_ac_params *ac = &edca[aci];
                    755:
                    756:                *frm++ = (aci << 5) | ((ac->ac_acm & 0x1) << 4) |
                    757:                         (ac->ac_aifsn & 0xf);
                    758:                *frm++ = (ac->ac_ecwmax << 4) |
                    759:                         (ac->ac_ecwmin & 0xf);
                    760:                LE_WRITE_2(frm, ac->ac_txoplimit); frm += 2;
                    761:        }
                    762:        return frm;
                    763: }
                    764:
                    765: /*
                    766:  * Add an ERP element to a frame (see 7.3.2.13).
                    767:  */
                    768: u_int8_t *
                    769: ieee80211_add_erp(u_int8_t *frm, struct ieee80211com *ic)
                    770: {
                    771:        u_int8_t erp;
                    772:
                    773:        *frm++ = IEEE80211_ELEMID_ERP;
                    774:        *frm++ = 1;
                    775:        erp = 0;
                    776:        /*
                    777:         * The NonERP_Present bit shall be set to 1 when a NonERP STA
                    778:         * is associated with the BSS.
                    779:         */
                    780:        if (ic->ic_nonerpsta != 0)
                    781:                erp |= IEEE80211_ERP_NON_ERP_PRESENT;
                    782:        /*
                    783:         * If one or more NonERP STAs are associated in the BSS, the
                    784:         * Use_Protection bit shall be set to 1 in transmitted ERP
                    785:         * Information Elements.
                    786:         */
                    787:        if (ic->ic_flags & IEEE80211_F_USEPROT)
                    788:                erp |= IEEE80211_ERP_USE_PROTECTION;
                    789:        /*
                    790:         * The Barker_Preamble_Mode bit shall be set to 1 by the ERP
                    791:         * Information Element sender if one or more associated NonERP
                    792:         * STAs are not short preamble capable.
                    793:         */
                    794:        if (!(ic->ic_flags & IEEE80211_F_SHPREAMBLE))
                    795:                erp |= IEEE80211_ERP_BARKER_MODE;
                    796:        *frm++ = erp;
                    797:        return frm;
                    798: }
                    799:
                    800: /*
                    801:  * Add a QoS Capability element to a frame (see 7.3.2.35).
                    802:  */
                    803: u_int8_t *
                    804: ieee80211_add_qos_capability(u_int8_t *frm, struct ieee80211com *ic)
                    805: {
                    806:        *frm++ = IEEE80211_ELEMID_QOS_CAP;
                    807:        *frm++ = 1;
                    808:        *frm++ = 0;     /* QoS Info */
                    809:        return frm;
                    810: }
                    811:
                    812: /*
                    813:  * Add an RSN element to a frame (see 7.3.2.25).
                    814:  */
                    815: u_int8_t *
                    816: ieee80211_add_rsn_body(u_int8_t *frm, struct ieee80211com *ic,
                    817:     const struct ieee80211_node *ni, int wpa1)
                    818: {
                    819:        const u_int8_t *oui = wpa1 ? MICROSOFT_OUI : IEEE80211_OUI;
                    820:        u_int8_t *pcount;
                    821:        u_int16_t count;
                    822:
                    823:        /* write Version field */
                    824:        LE_WRITE_2(frm, 1); frm += 2;
                    825:
                    826:        /* write Group Cipher Suite field (see Table 20da) */
                    827:        memcpy(frm, oui, 3); frm += 3;
                    828:        switch (ni->ni_group_cipher) {
                    829:        case IEEE80211_CIPHER_USEGROUP:
                    830:                /* can't get there */
                    831:                panic("invalid group cipher!");
                    832:                break;
                    833:        case IEEE80211_CIPHER_WEP40:
                    834:                *frm++ = 1;
                    835:                break;
                    836:        case IEEE80211_CIPHER_TKIP:
                    837:                *frm++ = 2;
                    838:                break;
                    839:        case IEEE80211_CIPHER_CCMP:
                    840:                *frm++ = 4;
                    841:                break;
                    842:        case IEEE80211_CIPHER_WEP104:
                    843:                *frm++ = 5;
                    844:                break;
                    845:        }
                    846:
                    847:        pcount = frm; frm += 2;
                    848:        count = 0;
                    849:        /* write Pairwise Cipher Suite List */
                    850:        if (ni->ni_pairwise_cipherset & IEEE80211_CIPHER_USEGROUP) {
                    851:                memcpy(frm, oui, 3); frm += 3;
                    852:                *frm++ = 0;
                    853:                count++;
                    854:        }
                    855:        if (ni->ni_pairwise_cipherset & IEEE80211_CIPHER_TKIP) {
                    856:                memcpy(frm, oui, 3); frm += 3;
                    857:                *frm++ = 2;
                    858:                count++;
                    859:        }
                    860:        if (ni->ni_pairwise_cipherset & IEEE80211_CIPHER_CCMP) {
                    861:                memcpy(frm, oui, 3); frm += 3;
                    862:                *frm++ = 4;
                    863:                count++;
                    864:        }
                    865:        /* write Pairwise Cipher Suite Count field */
                    866:        LE_WRITE_2(pcount, count);
                    867:
                    868:        pcount = frm; frm += 2;
                    869:        count = 0;
                    870:        /* write AKM Suite List (see Table 20dc) */
                    871:        if (ni->ni_akmset & IEEE80211_AKM_IEEE8021X) {
                    872:                memcpy(frm, oui, 3); frm += 3;
                    873:                *frm++ = 1;
                    874:                count++;
                    875:        }
                    876:        if (ni->ni_akmset & IEEE80211_AKM_PSK) {
                    877:                memcpy(frm, oui, 3); frm += 3;
                    878:                *frm++ = 2;
                    879:                count++;
                    880:        }
                    881:        /* write AKM Suite List Count field */
                    882:        LE_WRITE_2(pcount, count);
                    883:
                    884:        /* write RSN Capabilities field */
                    885:        LE_WRITE_2(frm, ni->ni_rsncaps); frm += 2;
                    886:
                    887:        /* no PMKID List for now */
                    888:
                    889:        return frm;
                    890: }
                    891:
                    892: u_int8_t *
                    893: ieee80211_add_rsn(u_int8_t *frm, struct ieee80211com *ic,
                    894:     const struct ieee80211_node *ni)
                    895: {
                    896:        u_int8_t *plen;
                    897:
                    898:        *frm++ = IEEE80211_ELEMID_RSN;
                    899:        plen = frm++;   /* length filled in later */
                    900:        frm = ieee80211_add_rsn_body(frm, ic, ni, 0);
                    901:
                    902:        /* write length field */
                    903:        *plen = frm - plen - 1;
                    904:        return frm;
                    905: }
                    906:
                    907: /*
                    908:  * Add a vendor specific WPA1 element to a frame.
                    909:  * This is required for compatibility with Wi-Fi Alliance WPA1/WPA1+WPA2.
                    910:  */
                    911: u_int8_t *
                    912: ieee80211_add_wpa1(u_int8_t *frm, struct ieee80211com *ic,
                    913:     const struct ieee80211_node *ni)
                    914: {
                    915:        u_int8_t *plen;
                    916:
                    917:        *frm++ = IEEE80211_ELEMID_VENDOR;
                    918:        plen = frm++;   /* length filled in later */
                    919:        memcpy(frm, MICROSOFT_OUI, 3); frm += 3;
                    920:        *frm++ = 1;     /* WPA1 */
                    921:        frm = ieee80211_add_rsn_body(frm, ic, ni, 1);
                    922:
                    923:        /* write length field */
                    924:        *plen = frm - plen - 1;
                    925:        return frm;
                    926: }
                    927:
                    928: /*
                    929:  * Add an extended supported rates element to a frame (see 7.3.2.14).
                    930:  */
                    931: u_int8_t *
                    932: ieee80211_add_xrates(u_int8_t *frm, const struct ieee80211_rateset *rs)
                    933: {
                    934:        int nrates;
                    935:
                    936:        KASSERT(rs->rs_nrates > IEEE80211_RATE_SIZE);
                    937:
                    938:        *frm++ = IEEE80211_ELEMID_XRATES;
                    939:        nrates = rs->rs_nrates - IEEE80211_RATE_SIZE;
                    940:        *frm++ = nrates;
                    941:        memcpy(frm, rs->rs_rates + IEEE80211_RATE_SIZE, nrates);
                    942:        return frm + nrates;
                    943: }
                    944:
                    945: struct mbuf *
                    946: ieee80211_getmbuf(int flags, int type, u_int pktlen)
                    947: {
                    948:        struct mbuf *m;
                    949:
                    950:        /* account for 802.11 header */
                    951:        pktlen += sizeof(struct ieee80211_frame);
                    952:
                    953:        if (pktlen > MCLBYTES)
                    954:                panic("802.11 packet too large: %u", pktlen);
                    955:        MGETHDR(m, flags, type);
                    956:        if (m != NULL && pktlen > MHLEN) {
                    957:                MCLGET(m, flags);
                    958:                if (!(m->m_flags & M_EXT))
                    959:                        m = m_free(m);
                    960:        }
                    961:        return m;
                    962: }
                    963:
                    964: /*-
                    965:  * Probe request frame format:
                    966:  * [tlv] SSID
                    967:  * [tlv] Supported rates
                    968:  * [tlv] Extended Supported Rates (802.11g)
                    969:  */
                    970: struct mbuf *
                    971: ieee80211_get_probe_req(struct ieee80211com *ic, struct ieee80211_node *ni)
                    972: {
                    973:        const struct ieee80211_rateset *rs =
                    974:            &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
                    975:        struct mbuf *m;
                    976:        u_int8_t *frm;
                    977:
                    978:        m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
                    979:            2 + ic->ic_des_esslen +
                    980:            2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
                    981:            ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
                    982:                2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0));
                    983:        if (m == NULL)
                    984:                return NULL;
                    985:
                    986:        m->m_data += sizeof(struct ieee80211_frame);
                    987:
                    988:        frm = mtod(m, u_int8_t *);
                    989:        frm = ieee80211_add_ssid(frm, ic->ic_des_essid, ic->ic_des_esslen);
                    990:        frm = ieee80211_add_rates(frm, rs);
                    991:        if (rs->rs_nrates > IEEE80211_RATE_SIZE)
                    992:                frm = ieee80211_add_xrates(frm, rs);
                    993:
                    994:        m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
                    995:
                    996:        return m;
                    997: }
                    998:
                    999: /*-
                   1000:  * Probe response frame format:
                   1001:  * [8]    Timestamp
                   1002:  * [2]    Beacon interval
                   1003:  * [2]    Capability
                   1004:  * [tlv]  Service Set Identifier (SSID)
                   1005:  * [tlv]  Supported rates
                   1006:  * [tlv*] Frequency-Hopping (FH) Parameter Set
                   1007:  * [tlv*] DS Parameter Set (802.11g)
                   1008:  * [tlv]  ERP Information (802.11g)
                   1009:  * [tlv]  Extended Supported Rates (802.11g)
                   1010:  * [tlv]  RSN (802.11i)
                   1011:  * [tlv]  EDCA Parameter Set (802.11e)
                   1012:  */
                   1013: struct mbuf *
                   1014: ieee80211_get_probe_resp(struct ieee80211com *ic, struct ieee80211_node *ni)
                   1015: {
                   1016:        const struct ieee80211_rateset *rs = &ic->ic_bss->ni_rates;
                   1017:        struct mbuf *m;
                   1018:        u_int8_t *frm;
                   1019:
                   1020:        m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
                   1021:            8 + 2 + 2 +
                   1022:            2 + ni->ni_esslen +
                   1023:            2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
                   1024:            2 + ((ic->ic_phytype == IEEE80211_T_FH) ? 5 : 1) +
                   1025:            ((ic->ic_opmode == IEEE80211_M_IBSS) ? 2 + 2 : 0) +
                   1026:            ((ic->ic_curmode == IEEE80211_MODE_11G) ? 2 + 1 : 0) +
                   1027:            ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
                   1028:                2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
                   1029:            ((ic->ic_flags & IEEE80211_F_RSN) ? 2 + 44 : 0) +
                   1030:            ((ic->ic_flags & IEEE80211_F_QOS) ? 2 + 18 : 0) +
                   1031:            ((ic->ic_flags & IEEE80211_F_WPA1) ? 2 + 48 : 0));
                   1032:        if (m == NULL)
                   1033:                return NULL;
                   1034:
                   1035:        m->m_data += sizeof(struct ieee80211_frame);
                   1036:
                   1037:        frm = mtod(m, u_int8_t *);
                   1038:        memset(frm, 0, 8); frm += 8;    /* timestamp is set by hardware */
                   1039:        LE_WRITE_2(frm, ic->ic_bss->ni_intval); frm += 2;
                   1040:        frm = ieee80211_add_capinfo(frm, ic, ni);
                   1041:        frm = ieee80211_add_ssid(frm, ic->ic_bss->ni_essid,
                   1042:            ic->ic_bss->ni_esslen);
                   1043:        frm = ieee80211_add_rates(frm, rs);
                   1044:        if (ic->ic_phytype == IEEE80211_T_FH)
                   1045:                frm = ieee80211_add_fh_params(frm, ic, ni);
                   1046:        else
                   1047:                frm = ieee80211_add_ds_params(frm, ic, ni);
                   1048:        if (ic->ic_opmode == IEEE80211_M_IBSS)
                   1049:                frm = ieee80211_add_ibss_params(frm, ni);
                   1050:        if (ic->ic_curmode == IEEE80211_MODE_11G)
                   1051:                frm = ieee80211_add_erp(frm, ic);
                   1052:        if (rs->rs_nrates > IEEE80211_RATE_SIZE)
                   1053:                frm = ieee80211_add_xrates(frm, rs);
                   1054:        if (ic->ic_flags & IEEE80211_F_RSN)
                   1055:                frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
                   1056:        if (ic->ic_flags & IEEE80211_F_QOS)
                   1057:                frm = ieee80211_add_edca_params(frm, ic);
                   1058:        if (ic->ic_flags & IEEE80211_F_WPA1)
                   1059:                frm = ieee80211_add_wpa1(frm, ic, ic->ic_bss);
                   1060:
                   1061:        m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
                   1062:
                   1063:        return m;
                   1064: }
                   1065:
                   1066: /*-
                   1067:  * Authentication frame format:
                   1068:  * [2] Authentication algorithm number
                   1069:  * [2] Authentication transaction sequence number
                   1070:  * [2] Status code
                   1071:  */
                   1072: struct mbuf *
                   1073: ieee80211_get_auth(struct ieee80211com *ic, struct ieee80211_node *ni,
                   1074:     u_int16_t status, u_int16_t seq)
                   1075: {
                   1076:        struct mbuf *m;
                   1077:        u_int8_t *frm;
                   1078:
                   1079:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1080:        if (m == NULL)
                   1081:                return NULL;
                   1082:        MH_ALIGN(m, 2 * 3);
                   1083:        m->m_pkthdr.len = m->m_len = 2 * 3;
                   1084:
                   1085:        frm = mtod(m, u_int8_t *);
                   1086:        LE_WRITE_2(frm, IEEE80211_AUTH_ALG_OPEN); frm += 2;
                   1087:        LE_WRITE_2(frm, seq); frm += 2;
                   1088:        LE_WRITE_2(frm, status);
                   1089:
                   1090:        return m;
                   1091: }
                   1092:
                   1093: /*-
                   1094:  * Deauthentication frame format:
                   1095:  * [2] Reason code
                   1096:  */
                   1097: struct mbuf *
                   1098: ieee80211_get_deauth(struct ieee80211com *ic, struct ieee80211_node *ni,
                   1099:     u_int16_t reason)
                   1100: {
                   1101:        struct mbuf *m;
                   1102:
                   1103:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1104:        if (m == NULL)
                   1105:                return NULL;
                   1106:        MH_ALIGN(m, 2);
                   1107:
                   1108:        m->m_pkthdr.len = m->m_len = 2;
                   1109:        *mtod(m, u_int16_t *) = htole16(reason);
                   1110:
                   1111:        return m;
                   1112: }
                   1113:
                   1114: /*-
                   1115:  * (Re)Association request frame format:
                   1116:  * [2]   Capability information
                   1117:  * [2]   Listen interval
                   1118:  * [6*]  Current AP address (Reassociation only)
                   1119:  * [tlv] SSID
                   1120:  * [tlv] Supported rates
                   1121:  * [tlv] Extended Supported Rates (802.11g)
                   1122:  * [tlv] RSN (802.11i)
                   1123:  * [tlv] QoS Capability (802.11e)
                   1124:  */
                   1125: struct mbuf *
                   1126: ieee80211_get_assoc_req(struct ieee80211com *ic, struct ieee80211_node *ni,
                   1127:     int reassoc)
                   1128: {
                   1129:        const struct ieee80211_rateset *rs = &ni->ni_rates;
                   1130:        struct mbuf *m;
                   1131:        u_int8_t *frm;
                   1132:        u_int16_t capinfo;
                   1133:
                   1134:        m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
                   1135:            2 + 2 +
                   1136:            ((reassoc == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) ?
                   1137:                IEEE80211_ADDR_LEN : 0) +
                   1138:            2 + ni->ni_esslen +
                   1139:            2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
                   1140:            ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
                   1141:                2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
                   1142:            ((ic->ic_flags & IEEE80211_F_RSN) ? 2 + 44 : 0) +
                   1143:            ((ic->ic_flags & IEEE80211_F_QOS) ? 2 + 1 : 0) +
                   1144:            ((ic->ic_flags & IEEE80211_F_WPA1) ? 2 + 48 : 0));
                   1145:        if (m == NULL)
                   1146:                return NULL;
                   1147:
                   1148:        m->m_data += sizeof(struct ieee80211_frame);
                   1149:
                   1150:        frm = mtod(m, u_int8_t *);
                   1151:        capinfo = IEEE80211_CAPINFO_ESS;
                   1152:        if (ic->ic_flags & IEEE80211_F_WEPON)
                   1153:                capinfo |= IEEE80211_CAPINFO_PRIVACY;
                   1154:        if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
                   1155:            IEEE80211_IS_CHAN_2GHZ(ni->ni_chan))
                   1156:                capinfo |= IEEE80211_CAPINFO_SHORT_PREAMBLE;
                   1157:        if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME) &&
                   1158:            (ic->ic_flags & IEEE80211_F_SHSLOT))
                   1159:                capinfo |= IEEE80211_CAPINFO_SHORT_SLOTTIME;
                   1160:        LE_WRITE_2(frm, capinfo); frm += 2;
                   1161:        LE_WRITE_2(frm, ic->ic_lintval); frm += 2;
                   1162:        if (reassoc == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) {
                   1163:                IEEE80211_ADDR_COPY(frm, ic->ic_bss->ni_bssid);
                   1164:                frm += IEEE80211_ADDR_LEN;
                   1165:        }
                   1166:        frm = ieee80211_add_ssid(frm, ni->ni_essid, ni->ni_esslen);
                   1167:        frm = ieee80211_add_rates(frm, rs);
                   1168:        if (rs->rs_nrates > IEEE80211_RATE_SIZE)
                   1169:                frm = ieee80211_add_xrates(frm, rs);
                   1170:        if (ic->ic_flags & IEEE80211_F_RSN)
                   1171:                frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
                   1172:        if ((ic->ic_flags & IEEE80211_F_QOS) &&
                   1173:            (ni->ni_flags & IEEE80211_NODE_QOS))
                   1174:                frm = ieee80211_add_qos_capability(frm, ic);
                   1175:        if (ic->ic_flags & IEEE80211_F_WPA1)
                   1176:                frm = ieee80211_add_wpa1(frm, ic, ic->ic_bss);
                   1177:
                   1178:        m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
                   1179:
                   1180:        return m;
                   1181: }
                   1182:
                   1183: /*-
                   1184:  * (Re)Association response frame format:
                   1185:  * [2]   Capability information
                   1186:  * [2]   Status code
                   1187:  * [2]   Association ID (AID)
                   1188:  * [tlv] Supported rates
                   1189:  * [tlv] Extended Supported Rates (802.11g)
                   1190:  * [tlv] EDCA Parameter Set (802.11e)
                   1191:  */
                   1192: struct mbuf *
                   1193: ieee80211_get_assoc_resp(struct ieee80211com *ic, struct ieee80211_node *ni,
                   1194:     u_int16_t status)
                   1195: {
                   1196:        const struct ieee80211_rateset *rs = &ni->ni_rates;
                   1197:        struct mbuf *m;
                   1198:        u_int8_t *frm;
                   1199:
                   1200:        m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
                   1201:            2 + 2 + 2 +
                   1202:            2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
                   1203:            ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
                   1204:                2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
                   1205:            ((ic->ic_flags & IEEE80211_F_QOS) ? 2 + 18 : 0));
                   1206:        if (m == NULL)
                   1207:                return NULL;
                   1208:
                   1209:        m->m_data += sizeof(struct ieee80211_frame);
                   1210:
                   1211:        frm = mtod(m, u_int8_t *);
                   1212:        frm = ieee80211_add_capinfo(frm, ic, ni);
                   1213:        LE_WRITE_2(frm, status); frm += 2;
                   1214:        if (status == IEEE80211_STATUS_SUCCESS)
                   1215:                LE_WRITE_2(frm, ni->ni_associd);
                   1216:        else
                   1217:                LE_WRITE_2(frm, 0);
                   1218:        frm += 2;
                   1219:        frm = ieee80211_add_rates(frm, rs);
                   1220:        if (rs->rs_nrates > IEEE80211_RATE_SIZE)
                   1221:                frm = ieee80211_add_xrates(frm, rs);
                   1222:        if ((ic->ic_flags & IEEE80211_F_QOS) &&
                   1223:            (ni->ni_flags & IEEE80211_NODE_QOS))
                   1224:                frm = ieee80211_add_edca_params(frm, ic);
                   1225:
                   1226:        m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
                   1227:
                   1228:        return m;
                   1229: }
                   1230:
                   1231: /*-
                   1232:  * Disassociation frame format:
                   1233:  * [2] Reason code
                   1234:  */
                   1235: struct mbuf *
                   1236: ieee80211_get_disassoc(struct ieee80211com *ic, struct ieee80211_node *ni,
                   1237:     u_int16_t reason)
                   1238: {
                   1239:        struct mbuf *m;
                   1240:
                   1241:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1242:        if (m == NULL)
                   1243:                return NULL;
                   1244:        MH_ALIGN(m, 2);
                   1245:
                   1246:        m->m_pkthdr.len = m->m_len = 2;
                   1247:        *mtod(m, u_int16_t *) = htole16(reason);
                   1248:
                   1249:        return m;
                   1250: }
                   1251:
                   1252: /*
                   1253:  * Send a management frame.  The node is for the destination (or ic_bss
                   1254:  * when in station mode).  Nodes other than ic_bss have their reference
                   1255:  * count bumped to reflect our use for an indeterminant time.
                   1256:  */
                   1257: int
                   1258: ieee80211_send_mgmt(struct ieee80211com *ic, struct ieee80211_node *ni,
                   1259:     int type, int arg)
                   1260: {
                   1261: #define        senderr(_x, _v) do { ic->ic_stats._v++; ret = _x; goto bad; } while (0)
                   1262:        struct ifnet *ifp = &ic->ic_if;
                   1263:        struct mbuf *m;
                   1264:        int ret, timer;
                   1265:
                   1266:        if (ni == NULL)
                   1267:                panic("null node");
                   1268:
                   1269:        /*
                   1270:         * Hold a reference on the node so it doesn't go away until after
                   1271:         * the xmit is complete all the way in the driver.  On error we
                   1272:         * will remove our reference.
                   1273:         */
                   1274:        ieee80211_ref_node(ni);
                   1275:        timer = 0;
                   1276:        switch (type) {
                   1277:        case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
                   1278:                if ((m = ieee80211_get_probe_req(ic, ni)) == NULL)
                   1279:                        senderr(ENOMEM, is_tx_nombuf);
                   1280:
                   1281:                timer = IEEE80211_TRANS_WAIT;
                   1282:                break;
                   1283:
                   1284:        case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
                   1285:                if ((m = ieee80211_get_probe_resp(ic, ni)) == NULL)
                   1286:                        senderr(ENOMEM, is_tx_nombuf);
                   1287:                break;
                   1288:
                   1289:        case IEEE80211_FC0_SUBTYPE_AUTH:
                   1290:                m = ieee80211_get_auth(ic, ni, arg >> 16, arg & 0xffff);
                   1291:                if (m == NULL)
                   1292:                        senderr(ENOMEM, is_tx_nombuf);
                   1293:
                   1294:                if (ic->ic_opmode == IEEE80211_M_STA)
                   1295:                        timer = IEEE80211_TRANS_WAIT;
                   1296:                break;
                   1297:
                   1298:        case IEEE80211_FC0_SUBTYPE_DEAUTH:
                   1299:                if ((m = ieee80211_get_deauth(ic, ni, arg)) == NULL)
                   1300:                        senderr(ENOMEM, is_tx_nombuf);
                   1301:
                   1302:                if (ifp->if_flags & IFF_DEBUG) {
                   1303:                        printf("%s: station %s deauthenticate (reason %d)\n",
                   1304:                            ifp->if_xname, ether_sprintf(ni->ni_macaddr), arg);
                   1305:                }
                   1306:                break;
                   1307:
                   1308:        case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
                   1309:        case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
                   1310:                if ((m = ieee80211_get_assoc_req(ic, ni, type)) == NULL)
                   1311:                        senderr(ENOMEM, is_tx_nombuf);
                   1312:
                   1313:                timer = IEEE80211_TRANS_WAIT;
                   1314:                break;
                   1315:
                   1316:        case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
                   1317:        case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
                   1318:                if ((m = ieee80211_get_assoc_resp(ic, ni, arg)) == NULL)
                   1319:                        senderr(ENOMEM, is_tx_nombuf);
                   1320:                break;
                   1321:
                   1322:        case IEEE80211_FC0_SUBTYPE_DISASSOC:
                   1323:                if ((m = ieee80211_get_disassoc(ic, ni, arg)) == NULL)
                   1324:                        senderr(ENOMEM, is_tx_nombuf);
                   1325:
                   1326:                if (ifp->if_flags & IFF_DEBUG) {
                   1327:                        printf("%s: station %s disassociate (reason %d)\n",
                   1328:                            ifp->if_xname, ether_sprintf(ni->ni_macaddr), arg);
                   1329:                }
                   1330:                break;
                   1331:
                   1332:        default:
                   1333:                IEEE80211_DPRINTF(("%s: invalid mgmt frame type %u\n",
                   1334:                    __func__, type));
                   1335:                senderr(EINVAL, is_tx_unknownmgt);
                   1336:                /* NOTREACHED */
                   1337:        }
                   1338:
                   1339:        ret = ieee80211_mgmt_output(ifp, ni, m, type);
                   1340:        if (ret == 0) {
                   1341:                if (timer)
                   1342:                        ic->ic_mgt_timer = timer;
                   1343:        } else {
                   1344: bad:
                   1345:                ieee80211_release_node(ic, ni);
                   1346:        }
                   1347:        return ret;
                   1348: #undef senderr
                   1349: }
                   1350:
                   1351: /*
                   1352:  * Build a RTS (Request To Send) control frame (see 7.2.1.1).
                   1353:  */
                   1354: struct mbuf *
                   1355: ieee80211_get_rts(struct ieee80211com *ic, const struct ieee80211_frame *wh,
                   1356:     u_int16_t dur)
                   1357: {
                   1358:        struct ieee80211_frame_rts *rts;
                   1359:        struct mbuf *m;
                   1360:
                   1361:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1362:        if (m == NULL)
                   1363:                return NULL;
                   1364:
                   1365:        m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_rts);
                   1366:
                   1367:        rts = mtod(m, struct ieee80211_frame_rts *);
                   1368:        rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL |
                   1369:            IEEE80211_FC0_SUBTYPE_RTS;
                   1370:        rts->i_fc[1] = IEEE80211_FC1_DIR_NODS;
                   1371:        *(u_int16_t *)rts->i_dur = htole16(dur);
                   1372:        IEEE80211_ADDR_COPY(rts->i_ra, wh->i_addr1);
                   1373:        IEEE80211_ADDR_COPY(rts->i_ta, wh->i_addr2);
                   1374:
                   1375:        return m;
                   1376: }
                   1377:
                   1378: /*
                   1379:  * Build a CTS-to-self (Clear To Send) control frame (see 7.2.1.2).
                   1380:  */
                   1381: struct mbuf *
                   1382: ieee80211_get_cts_to_self(struct ieee80211com *ic, u_int16_t dur)
                   1383: {
                   1384:        struct ieee80211_frame_cts *cts;
                   1385:        struct mbuf *m;
                   1386:
                   1387:        MGETHDR(m, M_DONTWAIT, MT_DATA);
                   1388:        if (m == NULL)
                   1389:                return NULL;
                   1390:
                   1391:        m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_cts);
                   1392:
                   1393:        cts = mtod(m, struct ieee80211_frame_cts *);
                   1394:        cts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL |
                   1395:            IEEE80211_FC0_SUBTYPE_CTS;
                   1396:        cts->i_fc[1] = IEEE80211_FC1_DIR_NODS;
                   1397:        *(u_int16_t *)cts->i_dur = htole16(dur);
                   1398:        IEEE80211_ADDR_COPY(cts->i_ra, ic->ic_myaddr);
                   1399:
                   1400:        return m;
                   1401: }
                   1402:
                   1403: /*-
                   1404:  * Beacon frame format:
                   1405:  * [8]    Timestamp
                   1406:  * [2]    Beacon interval
                   1407:  * [2]    Capability
                   1408:  * [tlv]  Service Set Identifier (SSID)
                   1409:  * [tlv]  Supported rates
                   1410:  * [tlv*] Frequency-Hopping (FH) Parameter Set
                   1411:  * [tlv*] DS Parameter Set (802.11g)
                   1412:  * [tlv*] IBSS Parameter Set
                   1413:  * [tlv]  Traffic Indication Map (TIM)
                   1414:  * [tlv]  ERP Information (802.11g)
                   1415:  * [tlv]  Extended Supported Rates (802.11g)
                   1416:  * [tlv]  RSN (802.11i)
                   1417:  * [tlv]  EDCA Parameter Set (802.11e)
                   1418:  */
                   1419: struct mbuf *
                   1420: ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni)
                   1421: {
                   1422:        const struct ieee80211_rateset *rs = &ni->ni_rates;
                   1423:        struct ieee80211_frame *wh;
                   1424:        struct mbuf *m;
                   1425:        u_int8_t *frm;
                   1426:
                   1427:        m = ieee80211_getmbuf(M_DONTWAIT, MT_DATA,
                   1428:            8 + 2 + 2 +
                   1429:            2 + ((ic->ic_flags & IEEE80211_F_HIDENWID) ? 0 : ni->ni_esslen) +
                   1430:            2 + min(rs->rs_nrates, IEEE80211_RATE_SIZE) +
                   1431:            2 + ((ic->ic_phytype == IEEE80211_T_FH) ? 5 : 1) +
                   1432:            2 + ((ic->ic_opmode == IEEE80211_M_IBSS) ? 2 : 254) +
                   1433:            ((ic->ic_curmode == IEEE80211_MODE_11G) ? 2 + 1 : 0) +
                   1434:            ((rs->rs_nrates > IEEE80211_RATE_SIZE) ?
                   1435:                2 + rs->rs_nrates - IEEE80211_RATE_SIZE : 0) +
                   1436:            ((ic->ic_flags & IEEE80211_F_RSN) ? 2 + 44 : 0) +
                   1437:            ((ic->ic_flags & IEEE80211_F_QOS) ? 2 + 18 : 0) +
                   1438:            ((ic->ic_flags & IEEE80211_F_WPA1) ? 2 + 48 : 0));
                   1439:        if (m == NULL)
                   1440:                return NULL;
                   1441:
                   1442:        wh = mtod(m, struct ieee80211_frame *);
                   1443:        wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
                   1444:            IEEE80211_FC0_SUBTYPE_BEACON;
                   1445:        wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
                   1446:        *(u_int16_t *)wh->i_dur = 0;
                   1447:        IEEE80211_ADDR_COPY(wh->i_addr1, etherbroadcastaddr);
                   1448:        IEEE80211_ADDR_COPY(wh->i_addr2, ic->ic_myaddr);
                   1449:        IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
                   1450:        *(u_int16_t *)wh->i_seq = 0;
                   1451:
                   1452:        frm = (u_int8_t *)&wh[1];
                   1453:        memset(frm, 0, 8); frm += 8;    /* timestamp is set by hardware */
                   1454:        LE_WRITE_2(frm, ni->ni_intval); frm += 2;
                   1455:        frm = ieee80211_add_capinfo(frm, ic, ni);
                   1456:        if (ic->ic_flags & IEEE80211_F_HIDENWID)
                   1457:                frm = ieee80211_add_ssid(frm, NULL, 0);
                   1458:        else
                   1459:                frm = ieee80211_add_ssid(frm, ni->ni_essid, ni->ni_esslen);
                   1460:        frm = ieee80211_add_rates(frm, rs);
                   1461:        if (ic->ic_phytype == IEEE80211_T_FH)
                   1462:                frm = ieee80211_add_fh_params(frm, ic, ni);
                   1463:        else
                   1464:                frm = ieee80211_add_ds_params(frm, ic, ni);
                   1465:        if (ic->ic_opmode == IEEE80211_M_IBSS)
                   1466:                frm = ieee80211_add_ibss_params(frm, ni);
                   1467:        else
                   1468:                frm = ieee80211_add_tim(frm, ic);
                   1469:        if (ic->ic_curmode == IEEE80211_MODE_11G)
                   1470:                frm = ieee80211_add_erp(frm, ic);
                   1471:        if (rs->rs_nrates > IEEE80211_RATE_SIZE)
                   1472:                frm = ieee80211_add_xrates(frm, rs);
                   1473:        if (ic->ic_flags & IEEE80211_F_RSN)
                   1474:                frm = ieee80211_add_rsn(frm, ic, ni);
                   1475:        if (ic->ic_flags & IEEE80211_F_QOS)
                   1476:                frm = ieee80211_add_edca_params(frm, ic);
                   1477:        if (ic->ic_flags & IEEE80211_F_WPA1)
                   1478:                frm = ieee80211_add_wpa1(frm, ic, ni);
                   1479:
                   1480:        m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
                   1481:        m->m_pkthdr.rcvif = (void *)ni;
                   1482:
                   1483:        return m;
                   1484: }
                   1485:
                   1486: /* unaligned big endian access */
                   1487: #define BE_READ_2(p)                           \
                   1488:        ((u_int16_t)(p)[0] << 8 | (u_int16_t)(p)[1])
                   1489:
                   1490: #define BE_WRITE_2(p, v) do {                  \
                   1491:        (p)[0] = (v) >>  8; (p)[1] = (v);       \
                   1492: } while (0)
                   1493:
                   1494: #define BE_WRITE_8(p, v) do {                  \
                   1495:        (p)[0] = (v) >> 56; (p)[1] = (v) >> 48; \
                   1496:        (p)[2] = (v) >> 40; (p)[3] = (v) >> 32; \
                   1497:        (p)[4] = (v) >> 24; (p)[5] = (v) >> 16; \
                   1498:        (p)[6] = (v) >>  8; (p)[7] = (v);       \
                   1499: } while (0)
                   1500:
                   1501: /* unaligned little endian access */
                   1502: #define LE_WRITE_8(p, v) do {                  \
                   1503:        (p)[7] = (v) >> 56; (p)[6] = (v) >> 48; \
                   1504:        (p)[5] = (v) >> 40; (p)[4] = (v) >> 32; \
                   1505:        (p)[3] = (v) >> 24; (p)[2] = (v) >> 16; \
                   1506:        (p)[1] = (v) >>  8; (p)[0] = (v);       \
                   1507: } while (0)
                   1508:
                   1509: int
                   1510: ieee80211_send_eapol_key(struct ieee80211com *ic, struct mbuf *m,
                   1511:     struct ieee80211_node *ni)
                   1512: {
                   1513:        struct ifnet *ifp = &ic->ic_if;
                   1514:        struct ether_header *eh;
                   1515:        struct ieee80211_eapol_key *key;
                   1516:        u_int16_t len, info;
                   1517:        int s, error;
                   1518:
                   1519:        M_PREPEND(m, sizeof(struct ether_header), M_DONTWAIT);
                   1520:        if (m == NULL)
                   1521:                return ENOMEM;
                   1522:        eh = mtod(m, struct ether_header *);
                   1523:        eh->ether_type = htons(ETHERTYPE_PAE);
                   1524:        IEEE80211_ADDR_COPY(eh->ether_shost, ic->ic_myaddr);
                   1525:        IEEE80211_ADDR_COPY(eh->ether_dhost, ni->ni_macaddr);
                   1526:
                   1527:        key = (struct ieee80211_eapol_key *)&eh[1];
                   1528:        key->version = EAPOL_VERSION;
                   1529:        key->type = EAPOL_KEY;
                   1530:        key->desc = ni->ni_eapol_desc;
                   1531:
                   1532:        info = BE_READ_2(key->info);
                   1533:        /* use V2 descriptor only when pairwise cipher is CCMP */
                   1534:        info |= (ni->ni_pairwise_cipher != IEEE80211_CIPHER_CCMP) ?
                   1535:            EAPOL_KEY_DESC_V1 : EAPOL_KEY_DESC_V2;
                   1536:        BE_WRITE_2(key->info, info);
                   1537:
                   1538:        len = m->m_len - sizeof(struct ether_header);
                   1539:        BE_WRITE_2(key->paylen, len - sizeof(*key));
                   1540:        BE_WRITE_2(key->len, len - 4);
                   1541:
                   1542:        KASSERT((info & (EAPOL_KEY_ENCRYPTED | EAPOL_KEY_KEYMIC)) == 0 ||
                   1543:            ni->ni_ptk_ok);
                   1544:
                   1545:        if (info & EAPOL_KEY_ENCRYPTED)
                   1546:                ieee80211_eapol_key_encrypt(ic, key, ni->ni_ptk.kek);
                   1547:
                   1548:        if (info & EAPOL_KEY_KEYMIC)
                   1549:                ieee80211_eapol_key_mic(key, ni->ni_ptk.kck);
                   1550:
                   1551:        s = splnet();
                   1552:        IFQ_ENQUEUE(&ifp->if_snd, m, NULL, error);
                   1553:        if (error) {
                   1554:                splx(s);
                   1555:                return error;
                   1556:        }
                   1557:        ifp->if_obytes += m->m_pkthdr.len;
                   1558:        if ((ifp->if_flags & IFF_OACTIVE) == 0)
                   1559:                (*ifp->if_start)(ifp);
                   1560:        splx(s);
                   1561:
                   1562:        return 0;
                   1563: }
                   1564:
                   1565: /*
                   1566:  * Add a GTK KDE to an EAPOL-Key frame (see Figure 144).
                   1567:  */
                   1568: u_int8_t *
                   1569: ieee80211_add_gtk_kde(u_int8_t *frm, const struct ieee80211_key *k)
                   1570: {
                   1571:        KASSERT(k->k_flags & IEEE80211_KEY_GROUP);
                   1572:
                   1573:        *frm++ = IEEE80211_ELEMID_VENDOR;
                   1574:        *frm++ = 6 + k->k_len;
                   1575:        memcpy(frm, IEEE80211_OUI, 3); frm += 3;
                   1576:        *frm++ = IEEE80211_KDE_GTK;
                   1577:        *frm = k->k_id & 3;
                   1578:        if (k->k_flags & IEEE80211_KEY_TX)
                   1579:                *frm |= 1 << 2; /* set the Tx bit */
                   1580:        frm++;
                   1581:        *frm++ = 0;     /* reserved */
                   1582:        memcpy(frm, k->k_key, k->k_len);
                   1583:        return frm + k->k_len;
                   1584: }
                   1585:
                   1586: /*
                   1587:  * Add a PMKID KDE to an EAPOL-Key frame (see Figure 146).
                   1588:  */
                   1589: u_int8_t *
                   1590: ieee80211_add_pmkid_kde(u_int8_t *frm, const u_int8_t *pmkid)
                   1591: {
                   1592:        *frm++ = IEEE80211_ELEMID_VENDOR;
                   1593:        *frm++ = 20;
                   1594:        memcpy(frm, IEEE80211_OUI, 3); frm += 3;
                   1595:        *frm++ = IEEE80211_KDE_PMKID;
                   1596:        memcpy(frm, pmkid, IEEE80211_PMKID_LEN);
                   1597:        return frm + IEEE80211_PMKID_LEN;
                   1598: }
                   1599:
                   1600: struct mbuf *
                   1601: ieee80211_get_eapol_key(int flags, int type, u_int pktlen)
                   1602: {
                   1603:        struct mbuf *m;
                   1604:
                   1605:        pktlen += sizeof(struct ether_header) +
                   1606:            sizeof(struct ieee80211_eapol_key);
                   1607:
                   1608:        if (pktlen > MCLBYTES)
                   1609:                panic("EAPOL-Key frame too large: %u", pktlen);
                   1610:        MGETHDR(m, flags, type);
                   1611:        if (m != NULL && pktlen > MHLEN) {
                   1612:                MCLGET(m, flags);
                   1613:                if (!(m->m_flags & M_EXT))
                   1614:                        m = m_free(m);
                   1615:        }
                   1616:        m->m_data += sizeof(struct ether_header);
                   1617:        return m;
                   1618: }
                   1619:
                   1620: /*
                   1621:  * 4-Way Handshake Message 1 is sent by the authenticator to the supplicant
                   1622:  * (see 8.5.3.1).
                   1623:  */
                   1624: int
                   1625: ieee80211_send_4way_msg1(struct ieee80211com *ic, struct ieee80211_node *ni)
                   1626: {
                   1627:        struct ieee80211_eapol_key *key;
                   1628:        struct mbuf *m;
                   1629:        u_int16_t info, keylen;
                   1630:        u_int8_t *pmkid;
                   1631:        u_int8_t *frm;
                   1632:
                   1633:        m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
                   1634:            (ni->ni_eapol_desc == EAPOL_KEY_DESC_IEEE80211) ? 2 + 20 : 0);
                   1635:        if (m == NULL)
                   1636:                return ENOMEM;
                   1637:        key = mtod(m, struct ieee80211_eapol_key *);
                   1638:        memset(key, 0, sizeof(*key));
                   1639:
                   1640:        info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYACK;
                   1641:        BE_WRITE_2(key->info, info);
                   1642:
                   1643:        /* generate a new nonce ANonce */
                   1644:        get_random_bytes(ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
                   1645:        memcpy(key->nonce, ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
                   1646:
                   1647:        keylen = ieee80211_cipher_keylen(ni->ni_pairwise_cipher);
                   1648:        BE_WRITE_2(key->keylen, keylen);
                   1649:
                   1650:        frm = (u_int8_t *)&key[1];
                   1651:        /* WPA1 does not have PMKID KDE */
                   1652:        if (ni->ni_eapol_desc == EAPOL_KEY_DESC_IEEE80211) {
                   1653:                /* XXX retrieve PMKID from the PMKSA cache */
                   1654:                frm = ieee80211_add_pmkid_kde(frm, pmkid);
                   1655:        }
                   1656:
                   1657:        m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
                   1658:
                   1659:        if (ic->ic_if.if_flags & IFF_DEBUG)
                   1660:                printf("%s: sending msg %d/%d of the %s handshake to %s\n",
                   1661:                    ic->ic_if.if_xname, 1, 4, "4-way",
                   1662:                    ether_sprintf(ni->ni_macaddr));
                   1663:
                   1664:        return ieee80211_send_eapol_key(ic, m, ni);
                   1665: }
                   1666:
                   1667: /*
                   1668:  * 4-Way Handshake Message 2 is sent by the supplicant to the authenticator
                   1669:  * (see 8.5.3.2).
                   1670:  */
                   1671: int
                   1672: ieee80211_send_4way_msg2(struct ieee80211com *ic, struct ieee80211_node *ni,
                   1673:     const u_int8_t *snonce)
                   1674: {
                   1675:        struct ieee80211_eapol_key *key;
                   1676:        struct mbuf *m;
                   1677:        u_int16_t info;
                   1678:        u_int8_t *frm;
                   1679:
                   1680:        m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
                   1681:            2 + 48);
                   1682:        if (m == NULL)
                   1683:                return ENOMEM;
                   1684:        key = mtod(m, struct ieee80211_eapol_key *);
                   1685:        memset(key, 0, sizeof(*key));
                   1686:
                   1687:        info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYMIC;
                   1688:        BE_WRITE_2(key->info, info);
                   1689:
                   1690:        /* copy key replay counter from authenticator */
                   1691:        BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
                   1692:
                   1693:        /* copy the supplicant's nonce (SNonce) */
                   1694:        memcpy(key->nonce, snonce, EAPOL_KEY_NONCE_LEN);
                   1695:
                   1696:        frm = (u_int8_t *)&key[1];
                   1697:        /* add the WPA/RSN IE used in the (Re)Association Request */
                   1698:        if (ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) {
                   1699:                u_int16_t keylen;
                   1700:                frm = ieee80211_add_wpa1(frm, ic, ni);
                   1701:                /* WPA1 sets the key length field here */
                   1702:                keylen = ieee80211_cipher_keylen(ni->ni_pairwise_cipher);
                   1703:                BE_WRITE_2(key->keylen, keylen);
                   1704:        } else  /* RSN */
                   1705:                frm = ieee80211_add_rsn(frm, ic, ni);
                   1706:
                   1707:        m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
                   1708:
                   1709:        if (ic->ic_if.if_flags & IFF_DEBUG)
                   1710:                printf("%s: sending msg %d/%d of the %s handshake to %s\n",
                   1711:                    ic->ic_if.if_xname, 2, 4, "4-way",
                   1712:                    ether_sprintf(ni->ni_macaddr));
                   1713:
                   1714:        return ieee80211_send_eapol_key(ic, m, ni);
                   1715: }
                   1716:
                   1717: /*
                   1718:  * 4-Way Handshake Message 3 is sent by the authenticator to the supplicant
                   1719:  * (see 8.5.3.3).
                   1720:  */
                   1721: int
                   1722: ieee80211_send_4way_msg3(struct ieee80211com *ic, struct ieee80211_node *ni)
                   1723: {
                   1724:        struct ieee80211_eapol_key *key;
                   1725:        struct ieee80211_key *gtk;
                   1726:        struct mbuf *m;
                   1727:        u_int16_t info, keylen;
                   1728:        u_int8_t *frm;
                   1729:
                   1730:        m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
                   1731:            2 + 48 +
                   1732:            ((ni->ni_eapol_desc == EAPOL_KEY_DESC_IEEE80211) ?
                   1733:                2 + 6 + gtk->k_len : 0) +
                   1734:            8);
                   1735:        if (m == NULL)
                   1736:                return ENOMEM;
                   1737:        key = mtod(m, struct ieee80211_eapol_key *);
                   1738:        memset(key, 0, sizeof(*key));
                   1739:
                   1740:        info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_INSTALL | EAPOL_KEY_KEYACK |
                   1741:            EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE;
                   1742:
                   1743:        BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
                   1744:        /* use same nonce as in Message 1 */
                   1745:        memcpy(key->nonce, ni->ni_nonce, EAPOL_KEY_NONCE_LEN);
                   1746:
                   1747:        keylen = ieee80211_cipher_keylen(ni->ni_pairwise_cipher);
                   1748:        BE_WRITE_2(key->keylen, keylen);
                   1749:
                   1750:        frm = (u_int8_t *)&key[1];
                   1751:        /* add the WPA/RSN IE included in Beacon/Probe Response */
                   1752:        if (ni->ni_eapol_desc == EAPOL_KEY_DESC_IEEE80211) {
                   1753:                frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
                   1754:                /* RSN: encapsulate the GTK and ask for encryption */
                   1755:                frm = ieee80211_add_gtk_kde(frm, gtk);
                   1756:                LE_WRITE_8(key->rsc, gtk->k_rsc);
                   1757:                info |= EAPOL_KEY_ENCRYPTED;
                   1758:        } else  /* WPA1 */
                   1759:                frm = ieee80211_add_wpa1(frm, ic, ic->ic_bss);
                   1760:
                   1761:        /* write the key info field */
                   1762:        BE_WRITE_2(key->info, info);
                   1763:
                   1764:        m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
                   1765:
                   1766:        if (ic->ic_if.if_flags & IFF_DEBUG)
                   1767:                printf("%s: sending msg %d/%d of the %s handshake to %s\n",
                   1768:                    ic->ic_if.if_xname, 3, 4, "4-way",
                   1769:                    ether_sprintf(ni->ni_macaddr));
                   1770:
                   1771:        return ieee80211_send_eapol_key(ic, m, ni);
                   1772: }
                   1773:
                   1774: /*
                   1775:  * 4-Way Handshake Message 4 is sent by the supplicant to the authenticator
                   1776:  * (see 8.5.3.4).
                   1777:  */
                   1778: int
                   1779: ieee80211_send_4way_msg4(struct ieee80211com *ic, struct ieee80211_node *ni)
                   1780: {
                   1781:        struct ieee80211_eapol_key *key;
                   1782:        struct mbuf *m;
                   1783:        u_int16_t info;
                   1784:
                   1785:        m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
                   1786:        if (m == NULL)
                   1787:                return ENOMEM;
                   1788:        key = mtod(m, struct ieee80211_eapol_key *);
                   1789:        memset(key, 0, sizeof(*key));
                   1790:
                   1791:        info = EAPOL_KEY_PAIRWISE | EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE;
                   1792:        BE_WRITE_2(key->info, info);
                   1793:
                   1794:        /* copy key replay counter from authenticator */
                   1795:        BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
                   1796:
                   1797:        if (ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) {
                   1798:                u_int16_t keylen;
                   1799:                /* WPA1 sets the key length field here */
                   1800:                keylen = ieee80211_cipher_keylen(ni->ni_pairwise_cipher);
                   1801:                BE_WRITE_2(key->keylen, keylen);
                   1802:        }
                   1803:
                   1804:        /* empty key data field */
                   1805:        m->m_pkthdr.len = m->m_len = sizeof(*key);
                   1806:
                   1807:        if (ic->ic_if.if_flags & IFF_DEBUG)
                   1808:                printf("%s: sending msg %d/%d of the %s handshake to %s\n",
                   1809:                    ic->ic_if.if_xname, 4, 4, "4-way",
                   1810:                    ether_sprintf(ni->ni_macaddr));
                   1811:
                   1812:        return ieee80211_send_eapol_key(ic, m, ni);
                   1813: }
                   1814:
                   1815: /*
                   1816:  * Group Key Handshake Message 1 is sent by the authenticator to the
                   1817:  * supplicant (see 8.5.4.1).
                   1818:  */
                   1819: int
                   1820: ieee80211_send_group_msg1(struct ieee80211com *ic, struct ieee80211_node *ni)
                   1821: {
                   1822:        struct ieee80211_eapol_key *key;
                   1823:        struct ieee80211_key *gtk;
                   1824:        struct mbuf *m;
                   1825:        u_int16_t info;
                   1826:        u_int8_t *frm;
                   1827:
                   1828:        m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA,
                   1829:            ((ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) ?
                   1830:                gtk->k_len : 2 + 6 + gtk->k_len) +
                   1831:            8);
                   1832:        if (m == NULL)
                   1833:                return ENOMEM;
                   1834:        key = mtod(m, struct ieee80211_eapol_key *);
                   1835:        memset(key, 0, sizeof(*key));
                   1836:
                   1837:        info = EAPOL_KEY_KEYACK | EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE |
                   1838:            EAPOL_KEY_ENCRYPTED;
                   1839:
                   1840:        BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
                   1841:
                   1842:        frm = (u_int8_t *)&key[1];
                   1843:        if (ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) {
                   1844:                /* WPA1 does not have GTK KDE */
                   1845:                BE_WRITE_2(key->keylen, gtk->k_len);
                   1846:                memcpy(frm, gtk->k_key, gtk->k_len);
                   1847:                frm += gtk->k_len;
                   1848:                info |= gtk->k_id << EAPOL_KEY_WPA_KID_SHIFT;
                   1849:                if (gtk->k_flags & IEEE80211_KEY_TX)
                   1850:                        info |= EAPOL_KEY_WPA_TX;
                   1851:        } else  /* RSN */
                   1852:                frm = ieee80211_add_gtk_kde(frm, gtk);
                   1853:
                   1854:        LE_WRITE_8(key->rsc, gtk->k_rsc);
                   1855:
                   1856:        /* write the key info field */
                   1857:        BE_WRITE_2(key->info, info);
                   1858:
                   1859:        m->m_pkthdr.len = m->m_len = frm - (u_int8_t *)key;
                   1860:
                   1861:        if (ic->ic_if.if_flags & IFF_DEBUG)
                   1862:                printf("%s: sending msg %d/%d of the %s handshake to %s\n",
                   1863:                    ic->ic_if.if_xname, 1, 2, "group key",
                   1864:                    ether_sprintf(ni->ni_macaddr));
                   1865:
                   1866:        return ieee80211_send_eapol_key(ic, m, ni);
                   1867: }
                   1868:
                   1869: /*
                   1870:  * Group Key Handshake Message 2 is sent by the supplicant to the
                   1871:  * authenticator (see 8.5.4.2).
                   1872:  */
                   1873: int
                   1874: ieee80211_send_group_msg2(struct ieee80211com *ic, struct ieee80211_node *ni,
                   1875:     const struct ieee80211_key *gtk)
                   1876: {
                   1877:        struct ieee80211_eapol_key *key;
                   1878:        u_int16_t info;
                   1879:        struct mbuf *m;
                   1880:
                   1881:        m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
                   1882:        if (m == NULL)
                   1883:                return ENOMEM;
                   1884:        key = mtod(m, struct ieee80211_eapol_key *);
                   1885:        memset(key, 0, sizeof(*key));
                   1886:
                   1887:        info = EAPOL_KEY_KEYMIC | EAPOL_KEY_SECURE;
                   1888:
                   1889:        /* copy key replay counter from authenticator */
                   1890:        BE_WRITE_8(key->replaycnt, ni->ni_replaycnt);
                   1891:
                   1892:        if (ni->ni_eapol_desc == EAPOL_KEY_DESC_WPA1) {
                   1893:                /* WPA1 sets the key length and key id fields here */
                   1894:                BE_WRITE_2(key->keylen, gtk->k_len);
                   1895:                info |= (gtk->k_id & 3) << EAPOL_KEY_WPA_KID_SHIFT;
                   1896:        }
                   1897:
                   1898:        /* write the key info field */
                   1899:        BE_WRITE_2(key->info, info);
                   1900:
                   1901:        /* empty key data field */
                   1902:        m->m_pkthdr.len = m->m_len = sizeof(*key);
                   1903:
                   1904:        if (ic->ic_if.if_flags & IFF_DEBUG)
                   1905:                printf("%s: sending msg %d/%d of the %s handshake to %s\n",
                   1906:                    ic->ic_if.if_xname, 2, 2, "group key",
                   1907:                    ether_sprintf(ni->ni_macaddr));
                   1908:
                   1909:        return ieee80211_send_eapol_key(ic, m, ni);
                   1910: }
                   1911:
                   1912: /*
                   1913:  * EAPOL-Key Request frames are sent by the supplicant to request that the
                   1914:  * authenticator initiate either a 4-Way Handshake or Group Key Handshake
                   1915:  * and to report a MIC failure in a TKIP MSDU.
                   1916:  */
                   1917: int
                   1918: ieee80211_send_eapol_key_req(struct ieee80211com *ic,
                   1919:     struct ieee80211_node *ni, u_int16_t info, u_int64_t tsc)
                   1920: {
                   1921:        struct ieee80211_eapol_key *key;
                   1922:        struct mbuf *m;
                   1923:
                   1924:        m = ieee80211_get_eapol_key(M_DONTWAIT, MT_DATA, 0);
                   1925:        if (m == NULL)
                   1926:                return ENOMEM;
                   1927:        key = mtod(m, struct ieee80211_eapol_key *);
                   1928:        memset(key, 0, sizeof(*key));
                   1929:
                   1930:        BE_WRITE_2(key->info, info);
                   1931:
                   1932:        /* in case of TKIP MIC failure, fill the RSC field */
                   1933:        if (info & EAPOL_KEY_ERROR)
                   1934:                LE_WRITE_8(key->rsc, tsc);
                   1935:
                   1936:        /* use our separate key replay counter for key requests */
                   1937:        BE_WRITE_8(key->replaycnt, ic->ic_keyreplaycnt);
                   1938:        ic->ic_keyreplaycnt++;
                   1939:
                   1940:        if (ic->ic_if.if_flags & IFF_DEBUG)
                   1941:                printf("%s: sending EAPOL-Key request to %s\n",
                   1942:                    ic->ic_if.if_xname, ether_sprintf(ni->ni_macaddr));
                   1943:
                   1944:        return ieee80211_send_eapol_key(ic, m, ni);
                   1945: }
                   1946:
                   1947: void
                   1948: ieee80211_pwrsave(struct ieee80211com *ic, struct ieee80211_node *ni,
                   1949:     struct mbuf *m)
                   1950: {
                   1951:        /* store the new packet on our queue, changing the TIM if necessary */
                   1952:        if (IF_IS_EMPTY(&ni->ni_savedq))
                   1953:                (*ic->ic_set_tim)(ic, ni->ni_associd, 1);
                   1954:
                   1955:        if (ni->ni_savedq.ifq_len >= IEEE80211_PS_MAX_QUEUE) {
                   1956:                IF_DROP(&ni->ni_savedq);
                   1957:                m_freem(m);
                   1958:                if (ic->ic_if.if_flags & IFF_DEBUG)
                   1959:                        printf("%s: station %s power save queue overflow"
                   1960:                            " of size %d drops %d\n",
                   1961:                            ic->ic_if.if_xname,
                   1962:                            ether_sprintf(ni->ni_macaddr),
                   1963:                            IEEE80211_PS_MAX_QUEUE,
                   1964:                            ni->ni_savedq.ifq_drops);
                   1965:        } else {
                   1966:                /*
                   1967:                 * Similar to ieee80211_mgmt_output, store the node in
                   1968:                 * the rcvif field.
                   1969:                 */
                   1970:                IF_ENQUEUE(&ni->ni_savedq, m);
                   1971:                m->m_pkthdr.rcvif = (void *)ni;
                   1972:        }
                   1973: }

CVSweb