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


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

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

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2001 Atsushi Onoe
    3  * Copyright (c) 2002, 2003 Sam Leffler, Errno Consulting
    4  * All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions
    8  * are met:
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  * 3. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission.
   16  *
   17  * Alternatively, this software may be distributed under the terms of the
   18  * GNU General Public License ("GPL") version 2 as published by the Free
   19  * Software Foundation.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 /*
   37  * IEEE 802.11 protocol support.
   38  */
   39 
   40 #include "opt_inet.h"
   41 
   42 #include <sys/param.h>
   43 #include <sys/systm.h> 
   44 #include <sys/mbuf.h>   
   45 #include <sys/malloc.h>
   46 #include <sys/kernel.h>
   47 #include <sys/socket.h>
   48 #include <sys/sockio.h>
   49 #include <sys/endian.h>
   50 #include <sys/errno.h>
   51 #include <sys/bus.h>
   52 #include <sys/proc.h>
   53 #include <sys/sysctl.h>
   54 
   55 #include <machine/atomic.h>
   56  
   57 #include <net/if.h>
   58 #include <net/if_dl.h>
   59 #include <net/if_media.h>
   60 #include <net/if_arp.h>
   61 #include <net/ethernet.h>
   62 #include <net/if_llc.h>
   63 
   64 #include <net80211/ieee80211_var.h>
   65 
   66 #include <net/bpf.h>
   67 
   68 #ifdef INET
   69 #include <netinet/in.h> 
   70 #include <netinet/if_ether.h>
   71 #endif
   72 
   73 #define IEEE80211_RATE2MBS(r)   (((r) & IEEE80211_RATE_VAL) / 2)
   74 
   75 const char *ieee80211_mgt_subtype_name[] = {
   76         "assoc_req",    "assoc_resp",   "reassoc_req",  "reassoc_resp",
   77         "probe_req",    "probe_resp",   "reserved#6",   "reserved#7",
   78         "beacon",       "atim",         "disassoc",     "auth",
   79         "deauth",       "reserved#13",  "reserved#14",  "reserved#15"
   80 };
   81 const char *ieee80211_state_name[IEEE80211_S_MAX] = {
   82         "INIT",         /* IEEE80211_S_INIT */
   83         "SCAN",         /* IEEE80211_S_SCAN */
   84         "AUTH",         /* IEEE80211_S_AUTH */
   85         "ASSOC",        /* IEEE80211_S_ASSOC */
   86         "RUN"           /* IEEE80211_S_RUN */
   87 };
   88 
   89 static int ieee80211_newstate(struct ieee80211com *, enum ieee80211_state, int);
   90 
   91 void
   92 ieee80211_proto_attach(struct ifnet *ifp)
   93 {
   94         struct ieee80211com *ic = (void *)ifp;
   95 
   96         ifp->if_hdrlen = sizeof(struct ieee80211_frame);
   97 
   98 #ifdef notdef
   99         ic->ic_rtsthreshold = IEEE80211_RTS_DEFAULT;
  100 #else
  101         ic->ic_rtsthreshold = IEEE80211_RTS_MAX;
  102 #endif
  103         ic->ic_fragthreshold = 2346;            /* XXX not used yet */
  104         ic->ic_fixed_rate = -1;                 /* no fixed rate */
  105         ic->ic_protmode = IEEE80211_PROT_CTSONLY;
  106 
  107         mtx_init(&ic->ic_mgtq.ifq_mtx, ifp->if_xname, "mgmt send q", MTX_DEF);
  108 
  109         /* protocol state change handler */
  110         ic->ic_newstate = ieee80211_newstate;
  111 
  112         /* initialize management frame handlers */
  113         ic->ic_recv_mgmt = ieee80211_recv_mgmt;
  114         ic->ic_send_mgmt = ieee80211_send_mgmt;
  115 }
  116 
  117 void
  118 ieee80211_proto_detach(struct ifnet *ifp)
  119 {
  120         struct ieee80211com *ic = (void *)ifp;
  121 
  122         IF_DRAIN(&ic->ic_mgtq);
  123         mtx_destroy(&ic->ic_mgtq.ifq_mtx);
  124 }
  125 
  126 void
  127 ieee80211_print_essid(u_int8_t *essid, int len)
  128 {
  129         int i;
  130         u_int8_t *p; 
  131 
  132         if (len > IEEE80211_NWID_LEN)
  133                 len = IEEE80211_NWID_LEN;
  134         /* determine printable or not */
  135         for (i = 0, p = essid; i < len; i++, p++) {
  136                 if (*p < ' ' || *p > 0x7e)
  137                         break;
  138         }
  139         if (i == len) {
  140                 printf("\"");
  141                 for (i = 0, p = essid; i < len; i++, p++)
  142                         printf("%c", *p);
  143                 printf("\"");
  144         } else {
  145                 printf("0x");
  146                 for (i = 0, p = essid; i < len; i++, p++)
  147                         printf("%02x", *p);
  148         }
  149 }
  150 
  151 void
  152 ieee80211_dump_pkt(u_int8_t *buf, int len, int rate, int rssi)
  153 {
  154         struct ieee80211_frame *wh;
  155         int i;
  156 
  157         wh = (struct ieee80211_frame *)buf;
  158         switch (wh->i_fc[1] & IEEE80211_FC1_DIR_MASK) {
  159         case IEEE80211_FC1_DIR_NODS:
  160                 printf("NODS %s", ether_sprintf(wh->i_addr2));
  161                 printf("->%s", ether_sprintf(wh->i_addr1));
  162                 printf("(%s)", ether_sprintf(wh->i_addr3));
  163                 break;
  164         case IEEE80211_FC1_DIR_TODS:
  165                 printf("TODS %s", ether_sprintf(wh->i_addr2));
  166                 printf("->%s", ether_sprintf(wh->i_addr3));
  167                 printf("(%s)", ether_sprintf(wh->i_addr1));
  168                 break;
  169         case IEEE80211_FC1_DIR_FROMDS:
  170                 printf("FRDS %s", ether_sprintf(wh->i_addr3));
  171                 printf("->%s", ether_sprintf(wh->i_addr1));
  172                 printf("(%s)", ether_sprintf(wh->i_addr2));
  173                 break;
  174         case IEEE80211_FC1_DIR_DSTODS:
  175                 printf("DSDS %s", ether_sprintf((u_int8_t *)&wh[1]));
  176                 printf("->%s", ether_sprintf(wh->i_addr3));
  177                 printf("(%s", ether_sprintf(wh->i_addr2));
  178                 printf("->%s)", ether_sprintf(wh->i_addr1));
  179                 break;
  180         }
  181         switch (wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) {
  182         case IEEE80211_FC0_TYPE_DATA:
  183                 printf(" data");
  184                 break;
  185         case IEEE80211_FC0_TYPE_MGT:
  186                 printf(" %s", ieee80211_mgt_subtype_name[
  187                     (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK)
  188                     >> IEEE80211_FC0_SUBTYPE_SHIFT]);
  189                 break;
  190         default:
  191                 printf(" type#%d", wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK);
  192                 break;
  193         }
  194         if (wh->i_fc[1] & IEEE80211_FC1_WEP)
  195                 printf(" WEP");
  196         if (rate >= 0)
  197                 printf(" %dM", rate / 2);
  198         if (rssi >= 0)
  199                 printf(" +%d", rssi);
  200         printf("\n");
  201         if (len > 0) {
  202                 for (i = 0; i < len; i++) {
  203                         if ((i & 1) == 0)
  204                                 printf(" ");
  205                         printf("%02x", buf[i]);
  206                 }
  207                 printf("\n");
  208         }
  209 }
  210 
  211 int
  212 ieee80211_fix_rate(struct ieee80211com *ic, struct ieee80211_node *ni, int flags)
  213 {
  214 #define RV(v)   ((v) & IEEE80211_RATE_VAL)
  215         int i, j, ignore, error;
  216         int okrate, badrate;
  217         struct ieee80211_rateset *srs, *nrs;
  218         u_int8_t r;
  219 
  220         error = 0;
  221         okrate = badrate = 0;
  222         srs = &ic->ic_sup_rates[ieee80211_chan2mode(ic, ni->ni_chan)];
  223         nrs = &ni->ni_rates;
  224         for (i = 0; i < nrs->rs_nrates; ) {
  225                 ignore = 0;
  226                 if (flags & IEEE80211_F_DOSORT) {
  227                         /*
  228                          * Sort rates.
  229                          */
  230                         for (j = i + 1; j < nrs->rs_nrates; j++) {
  231                                 if (RV(nrs->rs_rates[i]) > RV(nrs->rs_rates[j])) {
  232                                         r = nrs->rs_rates[i];
  233                                         nrs->rs_rates[i] = nrs->rs_rates[j];
  234                                         nrs->rs_rates[j] = r;
  235                                 }
  236                         }
  237                 }
  238                 r = nrs->rs_rates[i] & IEEE80211_RATE_VAL;
  239                 badrate = r;
  240                 if (flags & IEEE80211_F_DOFRATE) {
  241                         /*
  242                          * Apply fixed rate constraint.  Note that we do
  243                          * not apply the constraint to basic rates as
  244                          * otherwise we may not be able to associate if
  245                          * the rate set we submit to the AP is invalid
  246                          * (e.g. fix rate at 36Mb/s which is not a basic
  247                          * rate for 11a operation).
  248                          */
  249                         if ((nrs->rs_rates[i] & IEEE80211_RATE_BASIC) == 0 &&
  250                             ic->ic_fixed_rate >= 0 &&
  251                             r != RV(srs->rs_rates[ic->ic_fixed_rate]))
  252                                 ignore++;
  253                 }
  254                 if (flags & IEEE80211_F_DONEGO) {
  255                         /*
  256                          * Check against supported rates.
  257                          */
  258                         for (j = 0; j < srs->rs_nrates; j++) {
  259                                 if (r == RV(srs->rs_rates[j])) {
  260                                         /*
  261                                          * Overwrite with the supported rate
  262                                          * value so any basic rate bit is set.
  263                                          * This insures that response we send
  264                                          * to stations have the necessary basic
  265                                          * rate bit set.
  266                                          */
  267                                         nrs->rs_rates[i] = srs->rs_rates[j];
  268                                         break;
  269                                 }
  270                         }
  271                         if (j == srs->rs_nrates) {
  272                                 /*
  273                                  * A rate in the node's rate set is not
  274                                  * supported.  If this is a basic rate and we
  275                                  * are operating as an AP then this is an error.
  276                                  * Otherwise we just discard/ignore the rate.
  277                                  * Note that this is important for 11b stations
  278                                  * when they want to associate with an 11g AP.
  279                                  */
  280                                 if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
  281                                     (nrs->rs_rates[i] & IEEE80211_RATE_BASIC))
  282                                         error++;
  283                                 ignore++;
  284                         }
  285                 }
  286                 if (flags & IEEE80211_F_DODEL) {
  287                         /*
  288                          * Delete unacceptable rates.
  289                          */
  290                         if (ignore) {
  291                                 nrs->rs_nrates--;
  292                                 for (j = i; j < nrs->rs_nrates; j++)
  293                                         nrs->rs_rates[j] = nrs->rs_rates[j + 1];
  294                                 nrs->rs_rates[j] = 0;
  295                                 continue;
  296                         }
  297                 }
  298                 if (!ignore)
  299                         okrate = nrs->rs_rates[i];
  300                 i++;
  301         }
  302         if (okrate == 0 || error != 0)
  303                 return badrate | IEEE80211_RATE_BASIC;
  304         else
  305                 return RV(okrate);
  306 #undef RV
  307 }
  308 
  309 static int
  310 ieee80211_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int mgt)
  311 {
  312         struct ifnet *ifp = &ic->ic_if;
  313         struct ieee80211_node *ni;
  314         enum ieee80211_state ostate;
  315 
  316         ostate = ic->ic_state;
  317         IEEE80211_DPRINTF(("%s: %s -> %s\n", __func__,
  318                 ieee80211_state_name[ostate], ieee80211_state_name[nstate]));
  319         ic->ic_state = nstate;                  /* state transition */
  320         ni = ic->ic_bss;                        /* NB: no reference held */
  321         switch (nstate) {
  322         case IEEE80211_S_INIT:
  323                 switch (ostate) {
  324                 case IEEE80211_S_INIT:
  325                         break;
  326                 case IEEE80211_S_RUN:
  327                         switch (ic->ic_opmode) {
  328                         case IEEE80211_M_STA:
  329                                 IEEE80211_SEND_MGMT(ic, ni,
  330                                     IEEE80211_FC0_SUBTYPE_DISASSOC,
  331                                     IEEE80211_REASON_ASSOC_LEAVE);
  332                                 break;
  333                         case IEEE80211_M_HOSTAP:
  334                                 IEEE80211_NODE_LOCK(ic);
  335                                 TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
  336                                         if (ni->ni_associd == 0)
  337                                                 continue;
  338                                         IEEE80211_SEND_MGMT(ic, ni,
  339                                             IEEE80211_FC0_SUBTYPE_DISASSOC,
  340                                             IEEE80211_REASON_ASSOC_LEAVE);
  341                                 }
  342                                 IEEE80211_NODE_UNLOCK(ic);
  343                                 break;
  344                         default:
  345                                 break;
  346                         }
  347                         /* FALLTHRU */
  348                 case IEEE80211_S_ASSOC:
  349                         switch (ic->ic_opmode) {
  350                         case IEEE80211_M_STA:
  351                                 IEEE80211_SEND_MGMT(ic, ni,
  352                                     IEEE80211_FC0_SUBTYPE_DEAUTH,
  353                                     IEEE80211_REASON_AUTH_LEAVE);
  354                                 break;
  355                         case IEEE80211_M_HOSTAP:
  356                                 IEEE80211_NODE_LOCK(ic);
  357                                 TAILQ_FOREACH(ni, &ic->ic_node, ni_list) {
  358                                         IEEE80211_SEND_MGMT(ic, ni,
  359                                             IEEE80211_FC0_SUBTYPE_DEAUTH,
  360                                             IEEE80211_REASON_AUTH_LEAVE);
  361                                 }
  362                                 IEEE80211_NODE_UNLOCK(ic);
  363                                 break;
  364                         default:
  365                                 break;
  366                         }
  367                         /* FALLTHRU */
  368                 case IEEE80211_S_AUTH:
  369                 case IEEE80211_S_SCAN:
  370                         ic->ic_mgt_timer = 0;
  371                         IF_DRAIN(&ic->ic_mgtq);
  372                         if (ic->ic_wep_ctx != NULL) {
  373                                 free(ic->ic_wep_ctx, M_DEVBUF);
  374                                 ic->ic_wep_ctx = NULL;
  375                         }
  376                         ieee80211_free_allnodes(ic);
  377                         break;
  378                 }
  379                 break;
  380         case IEEE80211_S_SCAN:
  381                 ic->ic_flags &= ~IEEE80211_F_SIBSS;
  382                 /* initialize bss for probe request */
  383                 IEEE80211_ADDR_COPY(ni->ni_macaddr, ifp->if_broadcastaddr);
  384                 IEEE80211_ADDR_COPY(ni->ni_bssid, ifp->if_broadcastaddr);
  385                 ni->ni_rates = ic->ic_sup_rates[
  386                         ieee80211_chan2mode(ic, ni->ni_chan)];
  387                 ni->ni_associd = 0;
  388                 ni->ni_rstamp = 0;
  389                 switch (ostate) {
  390                 case IEEE80211_S_INIT:
  391                         if (ic->ic_opmode == IEEE80211_M_HOSTAP &&
  392                             ic->ic_des_chan != IEEE80211_CHAN_ANYC) {
  393                                 /*
  394                                  * AP operation and we already have a channel;
  395                                  * bypass the scan and startup immediately.
  396                                  */
  397                                 ieee80211_create_ibss(ic, ic->ic_des_chan);
  398                         } else {
  399                                 ieee80211_begin_scan(ifp);
  400                         }
  401                         break;
  402                 case IEEE80211_S_SCAN:
  403                         /* scan next */
  404                         if (ic->ic_flags & IEEE80211_F_ASCAN) {
  405                                 IEEE80211_SEND_MGMT(ic, ni,
  406                                     IEEE80211_FC0_SUBTYPE_PROBE_REQ, 0);
  407                         }
  408                         break;
  409                 case IEEE80211_S_RUN:
  410                         /* beacon miss */
  411                         if (ifp->if_flags & IFF_DEBUG) {
  412                                 /* XXX bssid clobbered above */
  413                                 if_printf(ifp, "no recent beacons from %s;"
  414                                     " rescanning\n",
  415                                     ether_sprintf(ic->ic_bss->ni_bssid));
  416                         }
  417                         ieee80211_free_allnodes(ic);
  418                         /* FALLTHRU */
  419                 case IEEE80211_S_AUTH:
  420                 case IEEE80211_S_ASSOC:
  421                         /* timeout restart scan */
  422                         ni = ieee80211_find_node(ic, ic->ic_bss->ni_macaddr);
  423                         if (ni != NULL) {
  424                                 ni->ni_fails++;
  425                                 ieee80211_unref_node(&ni);
  426                         }
  427                         ieee80211_begin_scan(ifp);
  428                         break;
  429                 }
  430                 break;
  431         case IEEE80211_S_AUTH:
  432                 switch (ostate) {
  433                 case IEEE80211_S_INIT:
  434                         IEEE80211_DPRINTF(("%s: invalid transition\n",
  435                                 __func__));
  436                         break;
  437                 case IEEE80211_S_SCAN:
  438                         IEEE80211_SEND_MGMT(ic, ni,
  439                             IEEE80211_FC0_SUBTYPE_AUTH, 1);
  440                         break;
  441                 case IEEE80211_S_AUTH:
  442                 case IEEE80211_S_ASSOC:
  443                         switch (mgt) {
  444                         case IEEE80211_FC0_SUBTYPE_AUTH:
  445                                 /* ??? */
  446                                 IEEE80211_SEND_MGMT(ic, ni,
  447                                     IEEE80211_FC0_SUBTYPE_AUTH, 2);
  448                                 break;
  449                         case IEEE80211_FC0_SUBTYPE_DEAUTH:
  450                                 /* ignore and retry scan on timeout */
  451                                 break;
  452                         }
  453                         break;
  454                 case IEEE80211_S_RUN:
  455                         switch (mgt) {
  456                         case IEEE80211_FC0_SUBTYPE_AUTH:
  457                                 IEEE80211_SEND_MGMT(ic, ni,
  458                                     IEEE80211_FC0_SUBTYPE_AUTH, 2);
  459                                 ic->ic_state = ostate;  /* stay RUN */
  460                                 break;
  461                         case IEEE80211_FC0_SUBTYPE_DEAUTH:
  462                                 /* try to reauth */
  463                                 IEEE80211_SEND_MGMT(ic, ni,
  464                                     IEEE80211_FC0_SUBTYPE_AUTH, 1);
  465                                 break;
  466                         }
  467                         break;
  468                 }
  469                 break;
  470         case IEEE80211_S_ASSOC:
  471                 switch (ostate) {
  472                 case IEEE80211_S_INIT:
  473                 case IEEE80211_S_SCAN:
  474                 case IEEE80211_S_ASSOC:
  475                         IEEE80211_DPRINTF(("%s: invalid transition\n",
  476                                 __func__));
  477                         break;
  478                 case IEEE80211_S_AUTH:
  479                         IEEE80211_SEND_MGMT(ic, ni,
  480                             IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 0);
  481                         break;
  482                 case IEEE80211_S_RUN:
  483                         IEEE80211_SEND_MGMT(ic, ni,
  484                             IEEE80211_FC0_SUBTYPE_ASSOC_REQ, 1);
  485                         break;
  486                 }
  487                 break;
  488         case IEEE80211_S_RUN:
  489                 switch (ostate) {
  490                 case IEEE80211_S_INIT:
  491                 case IEEE80211_S_AUTH:
  492                 case IEEE80211_S_RUN:
  493                         IEEE80211_DPRINTF(("%s: invalid transition\n",
  494                                 __func__));
  495                         break;
  496                 case IEEE80211_S_SCAN:          /* adhoc/hostap mode */
  497                 case IEEE80211_S_ASSOC:         /* infra mode */
  498                         KASSERT(ni->ni_txrate < ni->ni_rates.rs_nrates,
  499                                 ("%s: bogus xmit rate %u setup\n", __func__,
  500                                         ni->ni_txrate));
  501                         if (ifp->if_flags & IFF_DEBUG) {
  502                                 if_printf(ifp, " ");
  503                                 if (ic->ic_opmode == IEEE80211_M_STA)
  504                                         printf("associated ");
  505                                 else
  506                                         printf("synchronized ");
  507                                 printf("with %s ssid ",
  508                                     ether_sprintf(ni->ni_bssid));
  509                                 ieee80211_print_essid(ic->ic_bss->ni_essid,
  510                                     ni->ni_esslen);
  511                                 printf(" channel %d start %uMb\n",
  512                                         ieee80211_chan2ieee(ic, ni->ni_chan),
  513                                         IEEE80211_RATE2MBS(ni->ni_rates.rs_rates[ni->ni_txrate]));
  514                         }
  515                         ic->ic_mgt_timer = 0;
  516                         if_start(ifp);
  517                         break;
  518                 }
  519                 break;
  520         }
  521         return 0;
  522 }

Cache object: beeef53f43588e5b3ec9deadb7cf4a09


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


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