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_adhoc.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) 2007-2009 Sam Leffler, Errno Consulting
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   24  */
   25 
   26 #include <sys/cdefs.h>
   27 #ifdef __FreeBSD__
   28 __FBSDID("$FreeBSD: releng/11.0/sys/net80211/ieee80211_adhoc.c 302202 2016-06-25 20:31:20Z adrian $");
   29 #endif
   30 
   31 /*
   32  * IEEE 802.11 IBSS mode support.
   33  */
   34 #include "opt_inet.h"
   35 #include "opt_wlan.h"
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h> 
   39 #include <sys/mbuf.h>   
   40 #include <sys/malloc.h>
   41 #include <sys/kernel.h>
   42 
   43 #include <sys/socket.h>
   44 #include <sys/sockio.h>
   45 #include <sys/endian.h>
   46 #include <sys/errno.h>
   47 #include <sys/proc.h>
   48 #include <sys/sysctl.h>
   49 
   50 #include <net/if.h>
   51 #include <net/if_var.h>
   52 #include <net/if_media.h>
   53 #include <net/if_llc.h>
   54 #include <net/ethernet.h>
   55 
   56 #include <net/bpf.h>
   57 
   58 #include <net80211/ieee80211_var.h>
   59 #include <net80211/ieee80211_adhoc.h>
   60 #include <net80211/ieee80211_input.h>
   61 #ifdef IEEE80211_SUPPORT_SUPERG
   62 #include <net80211/ieee80211_superg.h>
   63 #endif
   64 #ifdef IEEE80211_SUPPORT_TDMA
   65 #include <net80211/ieee80211_tdma.h>
   66 #endif
   67 #include <net80211/ieee80211_sta.h>
   68 
   69 #define IEEE80211_RATE2MBS(r)   (((r) & IEEE80211_RATE_VAL) / 2)
   70 
   71 static  void adhoc_vattach(struct ieee80211vap *);
   72 static  int adhoc_newstate(struct ieee80211vap *, enum ieee80211_state, int);
   73 static int adhoc_input(struct ieee80211_node *, struct mbuf *,
   74             const struct ieee80211_rx_stats *, int, int);
   75 static void adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *,
   76         int subtype, const struct ieee80211_rx_stats *, int, int);
   77 static void ahdemo_recv_mgmt(struct ieee80211_node *, struct mbuf *,
   78             int subtype, const struct ieee80211_rx_stats *rxs, int, int);
   79 static void adhoc_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype);
   80 
   81 void
   82 ieee80211_adhoc_attach(struct ieee80211com *ic)
   83 {
   84         ic->ic_vattach[IEEE80211_M_IBSS] = adhoc_vattach;
   85         ic->ic_vattach[IEEE80211_M_AHDEMO] = adhoc_vattach;
   86 }
   87 
   88 void
   89 ieee80211_adhoc_detach(struct ieee80211com *ic)
   90 {
   91 }
   92 
   93 static void
   94 adhoc_vdetach(struct ieee80211vap *vap)
   95 {
   96 }
   97 
   98 static void
   99 adhoc_vattach(struct ieee80211vap *vap)
  100 {
  101         vap->iv_newstate = adhoc_newstate;
  102         vap->iv_input = adhoc_input;
  103         if (vap->iv_opmode == IEEE80211_M_IBSS)
  104                 vap->iv_recv_mgmt = adhoc_recv_mgmt;
  105         else
  106                 vap->iv_recv_mgmt = ahdemo_recv_mgmt;
  107         vap->iv_recv_ctl = adhoc_recv_ctl;
  108         vap->iv_opdetach = adhoc_vdetach;
  109 #ifdef IEEE80211_SUPPORT_TDMA
  110         /*
  111          * Throw control to tdma support.  Note we do this
  112          * after setting up our callbacks so it can piggyback
  113          * on top of us.
  114          */
  115         if (vap->iv_caps & IEEE80211_C_TDMA)
  116                 ieee80211_tdma_vattach(vap);
  117 #endif
  118 }
  119 
  120 static void
  121 sta_leave(void *arg, struct ieee80211_node *ni)
  122 {
  123         struct ieee80211vap *vap = arg;
  124 
  125         if (ni->ni_vap == vap && ni != vap->iv_bss)
  126                 ieee80211_node_leave(ni);
  127 }
  128 
  129 /*
  130  * IEEE80211_M_IBSS+IEEE80211_M_AHDEMO vap state machine handler.
  131  */
  132 static int
  133 adhoc_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
  134 {
  135         struct ieee80211com *ic = vap->iv_ic;
  136         struct ieee80211_node *ni;
  137         enum ieee80211_state ostate;
  138 
  139         IEEE80211_LOCK_ASSERT(vap->iv_ic);
  140 
  141         ostate = vap->iv_state;
  142         IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE, "%s: %s -> %s (%d)\n",
  143             __func__, ieee80211_state_name[ostate],
  144             ieee80211_state_name[nstate], arg);
  145         vap->iv_state = nstate;                 /* state transition */
  146         if (ostate != IEEE80211_S_SCAN)
  147                 ieee80211_cancel_scan(vap);     /* background scan */
  148         ni = vap->iv_bss;                       /* NB: no reference held */
  149         switch (nstate) {
  150         case IEEE80211_S_INIT:
  151                 switch (ostate) {
  152                 case IEEE80211_S_SCAN:
  153                         ieee80211_cancel_scan(vap);
  154                         break;
  155                 default:
  156                         break;
  157                 }
  158                 if (ostate != IEEE80211_S_INIT) {
  159                         /* NB: optimize INIT -> INIT case */
  160                         ieee80211_reset_bss(vap);
  161                 }
  162                 break;
  163         case IEEE80211_S_SCAN:
  164                 switch (ostate) {
  165                 case IEEE80211_S_RUN:           /* beacon miss */
  166                         /* purge station table; entries are stale */
  167                         ieee80211_iterate_nodes(&ic->ic_sta, sta_leave, vap);
  168                         /* fall thru... */
  169                 case IEEE80211_S_INIT:
  170                         if (vap->iv_des_chan != IEEE80211_CHAN_ANYC &&
  171                             !IEEE80211_IS_CHAN_RADAR(vap->iv_des_chan)) {
  172                                 /*
  173                                  * Already have a channel; bypass the
  174                                  * scan and startup immediately.
  175                                  */
  176                                 ieee80211_create_ibss(vap,
  177                                     ieee80211_ht_adjust_channel(ic,
  178                                     vap->iv_des_chan, vap->iv_flags_ht));
  179                                 break;
  180                         }
  181                         /*
  182                          * Initiate a scan.  We can come here as a result
  183                          * of an IEEE80211_IOC_SCAN_REQ too in which case
  184                          * the vap will be marked with IEEE80211_FEXT_SCANREQ
  185                          * and the scan request parameters will be present
  186                          * in iv_scanreq.  Otherwise we do the default.
  187                          */
  188                         if (vap->iv_flags_ext & IEEE80211_FEXT_SCANREQ) {
  189                                 ieee80211_check_scan(vap,
  190                                     vap->iv_scanreq_flags,
  191                                     vap->iv_scanreq_duration,
  192                                     vap->iv_scanreq_mindwell,
  193                                     vap->iv_scanreq_maxdwell,
  194                                     vap->iv_scanreq_nssid, vap->iv_scanreq_ssid);
  195                                 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCANREQ;
  196                         } else
  197                                 ieee80211_check_scan_current(vap);
  198                         break;
  199                 case IEEE80211_S_SCAN:
  200                         /*
  201                          * This can happen because of a change in state
  202                          * that requires a reset.  Trigger a new scan
  203                          * unless we're in manual roaming mode in which
  204                          * case an application must issue an explicit request.
  205                          */
  206                         if (vap->iv_roaming == IEEE80211_ROAMING_AUTO)
  207                                 ieee80211_check_scan_current(vap);
  208                         break;
  209                 default:
  210                         goto invalid;
  211                 }
  212                 break;
  213         case IEEE80211_S_RUN:
  214                 if (vap->iv_flags & IEEE80211_F_WPA) {
  215                         /* XXX validate prerequisites */
  216                 }
  217                 switch (ostate) {
  218                 case IEEE80211_S_SCAN:
  219 #ifdef IEEE80211_DEBUG
  220                         if (ieee80211_msg_debug(vap)) {
  221                                 ieee80211_note(vap,
  222                                     "synchronized with %s ssid ",
  223                                     ether_sprintf(ni->ni_bssid));
  224                                 ieee80211_print_essid(vap->iv_bss->ni_essid,
  225                                     ni->ni_esslen);
  226                                 /* XXX MCS/HT */
  227                                 printf(" channel %d start %uMb\n",
  228                                     ieee80211_chan2ieee(ic, ic->ic_curchan),
  229                                     IEEE80211_RATE2MBS(ni->ni_txrate));
  230                         }
  231 #endif
  232                         break;
  233                 case IEEE80211_S_RUN:   /* IBSS merge */
  234                         break;
  235                 default:
  236                         goto invalid;
  237                 }
  238                 /*
  239                  * When 802.1x is not in use mark the port authorized
  240                  * at this point so traffic can flow.
  241                  */
  242                 if (ni->ni_authmode != IEEE80211_AUTH_8021X)
  243                         ieee80211_node_authorize(ni);
  244                 /*
  245                  * Fake association when joining an existing bss.
  246                  */
  247                 if (!IEEE80211_ADDR_EQ(ni->ni_macaddr, vap->iv_myaddr) &&
  248                     ic->ic_newassoc != NULL)
  249                         ic->ic_newassoc(ni, ostate != IEEE80211_S_RUN);
  250                 break;
  251         case IEEE80211_S_SLEEP:
  252                 vap->iv_sta_ps(vap, 0);
  253                 break;
  254         default:
  255         invalid:
  256                 IEEE80211_DPRINTF(vap, IEEE80211_MSG_STATE,
  257                     "%s: unexpected state transition %s -> %s\n", __func__,
  258                     ieee80211_state_name[ostate], ieee80211_state_name[nstate]);
  259                 break;
  260         }
  261         return 0;
  262 }
  263 
  264 /*
  265  * Decide if a received management frame should be
  266  * printed when debugging is enabled.  This filters some
  267  * of the less interesting frames that come frequently
  268  * (e.g. beacons).
  269  */
  270 static __inline int
  271 doprint(struct ieee80211vap *vap, int subtype)
  272 {
  273         switch (subtype) {
  274         case IEEE80211_FC0_SUBTYPE_BEACON:
  275                 return (vap->iv_ic->ic_flags & IEEE80211_F_SCAN);
  276         case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
  277                 return 1;
  278         }
  279         return 1;
  280 }
  281 
  282 /*
  283  * Process a received frame.  The node associated with the sender
  284  * should be supplied.  If nothing was found in the node table then
  285  * the caller is assumed to supply a reference to iv_bss instead.
  286  * The RSSI and a timestamp are also supplied.  The RSSI data is used
  287  * during AP scanning to select a AP to associate with; it can have
  288  * any units so long as values have consistent units and higher values
  289  * mean ``better signal''.  The receive timestamp is currently not used
  290  * by the 802.11 layer.
  291  */
  292 static int
  293 adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
  294     const struct ieee80211_rx_stats *rxs, int rssi, int nf)
  295 {
  296         struct ieee80211vap *vap = ni->ni_vap;
  297         struct ieee80211com *ic = ni->ni_ic;
  298         struct ifnet *ifp = vap->iv_ifp;
  299         struct ieee80211_frame *wh;
  300         struct ieee80211_key *key;
  301         struct ether_header *eh;
  302         int hdrspace, need_tap = 1;     /* mbuf need to be tapped. */   
  303         uint8_t dir, type, subtype, qos;
  304         uint8_t *bssid;
  305 
  306         if (m->m_flags & M_AMPDU_MPDU) {
  307                 /*
  308                  * Fastpath for A-MPDU reorder q resubmission.  Frames
  309                  * w/ M_AMPDU_MPDU marked have already passed through
  310                  * here but were received out of order and been held on
  311                  * the reorder queue.  When resubmitted they are marked
  312                  * with the M_AMPDU_MPDU flag and we can bypass most of
  313                  * the normal processing.
  314                  */
  315                 wh = mtod(m, struct ieee80211_frame *);
  316                 type = IEEE80211_FC0_TYPE_DATA;
  317                 dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
  318                 subtype = IEEE80211_FC0_SUBTYPE_QOS;
  319                 hdrspace = ieee80211_hdrspace(ic, wh);  /* XXX optimize? */
  320                 goto resubmit_ampdu;
  321         }
  322 
  323         KASSERT(ni != NULL, ("null node"));
  324         ni->ni_inact = ni->ni_inact_reload;
  325 
  326         type = -1;                      /* undefined */
  327 
  328         if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) {
  329                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
  330                     ni->ni_macaddr, NULL,
  331                     "too short (1): len %u", m->m_pkthdr.len);
  332                 vap->iv_stats.is_rx_tooshort++;
  333                 goto out;
  334         }
  335         /*
  336          * Bit of a cheat here, we use a pointer for a 3-address
  337          * frame format but don't reference fields past outside
  338          * ieee80211_frame_min w/o first validating the data is
  339          * present.
  340          */
  341         wh = mtod(m, struct ieee80211_frame *);
  342 
  343         if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) !=
  344             IEEE80211_FC0_VERSION_0) {
  345                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
  346                     ni->ni_macaddr, NULL, "wrong version, fc %02x:%02x",
  347                     wh->i_fc[0], wh->i_fc[1]);
  348                 vap->iv_stats.is_rx_badversion++;
  349                 goto err;
  350         }
  351 
  352         dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK;
  353         type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
  354         subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
  355         if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
  356                 if (dir != IEEE80211_FC1_DIR_NODS)
  357                         bssid = wh->i_addr1;
  358                 else if (type == IEEE80211_FC0_TYPE_CTL)
  359                         bssid = wh->i_addr1;
  360                 else {
  361                         if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
  362                                 IEEE80211_DISCARD_MAC(vap,
  363                                     IEEE80211_MSG_ANY, ni->ni_macaddr,
  364                                     NULL, "too short (2): len %u",
  365                                     m->m_pkthdr.len);
  366                                 vap->iv_stats.is_rx_tooshort++;
  367                                 goto out;
  368                         }
  369                         bssid = wh->i_addr3;
  370                 }
  371                 /*
  372                  * Validate the bssid.
  373                  */
  374                 if (!(type == IEEE80211_FC0_TYPE_MGT &&
  375                      (subtype == IEEE80211_FC0_SUBTYPE_BEACON ||
  376                       subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP)) &&
  377                     !IEEE80211_ADDR_EQ(bssid, vap->iv_bss->ni_bssid) &&
  378                     !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) {
  379                         /* not interested in */
  380                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
  381                             bssid, NULL, "%s", "not to bss");
  382                         vap->iv_stats.is_rx_wrongbss++;
  383                         goto out;
  384                 }
  385                 /*
  386                  * Data frame, cons up a node when it doesn't
  387                  * exist. This should probably done after an ACL check.
  388                  */
  389                 if (type == IEEE80211_FC0_TYPE_DATA &&
  390                     ni == vap->iv_bss &&
  391                     !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
  392                         /*
  393                          * Beware of frames that come in too early; we
  394                          * can receive broadcast frames and creating sta
  395                          * entries will blow up because there is no bss
  396                          * channel yet.
  397                          */
  398                         if (vap->iv_state != IEEE80211_S_RUN) {
  399                                 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  400                                     wh, "data", "not in RUN state (%s)",
  401                                     ieee80211_state_name[vap->iv_state]);
  402                                 vap->iv_stats.is_rx_badstate++;
  403                                 goto err;
  404                         }
  405                         /*
  406                          * Fake up a node for this newly
  407                          * discovered member of the IBSS.
  408                          */
  409                         ni = ieee80211_fakeup_adhoc_node(vap, wh->i_addr2);
  410                         if (ni == NULL) {
  411                                 /* NB: stat kept for alloc failure */
  412                                 goto err;
  413                         }
  414                 }
  415                 IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
  416                 ni->ni_noise = nf;
  417                 if (IEEE80211_HAS_SEQ(type, subtype) &&
  418                     IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
  419                         uint8_t tid = ieee80211_gettid(wh);
  420                         if (IEEE80211_QOS_HAS_SEQ(wh) &&
  421                             TID_TO_WME_AC(tid) >= WME_AC_VI)
  422                                 ic->ic_wme.wme_hipri_traffic++;
  423                         if (! ieee80211_check_rxseq(ni, wh, bssid))
  424                                 goto out;
  425                 }
  426         }
  427 
  428         switch (type) {
  429         case IEEE80211_FC0_TYPE_DATA:
  430                 hdrspace = ieee80211_hdrspace(ic, wh);
  431                 if (m->m_len < hdrspace &&
  432                     (m = m_pullup(m, hdrspace)) == NULL) {
  433                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
  434                             ni->ni_macaddr, NULL,
  435                             "data too short: expecting %u", hdrspace);
  436                         vap->iv_stats.is_rx_tooshort++;
  437                         goto out;               /* XXX */
  438                 }
  439                 if (dir != IEEE80211_FC1_DIR_NODS) {
  440                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  441                             wh, "data", "incorrect dir 0x%x", dir);
  442                         vap->iv_stats.is_rx_wrongdir++;
  443                         goto out;
  444                 }
  445                 /* XXX no power-save support */
  446 
  447                 /*
  448                  * Handle A-MPDU re-ordering.  If the frame is to be
  449                  * processed directly then ieee80211_ampdu_reorder
  450                  * will return 0; otherwise it has consumed the mbuf
  451                  * and we should do nothing more with it.
  452                  */
  453                 if ((m->m_flags & M_AMPDU) &&
  454                     ieee80211_ampdu_reorder(ni, m) != 0) {
  455                         m = NULL;
  456                         goto out;
  457                 }
  458         resubmit_ampdu:
  459 
  460                 /*
  461                  * Handle privacy requirements.  Note that we
  462                  * must not be preempted from here until after
  463                  * we (potentially) call ieee80211_crypto_demic;
  464                  * otherwise we may violate assumptions in the
  465                  * crypto cipher modules used to do delayed update
  466                  * of replay sequence numbers.
  467                  */
  468                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
  469                         if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) {
  470                                 /*
  471                                  * Discard encrypted frames when privacy is off.
  472                                  */
  473                                 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  474                                     wh, "WEP", "%s", "PRIVACY off");
  475                                 vap->iv_stats.is_rx_noprivacy++;
  476                                 IEEE80211_NODE_STAT(ni, rx_noprivacy);
  477                                 goto out;
  478                         }
  479                         key = ieee80211_crypto_decap(ni, m, hdrspace);
  480                         if (key == NULL) {
  481                                 /* NB: stats+msgs handled in crypto_decap */
  482                                 IEEE80211_NODE_STAT(ni, rx_wepfail);
  483                                 goto out;
  484                         }
  485                         wh = mtod(m, struct ieee80211_frame *);
  486                         wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
  487                 } else {
  488                         /* XXX M_WEP and IEEE80211_F_PRIVACY */
  489                         key = NULL;
  490                 }
  491 
  492                 /*
  493                  * Save QoS bits for use below--before we strip the header.
  494                  */
  495                 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
  496                         qos = (dir == IEEE80211_FC1_DIR_DSTODS) ?
  497                             ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] :
  498                             ((struct ieee80211_qosframe *)wh)->i_qos[0];
  499                 } else
  500                         qos = 0;
  501 
  502                 /*
  503                  * Next up, any fragmentation.
  504                  */
  505                 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
  506                         m = ieee80211_defrag(ni, m, hdrspace);
  507                         if (m == NULL) {
  508                                 /* Fragment dropped or frame not complete yet */
  509                                 goto out;
  510                         }
  511                 }
  512                 wh = NULL;              /* no longer valid, catch any uses */
  513 
  514                 /*
  515                  * Next strip any MSDU crypto bits.
  516                  */
  517                 if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) {
  518                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
  519                             ni->ni_macaddr, "data", "%s", "demic error");
  520                         vap->iv_stats.is_rx_demicfail++;
  521                         IEEE80211_NODE_STAT(ni, rx_demicfail);
  522                         goto out;
  523                 }
  524 
  525                 /* copy to listener after decrypt */
  526                 if (ieee80211_radiotap_active_vap(vap))
  527                         ieee80211_radiotap_rx(vap, m);
  528                 need_tap = 0;
  529 
  530                 /*
  531                  * Finally, strip the 802.11 header.
  532                  */
  533                 m = ieee80211_decap(vap, m, hdrspace);
  534                 if (m == NULL) {
  535                         /* XXX mask bit to check for both */
  536                         /* don't count Null data frames as errors */
  537                         if (subtype == IEEE80211_FC0_SUBTYPE_NODATA ||
  538                             subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL)
  539                                 goto out;
  540                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
  541                             ni->ni_macaddr, "data", "%s", "decap error");
  542                         vap->iv_stats.is_rx_decap++;
  543                         IEEE80211_NODE_STAT(ni, rx_decap);
  544                         goto err;
  545                 }
  546                 eh = mtod(m, struct ether_header *);
  547                 if (!ieee80211_node_is_authorized(ni)) {
  548                         /*
  549                          * Deny any non-PAE frames received prior to
  550                          * authorization.  For open/shared-key
  551                          * authentication the port is mark authorized
  552                          * after authentication completes.  For 802.1x
  553                          * the port is not marked authorized by the
  554                          * authenticator until the handshake has completed.
  555                          */
  556                         if (eh->ether_type != htons(ETHERTYPE_PAE)) {
  557                                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
  558                                     eh->ether_shost, "data",
  559                                     "unauthorized port: ether type 0x%x len %u",
  560                                     eh->ether_type, m->m_pkthdr.len);
  561                                 vap->iv_stats.is_rx_unauth++;
  562                                 IEEE80211_NODE_STAT(ni, rx_unauth);
  563                                 goto err;
  564                         }
  565                 } else {
  566                         /*
  567                          * When denying unencrypted frames, discard
  568                          * any non-PAE frames received without encryption.
  569                          */
  570                         if ((vap->iv_flags & IEEE80211_F_DROPUNENC) &&
  571                             (key == NULL && (m->m_flags & M_WEP) == 0) &&
  572                             eh->ether_type != htons(ETHERTYPE_PAE)) {
  573                                 /*
  574                                  * Drop unencrypted frames.
  575                                  */
  576                                 vap->iv_stats.is_rx_unencrypted++;
  577                                 IEEE80211_NODE_STAT(ni, rx_unencrypted);
  578                                 goto out;
  579                         }
  580                 }
  581                 /* XXX require HT? */
  582                 if (qos & IEEE80211_QOS_AMSDU) {
  583                         m = ieee80211_decap_amsdu(ni, m);
  584                         if (m == NULL)
  585                                 return IEEE80211_FC0_TYPE_DATA;
  586                 } else {
  587 #ifdef IEEE80211_SUPPORT_SUPERG
  588                         m = ieee80211_decap_fastframe(vap, ni, m);
  589                         if (m == NULL)
  590                                 return IEEE80211_FC0_TYPE_DATA;
  591 #endif
  592                 }
  593                 if (dir == IEEE80211_FC1_DIR_DSTODS && ni->ni_wdsvap != NULL)
  594                         ieee80211_deliver_data(ni->ni_wdsvap, ni, m);
  595                 else
  596                         ieee80211_deliver_data(vap, ni, m);
  597                 return IEEE80211_FC0_TYPE_DATA;
  598 
  599         case IEEE80211_FC0_TYPE_MGT:
  600                 vap->iv_stats.is_rx_mgmt++;
  601                 IEEE80211_NODE_STAT(ni, rx_mgmt);
  602                 if (dir != IEEE80211_FC1_DIR_NODS) {
  603                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  604                             wh, "data", "incorrect dir 0x%x", dir);
  605                         vap->iv_stats.is_rx_wrongdir++;
  606                         goto err;
  607                 }
  608                 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
  609                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
  610                             ni->ni_macaddr, "mgt", "too short: len %u",
  611                             m->m_pkthdr.len);
  612                         vap->iv_stats.is_rx_tooshort++;
  613                         goto out;
  614                 }
  615 #ifdef IEEE80211_DEBUG
  616                 if ((ieee80211_msg_debug(vap) && doprint(vap, subtype)) ||
  617                     ieee80211_msg_dumppkts(vap)) {
  618                         if_printf(ifp, "received %s from %s rssi %d\n",
  619                             ieee80211_mgt_subtype_name(subtype),
  620                             ether_sprintf(wh->i_addr2), rssi);
  621                 }
  622 #endif
  623                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
  624                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  625                             wh, NULL, "%s", "WEP set but not permitted");
  626                         vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
  627                         goto out;
  628                 }
  629                 vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
  630                 goto out;
  631 
  632         case IEEE80211_FC0_TYPE_CTL:
  633                 vap->iv_stats.is_rx_ctl++;
  634                 IEEE80211_NODE_STAT(ni, rx_ctrl);
  635                 vap->iv_recv_ctl(ni, m, subtype);
  636                 goto out;
  637 
  638         default:
  639                 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
  640                     wh, "bad", "frame type 0x%x", type);
  641                 /* should not come here */
  642                 break;
  643         }
  644 err:
  645         if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
  646 out:
  647         if (m != NULL) {
  648                 if (need_tap && ieee80211_radiotap_active_vap(vap))
  649                         ieee80211_radiotap_rx(vap, m);
  650                 m_freem(m);
  651         }
  652         return type;
  653 }
  654 
  655 static int
  656 is11bclient(const uint8_t *rates, const uint8_t *xrates)
  657 {
  658         static const uint32_t brates = (1<<2*1)|(1<<2*2)|(1<<11)|(1<<2*11);
  659         int i;
  660 
  661         /* NB: the 11b clients we care about will not have xrates */
  662         if (xrates != NULL || rates == NULL)
  663                 return 0;
  664         for (i = 0; i < rates[1]; i++) {
  665                 int r = rates[2+i] & IEEE80211_RATE_VAL;
  666                 if (r > 2*11 || ((1<<r) & brates) == 0)
  667                         return 0;
  668         }
  669         return 1;
  670 }
  671 
  672 static void
  673 adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
  674         int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
  675 {
  676         struct ieee80211vap *vap = ni->ni_vap;
  677         struct ieee80211com *ic = ni->ni_ic;
  678         struct ieee80211_channel *rxchan = ic->ic_curchan;
  679         struct ieee80211_frame *wh;
  680         uint8_t *frm, *efrm;
  681         uint8_t *ssid, *rates, *xrates;
  682 #if 0
  683         int ht_state_change = 0;
  684 #endif
  685 
  686         wh = mtod(m0, struct ieee80211_frame *);
  687         frm = (uint8_t *)&wh[1];
  688         efrm = mtod(m0, uint8_t *) + m0->m_len;
  689         switch (subtype) {
  690         case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
  691         case IEEE80211_FC0_SUBTYPE_BEACON: {
  692                 struct ieee80211_scanparams scan;
  693                 struct ieee80211_channel *c;
  694                 /*
  695                  * We process beacon/probe response
  696                  * frames to discover neighbors.
  697                  */ 
  698                 if (rxs != NULL) {
  699                         c = ieee80211_lookup_channel_rxstatus(vap, rxs);
  700                         if (c != NULL)
  701                                 rxchan = c;
  702                 }
  703                 if (ieee80211_parse_beacon(ni, m0, rxchan, &scan) != 0)
  704                         return;
  705                 /*
  706                  * Count frame now that we know it's to be processed.
  707                  */
  708                 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
  709                         vap->iv_stats.is_rx_beacon++;           /* XXX remove */
  710                         IEEE80211_NODE_STAT(ni, rx_beacons);
  711                 } else
  712                         IEEE80211_NODE_STAT(ni, rx_proberesp);
  713                 /*
  714                  * If scanning, just pass information to the scan module.
  715                  */
  716                 if (ic->ic_flags & IEEE80211_F_SCAN) {
  717                         if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) {
  718                                 /*
  719                                  * Actively scanning a channel marked passive;
  720                                  * send a probe request now that we know there
  721                                  * is 802.11 traffic present.
  722                                  *
  723                                  * XXX check if the beacon we recv'd gives
  724                                  * us what we need and suppress the probe req
  725                                  */
  726                                 ieee80211_probe_curchan(vap, 1);
  727                                 ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
  728                         }
  729                         ieee80211_add_scan(vap, rxchan, &scan, wh,
  730                             subtype, rssi, nf);
  731                         return;
  732                 }
  733                 if (scan.capinfo & IEEE80211_CAPINFO_IBSS) {
  734                         if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
  735                                 /*
  736                                  * Create a new entry in the neighbor table.
  737                                  */
  738                                 ni = ieee80211_add_neighbor(vap, wh, &scan);
  739                         } else if (ni->ni_capinfo == 0) {
  740                                 /*
  741                                  * Update faked node created on transmit.
  742                                  * Note this also updates the tsf.
  743                                  */
  744                                 ieee80211_init_neighbor(ni, wh, &scan);
  745                         } else {
  746                                 /*
  747                                  * Record tsf for potential resync.
  748                                  */
  749                                 memcpy(ni->ni_tstamp.data, scan.tstamp,
  750                                         sizeof(ni->ni_tstamp));
  751                         }
  752                         /*
  753                          * This isn't enabled yet - otherwise it would
  754                          * update the HT parameters and channel width
  755                          * from any node, which could lead to lots of
  756                          * strange behaviour if the 11n nodes aren't
  757                          * exactly configured to match.
  758                          */
  759 #if 0
  760                         if (scan.htcap != NULL && scan.htinfo != NULL &&
  761                             (vap->iv_flags_ht & IEEE80211_FHT_HT)) {
  762                                 if (ieee80211_ht_updateparams(ni,
  763                                     scan.htcap, scan.htinfo))
  764                                         ht_state_change = 1;
  765                         }
  766 #endif
  767                         if (ni != NULL) {
  768                                 IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
  769                                 ni->ni_noise = nf;
  770                         }
  771                         /*
  772                          * Same here - the channel width change should
  773                          * be applied to the specific peer node, not
  774                          * to the ic.  Ie, the interface configuration
  775                          * should stay in its current channel width;
  776                          * but it should change the rate control and
  777                          * any queued frames for the given node only.
  778                          *
  779                          * Since there's no (current) way to inform
  780                          * the driver that a channel width change has
  781                          * occurred for a single node, just stub this
  782                          * out.
  783                          */
  784 #if 0
  785                         if (ht_state_change)
  786                                 ieee80211_update_chw(ic);
  787 #endif
  788                 }
  789                 break;
  790         }
  791 
  792         case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
  793                 if (vap->iv_state != IEEE80211_S_RUN) {
  794                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  795                             wh, NULL, "wrong state %s",
  796                             ieee80211_state_name[vap->iv_state]);
  797                         vap->iv_stats.is_rx_mgtdiscard++;
  798                         return;
  799                 }
  800                 if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
  801                         /* frame must be directed */
  802                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  803                             wh, NULL, "%s", "not unicast");
  804                         vap->iv_stats.is_rx_mgtdiscard++;       /* XXX stat */
  805                         return;
  806                 }
  807 
  808                 /*
  809                  * prreq frame format
  810                  *      [tlv] ssid
  811                  *      [tlv] supported rates
  812                  *      [tlv] extended supported rates
  813                  */
  814                 ssid = rates = xrates = NULL;
  815                 while (efrm - frm > 1) {
  816                         IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return);
  817                         switch (*frm) {
  818                         case IEEE80211_ELEMID_SSID:
  819                                 ssid = frm;
  820                                 break;
  821                         case IEEE80211_ELEMID_RATES:
  822                                 rates = frm;
  823                                 break;
  824                         case IEEE80211_ELEMID_XRATES:
  825                                 xrates = frm;
  826                                 break;
  827                         }
  828                         frm += frm[1] + 2;
  829                 }
  830                 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return);
  831                 if (xrates != NULL)
  832                         IEEE80211_VERIFY_ELEMENT(xrates,
  833                                 IEEE80211_RATE_MAXSIZE - rates[1], return);
  834                 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return);
  835                 IEEE80211_VERIFY_SSID(vap->iv_bss, ssid, return);
  836                 if ((vap->iv_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) {
  837                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  838                             wh, NULL,
  839                             "%s", "no ssid with ssid suppression enabled");
  840                         vap->iv_stats.is_rx_ssidmismatch++; /*XXX*/
  841                         return;
  842                 }
  843 
  844                 /* XXX find a better class or define it's own */
  845                 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
  846                     "%s", "recv probe req");
  847                 /*
  848                  * Some legacy 11b clients cannot hack a complete
  849                  * probe response frame.  When the request includes
  850                  * only a bare-bones rate set, communicate this to
  851                  * the transmit side.
  852                  */
  853                 ieee80211_send_proberesp(vap, wh->i_addr2,
  854                     is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0);
  855                 break;
  856 
  857         case IEEE80211_FC0_SUBTYPE_ACTION:
  858         case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
  859                 if ((ni == vap->iv_bss) &&
  860                     !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
  861                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  862                             wh, NULL, "%s", "unknown node");
  863                         vap->iv_stats.is_rx_mgtdiscard++;
  864                 } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
  865                     !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
  866                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  867                             wh, NULL, "%s", "not for us");
  868                         vap->iv_stats.is_rx_mgtdiscard++;
  869                 } else if (vap->iv_state != IEEE80211_S_RUN) {
  870                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  871                             wh, NULL, "wrong state %s",
  872                             ieee80211_state_name[vap->iv_state]);
  873                         vap->iv_stats.is_rx_mgtdiscard++;
  874                 } else {
  875                         if (ieee80211_parse_action(ni, m0) == 0)
  876                                 (void)ic->ic_recv_action(ni, wh, frm, efrm);
  877                 }
  878                 break;
  879 
  880         case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
  881         case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
  882         case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
  883         case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
  884         case IEEE80211_FC0_SUBTYPE_TIMING_ADV:
  885         case IEEE80211_FC0_SUBTYPE_ATIM:
  886         case IEEE80211_FC0_SUBTYPE_DISASSOC:
  887         case IEEE80211_FC0_SUBTYPE_AUTH:
  888         case IEEE80211_FC0_SUBTYPE_DEAUTH:
  889                 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  890                     wh, NULL, "%s", "not handled");
  891                 vap->iv_stats.is_rx_mgtdiscard++;
  892                 break;
  893 
  894         default:
  895                 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
  896                     wh, "mgt", "subtype 0x%x not handled", subtype);
  897                 vap->iv_stats.is_rx_badsubtype++;
  898                 break;
  899         }
  900 }
  901 #undef IEEE80211_VERIFY_LENGTH
  902 #undef IEEE80211_VERIFY_ELEMENT
  903 
  904 static void
  905 ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
  906         int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
  907 {
  908         struct ieee80211vap *vap = ni->ni_vap;
  909         struct ieee80211com *ic = ni->ni_ic;
  910         struct ieee80211_frame *wh;
  911 
  912         /*
  913          * Process management frames when scanning; useful for doing
  914          * a site-survey.
  915          */
  916         if (ic->ic_flags & IEEE80211_F_SCAN)
  917                 adhoc_recv_mgmt(ni, m0, subtype, rxs, rssi, nf);
  918         else {
  919                 wh = mtod(m0, struct ieee80211_frame *);
  920                 switch (subtype) {
  921                 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
  922                 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
  923                 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
  924                 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
  925                 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
  926                 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
  927                 case IEEE80211_FC0_SUBTYPE_TIMING_ADV:
  928                 case IEEE80211_FC0_SUBTYPE_BEACON:
  929                 case IEEE80211_FC0_SUBTYPE_ATIM:
  930                 case IEEE80211_FC0_SUBTYPE_DISASSOC:
  931                 case IEEE80211_FC0_SUBTYPE_AUTH:
  932                 case IEEE80211_FC0_SUBTYPE_DEAUTH:
  933                 case IEEE80211_FC0_SUBTYPE_ACTION:
  934                 case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
  935                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  936                              wh, NULL, "%s", "not handled");
  937                         vap->iv_stats.is_rx_mgtdiscard++;
  938                         break;
  939                 default:
  940                         IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
  941                              wh, "mgt", "subtype 0x%x not handled", subtype);
  942                         vap->iv_stats.is_rx_badsubtype++;
  943                         break;
  944                 }
  945         }
  946 }
  947 
  948 static void
  949 adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
  950 {
  951 
  952         switch (subtype) {
  953         case IEEE80211_FC0_SUBTYPE_BAR:
  954                 ieee80211_recv_bar(ni, m);
  955                 break;
  956         }
  957 }

Cache object: 68ffae077a9dc78a0282abb2c6585a2a


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