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-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    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$");
   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 = ieee80211_getqos(wh)[0];
  497                 else
  498                         qos = 0;
  499 
  500                 /*
  501                  * Next up, any fragmentation.
  502                  */
  503                 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
  504                         m = ieee80211_defrag(ni, m, hdrspace);
  505                         if (m == NULL) {
  506                                 /* Fragment dropped or frame not complete yet */
  507                                 goto out;
  508                         }
  509                 }
  510                 wh = NULL;              /* no longer valid, catch any uses */
  511 
  512                 /*
  513                  * Next strip any MSDU crypto bits.
  514                  */
  515                 if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) {
  516                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
  517                             ni->ni_macaddr, "data", "%s", "demic error");
  518                         vap->iv_stats.is_rx_demicfail++;
  519                         IEEE80211_NODE_STAT(ni, rx_demicfail);
  520                         goto out;
  521                 }
  522 
  523                 /* copy to listener after decrypt */
  524                 if (ieee80211_radiotap_active_vap(vap))
  525                         ieee80211_radiotap_rx(vap, m);
  526                 need_tap = 0;
  527 
  528                 /*
  529                  * Finally, strip the 802.11 header.
  530                  */
  531                 m = ieee80211_decap(vap, m, hdrspace);
  532                 if (m == NULL) {
  533                         /* XXX mask bit to check for both */
  534                         /* don't count Null data frames as errors */
  535                         if (subtype == IEEE80211_FC0_SUBTYPE_NODATA ||
  536                             subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL)
  537                                 goto out;
  538                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
  539                             ni->ni_macaddr, "data", "%s", "decap error");
  540                         vap->iv_stats.is_rx_decap++;
  541                         IEEE80211_NODE_STAT(ni, rx_decap);
  542                         goto err;
  543                 }
  544                 eh = mtod(m, struct ether_header *);
  545                 if (!ieee80211_node_is_authorized(ni)) {
  546                         /*
  547                          * Deny any non-PAE frames received prior to
  548                          * authorization.  For open/shared-key
  549                          * authentication the port is mark authorized
  550                          * after authentication completes.  For 802.1x
  551                          * the port is not marked authorized by the
  552                          * authenticator until the handshake has completed.
  553                          */
  554                         if (eh->ether_type != htons(ETHERTYPE_PAE)) {
  555                                 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
  556                                     eh->ether_shost, "data",
  557                                     "unauthorized port: ether type 0x%x len %u",
  558                                     eh->ether_type, m->m_pkthdr.len);
  559                                 vap->iv_stats.is_rx_unauth++;
  560                                 IEEE80211_NODE_STAT(ni, rx_unauth);
  561                                 goto err;
  562                         }
  563                 } else {
  564                         /*
  565                          * When denying unencrypted frames, discard
  566                          * any non-PAE frames received without encryption.
  567                          */
  568                         if ((vap->iv_flags & IEEE80211_F_DROPUNENC) &&
  569                             (key == NULL && (m->m_flags & M_WEP) == 0) &&
  570                             eh->ether_type != htons(ETHERTYPE_PAE)) {
  571                                 /*
  572                                  * Drop unencrypted frames.
  573                                  */
  574                                 vap->iv_stats.is_rx_unencrypted++;
  575                                 IEEE80211_NODE_STAT(ni, rx_unencrypted);
  576                                 goto out;
  577                         }
  578                 }
  579                 /* XXX require HT? */
  580                 if (qos & IEEE80211_QOS_AMSDU) {
  581                         m = ieee80211_decap_amsdu(ni, m);
  582                         if (m == NULL)
  583                                 return IEEE80211_FC0_TYPE_DATA;
  584                 } else {
  585 #ifdef IEEE80211_SUPPORT_SUPERG
  586                         m = ieee80211_decap_fastframe(vap, ni, m);
  587                         if (m == NULL)
  588                                 return IEEE80211_FC0_TYPE_DATA;
  589 #endif
  590                 }
  591                 if (dir == IEEE80211_FC1_DIR_DSTODS && ni->ni_wdsvap != NULL)
  592                         ieee80211_deliver_data(ni->ni_wdsvap, ni, m);
  593                 else
  594                         ieee80211_deliver_data(vap, ni, m);
  595                 return IEEE80211_FC0_TYPE_DATA;
  596 
  597         case IEEE80211_FC0_TYPE_MGT:
  598                 vap->iv_stats.is_rx_mgmt++;
  599                 IEEE80211_NODE_STAT(ni, rx_mgmt);
  600                 if (dir != IEEE80211_FC1_DIR_NODS) {
  601                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  602                             wh, "data", "incorrect dir 0x%x", dir);
  603                         vap->iv_stats.is_rx_wrongdir++;
  604                         goto err;
  605                 }
  606                 if (m->m_pkthdr.len < sizeof(struct ieee80211_frame)) {
  607                         IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
  608                             ni->ni_macaddr, "mgt", "too short: len %u",
  609                             m->m_pkthdr.len);
  610                         vap->iv_stats.is_rx_tooshort++;
  611                         goto out;
  612                 }
  613 #ifdef IEEE80211_DEBUG
  614                 if ((ieee80211_msg_debug(vap) && doprint(vap, subtype)) ||
  615                     ieee80211_msg_dumppkts(vap)) {
  616                         if_printf(ifp, "received %s from %s rssi %d\n",
  617                             ieee80211_mgt_subtype_name(subtype),
  618                             ether_sprintf(wh->i_addr2), rssi);
  619                 }
  620 #endif
  621                 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
  622                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  623                             wh, NULL, "%s", "WEP set but not permitted");
  624                         vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
  625                         goto out;
  626                 }
  627                 vap->iv_recv_mgmt(ni, m, subtype, rxs, rssi, nf);
  628                 goto out;
  629 
  630         case IEEE80211_FC0_TYPE_CTL:
  631                 vap->iv_stats.is_rx_ctl++;
  632                 IEEE80211_NODE_STAT(ni, rx_ctrl);
  633                 vap->iv_recv_ctl(ni, m, subtype);
  634                 goto out;
  635 
  636         default:
  637                 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
  638                     wh, "bad", "frame type 0x%x", type);
  639                 /* should not come here */
  640                 break;
  641         }
  642 err:
  643         if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
  644 out:
  645         if (m != NULL) {
  646                 if (need_tap && ieee80211_radiotap_active_vap(vap))
  647                         ieee80211_radiotap_rx(vap, m);
  648                 m_freem(m);
  649         }
  650         return type;
  651 }
  652 
  653 static int
  654 is11bclient(const uint8_t *rates, const uint8_t *xrates)
  655 {
  656         static const uint32_t brates = (1<<2*1)|(1<<2*2)|(1<<11)|(1<<2*11);
  657         int i;
  658 
  659         /* NB: the 11b clients we care about will not have xrates */
  660         if (xrates != NULL || rates == NULL)
  661                 return 0;
  662         for (i = 0; i < rates[1]; i++) {
  663                 int r = rates[2+i] & IEEE80211_RATE_VAL;
  664                 if (r > 2*11 || ((1<<r) & brates) == 0)
  665                         return 0;
  666         }
  667         return 1;
  668 }
  669 
  670 static void
  671 adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
  672         int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
  673 {
  674         struct ieee80211vap *vap = ni->ni_vap;
  675         struct ieee80211com *ic = ni->ni_ic;
  676         struct ieee80211_channel *rxchan = ic->ic_curchan;
  677         struct ieee80211_frame *wh;
  678         uint8_t *frm, *efrm;
  679         uint8_t *ssid, *rates, *xrates;
  680 #if 0
  681         int ht_state_change = 0;
  682 #endif
  683 
  684         wh = mtod(m0, struct ieee80211_frame *);
  685         frm = (uint8_t *)&wh[1];
  686         efrm = mtod(m0, uint8_t *) + m0->m_len;
  687         switch (subtype) {
  688         case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
  689         case IEEE80211_FC0_SUBTYPE_BEACON: {
  690                 struct ieee80211_scanparams scan;
  691                 struct ieee80211_channel *c;
  692                 /*
  693                  * We process beacon/probe response
  694                  * frames to discover neighbors.
  695                  */ 
  696                 if (rxs != NULL) {
  697                         c = ieee80211_lookup_channel_rxstatus(vap, rxs);
  698                         if (c != NULL)
  699                                 rxchan = c;
  700                 }
  701                 if (ieee80211_parse_beacon(ni, m0, rxchan, &scan) != 0)
  702                         return;
  703                 /*
  704                  * Count frame now that we know it's to be processed.
  705                  */
  706                 if (subtype == IEEE80211_FC0_SUBTYPE_BEACON) {
  707                         vap->iv_stats.is_rx_beacon++;           /* XXX remove */
  708                         IEEE80211_NODE_STAT(ni, rx_beacons);
  709                 } else
  710                         IEEE80211_NODE_STAT(ni, rx_proberesp);
  711                 /*
  712                  * If scanning, just pass information to the scan module.
  713                  */
  714                 if (ic->ic_flags & IEEE80211_F_SCAN) {
  715                         if (ic->ic_flags_ext & IEEE80211_FEXT_PROBECHAN) {
  716                                 /*
  717                                  * Actively scanning a channel marked passive;
  718                                  * send a probe request now that we know there
  719                                  * is 802.11 traffic present.
  720                                  *
  721                                  * XXX check if the beacon we recv'd gives
  722                                  * us what we need and suppress the probe req
  723                                  */
  724                                 ieee80211_probe_curchan(vap, 1);
  725                                 ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
  726                         }
  727                         ieee80211_add_scan(vap, rxchan, &scan, wh,
  728                             subtype, rssi, nf);
  729                         return;
  730                 }
  731                 if (scan.capinfo & IEEE80211_CAPINFO_IBSS) {
  732                         if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
  733                                 /*
  734                                  * Create a new entry in the neighbor table.
  735                                  *
  736                                  * XXX TODO:
  737                                  *
  738                                  * Here we're not scanning; so if we have an
  739                                  * SSID then make sure it matches our SSID.
  740                                  * Otherwise this code will match on all IBSS
  741                                  * beacons/probe requests for all SSIDs,
  742                                  * filling the node table with nodes that
  743                                  * aren't ours.
  744                                  */
  745                                 if (ieee80211_ibss_node_check_new(ni, &scan))
  746                                         ni = ieee80211_add_neighbor(vap, wh, &scan);
  747                                 else
  748                                         ni = NULL;
  749                         } else if (ni->ni_capinfo == 0) {
  750                                 /*
  751                                  * Update faked node created on transmit.
  752                                  * Note this also updates the tsf.
  753                                  */
  754                                 ieee80211_init_neighbor(ni, wh, &scan);
  755                         } else {
  756                                 /*
  757                                  * Record tsf for potential resync.
  758                                  */
  759                                 memcpy(ni->ni_tstamp.data, scan.tstamp,
  760                                         sizeof(ni->ni_tstamp));
  761                         }
  762                         /*
  763                          * This isn't enabled yet - otherwise it would
  764                          * update the HT parameters and channel width
  765                          * from any node, which could lead to lots of
  766                          * strange behaviour if the 11n nodes aren't
  767                          * exactly configured to match.
  768                          */
  769 #if 0
  770                         if (scan.htcap != NULL && scan.htinfo != NULL &&
  771                             (vap->iv_flags_ht & IEEE80211_FHT_HT)) {
  772                                 if (ieee80211_ht_updateparams(ni,
  773                                     scan.htcap, scan.htinfo))
  774                                         ht_state_change = 1;
  775                         }
  776 #endif
  777                         if (ni != NULL) {
  778                                 IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
  779                                 ni->ni_noise = nf;
  780                         }
  781                         /*
  782                          * Same here - the channel width change should
  783                          * be applied to the specific peer node, not
  784                          * to the ic.  Ie, the interface configuration
  785                          * should stay in its current channel width;
  786                          * but it should change the rate control and
  787                          * any queued frames for the given node only.
  788                          *
  789                          * Since there's no (current) way to inform
  790                          * the driver that a channel width change has
  791                          * occurred for a single node, just stub this
  792                          * out.
  793                          */
  794 #if 0
  795                         if (ht_state_change)
  796                                 ieee80211_update_chw(ic);
  797 #endif
  798                 }
  799                 break;
  800         }
  801 
  802         case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
  803                 if (vap->iv_state != IEEE80211_S_RUN) {
  804                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  805                             wh, NULL, "wrong state %s",
  806                             ieee80211_state_name[vap->iv_state]);
  807                         vap->iv_stats.is_rx_mgtdiscard++;
  808                         return;
  809                 }
  810                 if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
  811                         /* frame must be directed */
  812                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  813                             wh, NULL, "%s", "not unicast");
  814                         vap->iv_stats.is_rx_mgtdiscard++;       /* XXX stat */
  815                         return;
  816                 }
  817 
  818                 /*
  819                  * prreq frame format
  820                  *      [tlv] ssid
  821                  *      [tlv] supported rates
  822                  *      [tlv] extended supported rates
  823                  */
  824                 ssid = rates = xrates = NULL;
  825                 while (efrm - frm > 1) {
  826                         IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return);
  827                         switch (*frm) {
  828                         case IEEE80211_ELEMID_SSID:
  829                                 ssid = frm;
  830                                 break;
  831                         case IEEE80211_ELEMID_RATES:
  832                                 rates = frm;
  833                                 break;
  834                         case IEEE80211_ELEMID_XRATES:
  835                                 xrates = frm;
  836                                 break;
  837                         }
  838                         frm += frm[1] + 2;
  839                 }
  840                 IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return);
  841                 if (xrates != NULL)
  842                         IEEE80211_VERIFY_ELEMENT(xrates,
  843                                 IEEE80211_RATE_MAXSIZE - rates[1], return);
  844                 IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return);
  845                 IEEE80211_VERIFY_SSID(vap->iv_bss, ssid, return);
  846                 if ((vap->iv_flags & IEEE80211_F_HIDESSID) && ssid[1] == 0) {
  847                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  848                             wh, NULL,
  849                             "%s", "no ssid with ssid suppression enabled");
  850                         vap->iv_stats.is_rx_ssidmismatch++; /*XXX*/
  851                         return;
  852                 }
  853 
  854                 /* XXX find a better class or define it's own */
  855                 IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
  856                     "%s", "recv probe req");
  857                 /*
  858                  * Some legacy 11b clients cannot hack a complete
  859                  * probe response frame.  When the request includes
  860                  * only a bare-bones rate set, communicate this to
  861                  * the transmit side.
  862                  */
  863                 ieee80211_send_proberesp(vap, wh->i_addr2,
  864                     is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0);
  865                 break;
  866 
  867         case IEEE80211_FC0_SUBTYPE_ACTION:
  868         case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
  869                 if ((ni == vap->iv_bss) &&
  870                     !IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
  871                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  872                             wh, NULL, "%s", "unknown node");
  873                         vap->iv_stats.is_rx_mgtdiscard++;
  874                 } else if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
  875                     !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
  876                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  877                             wh, NULL, "%s", "not for us");
  878                         vap->iv_stats.is_rx_mgtdiscard++;
  879                 } else if (vap->iv_state != IEEE80211_S_RUN) {
  880                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  881                             wh, NULL, "wrong state %s",
  882                             ieee80211_state_name[vap->iv_state]);
  883                         vap->iv_stats.is_rx_mgtdiscard++;
  884                 } else {
  885                         if (ieee80211_parse_action(ni, m0) == 0)
  886                                 (void)ic->ic_recv_action(ni, wh, frm, efrm);
  887                 }
  888                 break;
  889 
  890         case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
  891         case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
  892         case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
  893         case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
  894         case IEEE80211_FC0_SUBTYPE_TIMING_ADV:
  895         case IEEE80211_FC0_SUBTYPE_ATIM:
  896         case IEEE80211_FC0_SUBTYPE_DISASSOC:
  897         case IEEE80211_FC0_SUBTYPE_AUTH:
  898         case IEEE80211_FC0_SUBTYPE_DEAUTH:
  899                 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  900                     wh, NULL, "%s", "not handled");
  901                 vap->iv_stats.is_rx_mgtdiscard++;
  902                 break;
  903 
  904         default:
  905                 IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
  906                     wh, "mgt", "subtype 0x%x not handled", subtype);
  907                 vap->iv_stats.is_rx_badsubtype++;
  908                 break;
  909         }
  910 }
  911 #undef IEEE80211_VERIFY_LENGTH
  912 #undef IEEE80211_VERIFY_ELEMENT
  913 
  914 static void
  915 ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0,
  916         int subtype, const struct ieee80211_rx_stats *rxs, int rssi, int nf)
  917 {
  918         struct ieee80211vap *vap = ni->ni_vap;
  919         struct ieee80211com *ic = ni->ni_ic;
  920         struct ieee80211_frame *wh;
  921 
  922         /*
  923          * Process management frames when scanning; useful for doing
  924          * a site-survey.
  925          */
  926         if (ic->ic_flags & IEEE80211_F_SCAN)
  927                 adhoc_recv_mgmt(ni, m0, subtype, rxs, rssi, nf);
  928         else {
  929                 wh = mtod(m0, struct ieee80211_frame *);
  930                 switch (subtype) {
  931                 case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
  932                 case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
  933                 case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
  934                 case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
  935                 case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
  936                 case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
  937                 case IEEE80211_FC0_SUBTYPE_TIMING_ADV:
  938                 case IEEE80211_FC0_SUBTYPE_BEACON:
  939                 case IEEE80211_FC0_SUBTYPE_ATIM:
  940                 case IEEE80211_FC0_SUBTYPE_DISASSOC:
  941                 case IEEE80211_FC0_SUBTYPE_AUTH:
  942                 case IEEE80211_FC0_SUBTYPE_DEAUTH:
  943                 case IEEE80211_FC0_SUBTYPE_ACTION:
  944                 case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
  945                         IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
  946                              wh, NULL, "%s", "not handled");
  947                         vap->iv_stats.is_rx_mgtdiscard++;
  948                         break;
  949                 default:
  950                         IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
  951                              wh, "mgt", "subtype 0x%x not handled", subtype);
  952                         vap->iv_stats.is_rx_badsubtype++;
  953                         break;
  954                 }
  955         }
  956 }
  957 
  958 static void
  959 adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
  960 {
  961 
  962         switch (subtype) {
  963         case IEEE80211_FC0_SUBTYPE_BAR:
  964                 ieee80211_recv_bar(ni, m);
  965                 break;
  966         }
  967 }

Cache object: 77137e54b5e8c971b7ee9ae1339cf3da


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