37#include <sys/malloc.h>
38#include <sys/endian.h>
39#include <sys/kernel.h>
41#include <sys/socket.h>
43#include <net/ethernet.h>
45#include <net/if_var.h>
46#include <net/if_llc.h>
47#include <net/if_media.h>
48#include <net/if_vlan_var.h>
52#ifdef IEEE80211_SUPPORT_MESH
59#include <netinet/in.h>
60#include <net/ethernet.h>
93 bzero(&rxs,
sizeof(rxs));
125 m->m_flags |= M_BCAST;
128 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
143 if (TAILQ_NEXT(vap, iv_next) != NULL) {
149 mcopy = m_dup(m, M_NOWAIT);
186 rxseq = le16toh(*(uint16_t *)wh->
i_seq);
190 if (!more_frag && fragno == 0 && ni->
ni_rxfrag[0] == NULL)
227 last_rxseq = le16toh(*(uint16_t *)lwh->
i_seq);
232 if (rxseq == last_rxseq+1 &&
238 *(uint16_t *) lwh->
i_seq = *(uint16_t *) wh->
i_seq;
269 wh->
i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
278 struct ether_header *eh = mtod(m,
struct ether_header *);
279 struct ifnet *ifp = vap->
iv_ifp;
282 m->m_flags &= ~(M_MCAST | M_BCAST);
290 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
293 if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
294 if (ETHER_IS_BROADCAST(eh->ether_dhost))
295 m->m_flags |= M_BCAST;
297 m->m_flags |= M_MCAST;
301 m->m_pkthdr.rcvif = ifp;
305 m->m_pkthdr.ether_vtag = ni->
ni_vlan;
306 m->m_flags |= M_VLANTAG;
308 ifp->if_input(ifp, m);
316 struct ether_header *eh;
319 KASSERT(hdrlen <=
sizeof(wh),
320 (
"hdrlen %d > max %zd", hdrlen,
sizeof(wh)));
322 if (m->m_len < hdrlen +
sizeof(*llc) &&
323 (m = m_pullup(m, hdrlen +
sizeof(*llc))) == NULL) {
328 memcpy(&wh, mtod(m, caddr_t), hdrlen);
329 llc = (
struct llc *)(mtod(m, caddr_t) + hdrlen);
330 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP &&
331 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 &&
332 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0 &&
334 !(llc->llc_snap.ether_type == htons(ETHERTYPE_AARP) ||
335 llc->llc_snap.ether_type == htons(ETHERTYPE_IPX)) &&
338 m_adj(m, hdrlen +
sizeof(
struct llc) -
sizeof(*eh));
341 m_adj(m, hdrlen -
sizeof(*eh));
343 eh = mtod(m,
struct ether_header *);
362#ifndef __NO_STRICT_ALIGNMENT
363 if (!ALIGNED_POINTER(mtod(m, caddr_t) +
sizeof(*eh), uint32_t)) {
370 eh = mtod(m,
struct ether_header *);
371 eh->ether_type = htons(m->m_pkthdr.len -
sizeof(*eh));
382#define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc))
383 struct ether_header *eh;
385 const uint8_t llc_hdr_mac[ETHER_ADDR_LEN] = {
387 LLC_SNAP_LSAP, LLC_SNAP_LSAP, LLC_UI, 0, 0, 0
400 eh = mtod(m,
struct ether_header *);
407 if (memcmp(eh->ether_dhost, llc_hdr_mac, ETHER_ADDR_LEN) == 0)
410 llc = (
struct llc *)&eh[1];
411 *framelen = ntohs(eh->ether_type)
412 +
sizeof(
struct ether_header) - sizeof(struct llc);
413 eh->ether_type = llc->llc_un.type_snap.ether_type;
414 ovbcopy(eh, mtod(m, uint8_t *) +
sizeof(
struct llc),
415 sizeof(
struct ether_header));
416 m_adj(m,
sizeof(
struct llc));
426 const uint8_t *rates,
const uint8_t *xrates,
int flags)
431 memset(rs, 0,
sizeof(*rs));
434 if (xrates != NULL) {
443 "extended rate set too large; only using "
444 "%u of %u rates", nxrates, xrates[1]);
502 "%s",
"shared key challenge alloc failed");
525 frm = (uint8_t *)&wh[1];
526 efrm = mtod(m, uint8_t *) + m->m_len;
554 memset(scan, 0,
sizeof(*scan));
555 scan->
tstamp = frm; frm += 8;
556 scan->
bintval = le16toh(*(uint16_t *)frm); frm += 2;
557 scan->
capinfo = le16toh(*(uint16_t *)frm); frm += 2;
563 while (efrm - frm > 1) {
584 scan->
fhdwell = le16dec(&frm[2]);
600 scan->
timoff = frm - mtod(m, uint8_t *);
616 "bad len %u", frm[1]);
620 scan->
erp = frm[2] | 0x100;
637#ifdef IEEE80211_SUPPORT_MESH
653#ifdef IEEE80211_SUPPORT_SUPERG
657#ifdef IEEE80211_SUPPORT_TDMA
667 if (scan->
htcap == NULL)
678 "id %u, len %u", *frm, frm[1]);
712 wh, NULL,
"for off-channel %u (bchan=%u)",
717 if (!(IEEE80211_BINTVAL_MIN <= scan->bintval &&
721 wh, NULL,
"bogus beacon interval (%d TU)",
737 if (scan->
csa != NULL) {
750 if (scan->
htcap != NULL) {
757 if (scan->
htinfo != NULL) {
766 if (scan->
vhtcap != NULL) {
798 frm = (u_int8_t *)&wh[1];
799 efrm = mtod(m, u_int8_t *) + m->m_len;
842#ifdef IEEE80211_SUPPORT_MESH
873 wh, NULL,
"not implemented yet, act=0x%02X",
898 printf(
"%s: TODO: VHT handling!\n", __func__);
904#ifdef IEEE80211_DEBUG
909ieee80211_ssid_mismatch(
struct ieee80211vap *vap,
const char *tag,
912 printf(
"[%s] discard %s frame, ssid mismatch: ",
913 ether_sprintf(
mac), tag);
921static const uint8_t *
934#include <machine/stdarg.h>
937ieee80211_note(
const struct ieee80211vap *vap,
const char *fmt, ...)
944 len = vsnprintf(buf,
sizeof(buf), fmt, ap);
947 if_printf(vap->
iv_ifp,
"%s", buf);
949 if (len >=
sizeof(buf))
950 printf(
"%s: XXX buffer too small: len = %d\n", __func__, len);
956 const char *fmt, ...)
963 len = vsnprintf(buf,
sizeof(buf), fmt, ap);
965 if_printf(vap->
iv_ifp,
"[%s] %s\n",
966 ether_sprintf(ieee80211_getbssid(vap, wh)), buf);
968 if (len >=
sizeof(buf))
969 printf(
"%s: XXX buffer too small: len = %d\n", __func__, len);
975 const char *fmt, ...)
982 len = vsnprintf(buf,
sizeof(buf), fmt, ap);
984 if_printf(vap->
iv_ifp,
"[%s] %s\n", ether_sprintf(
mac), buf);
986 if (len >=
sizeof(buf))
987 printf(
"%s: XXX buffer too small: len = %d\n", __func__, len);
993 const char *type,
const char *fmt, ...)
1000 len = vsnprintf(buf,
sizeof(buf), fmt, ap);
1003 if_printf(vap->
iv_ifp,
"[%s] discard %s frame, %s\n",
1004 ether_sprintf(ieee80211_getbssid(vap, wh)),
1008 if (len >=
sizeof(buf))
1009 printf(
"%s: XXX buffer too small: len = %d\n", __func__, len);
1015 const char *type,
const char *fmt, ...)
1022 len = vsnprintf(buf,
sizeof(buf), fmt, ap);
1025 if_printf(vap->
iv_ifp,
"[%s] discard%s%s information element, %s\n",
1026 ether_sprintf(ieee80211_getbssid(vap, wh)),
1027 type != NULL ?
" " :
"", type != NULL ? type :
"", buf);
1029 if (len >=
sizeof(buf))
1030 printf(
"%s: XXX buffer too small: len = %d\n", __func__, len);
1036 const char *type,
const char *fmt, ...)
1043 len = vsnprintf(buf,
sizeof(buf), fmt, ap);
1046 if_printf(vap->
iv_ifp,
"[%s] discard%s%s frame, %s\n",
1048 type != NULL ?
" " :
"", type != NULL ? type :
"", buf);
1050 if (len >=
sizeof(buf))
1051 printf(
"%s: XXX buffer too small: len = %d\n", __func__, len);
#define IEEE80211_R_C_CHAIN
#define IEEE80211_RATE_MAXSIZE
#define IEEE80211_MAX_CHAINS
#define IEEE80211_FH_CHAN(set, pat)
#define IEEE80211_R_C_RSSI
int ieee80211_chan2ieee(struct ieee80211com *ic, const struct ieee80211_channel *c)
#define IEEE80211_ACTION_CAT_VHT
#define IEEE80211_FC1_MORE_FRAG
#define IEEE80211_ACTION_CAT_BA
#define IEEE80211_ACTION_CAT_HT
#define IEEE80211_ADDR_LEN
#define IEEE80211_ACTION_HT_MIMOPWRSAVE
#define IEEE80211_FC1_PROTECTED
#define IEEE80211_FC0_SUBTYPE_PS_POLL
#define IEEE80211_FC1_DIR_DSTODS
#define IEEE80211_SEQ_FRAG_MASK
#define IEEE80211_ACTION_BA_ADDBA_RESPONSE
#define IEEE80211_ACTION_HT_TXCHWIDTH
#define IEEE80211_IS_MULTICAST(_a)
#define IEEE80211_ACTION_BA_ADDBA_REQUEST
#define IEEE80211_ACTION_CAT_MESH
#define IEEE80211_FC1_DIR_NODS
#define IEEE80211_FC1_DIR_MASK
#define IEEE80211_ACTION_BA_DELBA
#define IEEE80211_FC1_DIR_FROMDS
#define IEEE80211_FC1_DIR_TODS
#define IEEE80211_NWID_LEN
#define IEEE80211_QOS_AMSDU
@ IEEE80211_ELEMID_VENDOR
@ IEEE80211_ELEMID_EXTCAP
@ IEEE80211_ELEMID_BSSLOAD
@ IEEE80211_ELEMID_DSPARMS
@ IEEE80211_ELEMID_FHPARMS
@ IEEE80211_ELEMID_COUNTRY
@ IEEE80211_ELEMID_VHT_OPMODE
@ IEEE80211_ELEMID_PWRCNSTR
@ IEEE80211_ELEMID_XRATES
@ IEEE80211_ELEMID_CFPARMS
@ IEEE80211_ELEMID_MESHCONF
@ IEEE80211_ELEMID_APCHANREP
@ IEEE80211_ELEMID_HTINFO
@ IEEE80211_ELEMID_VHT_CAP
@ IEEE80211_ELEMID_MESHID
@ IEEE80211_ELEMID_IBSSPARMS
#define IEEE80211_FC0_SUBTYPE_MASK
#define IEEE80211_BINTVAL_MAX
#define IEEE80211_CHALLENGE_LEN
#define IEEE80211_ACTION_CAT_SELF_PROT
static const struct ieee80211_aclator mac
int ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs)
int ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs)
struct mbuf * ieee80211_realign(struct ieee80211vap *vap, struct mbuf *m, size_t align)
#define IEEE80211_M_NOWAIT
#define IEEE80211_NODE_LOCK(_nt)
#define IEEE80211_NODE_UNLOCK(_nt)
@ IEEE80211_ACTION_MESH_MCCA_AREQ
@ IEEE80211_ACTION_MESH_LMETRIC
@ IEEE80211_ACTION_MESH_TBTT_REQ
@ IEEE80211_ACTION_MESH_MCCA_SREP
@ IEEE80211_ACTION_MESH_HWMP
@ IEEE80211_ACTION_MESH_MCCA_TRDOWN
@ IEEE80211_ACTION_MESH_CC
@ IEEE80211_ACTION_MESH_MCCA_SREQ
@ IEEE80211_ACTION_MESH_GANN
@ IEEE80211_ACTION_MESH_MCCA_ADVER
@ IEEE80211_ACTION_MESH_TBTT_RES
@ IEEE80211_ACTION_MESHPEERING_CLOSE
@ IEEE80211_ACTION_MESHPEERING_CONFIRM
void ieee80211_free_node(struct ieee80211_node *ni)
struct ieee80211_node * ieee80211_tmp_node(struct ieee80211vap *vap, const uint8_t macaddr[IEEE80211_ADDR_LEN])
#define IEEE80211_RSSI_LPF(x, y)
#define IEEE80211_NODE_STAT(ni, stat)
static __inline struct ieee80211_node * ieee80211_ref_node(struct ieee80211_node *ni)
#define IEEE80211_NODE_STAT_ADD(ni, stat, v)
void ieee80211_print_essid(const uint8_t *essid, int len)
int ieee80211_fix_rate(struct ieee80211_node *ni, struct ieee80211_rateset *nrs, int flags)
static __inline const char * ieee80211_mgt_subtype_name(uint8_t subtype)
#define IEEE80211_SEND_MGMT(_ni, _type, _arg)
@ IEEE80211_BPARSE_XRATES_INVALID
@ IEEE80211_BPARSE_BINTVAL_INVALID
@ IEEE80211_BPARSE_OFFCHAN
@ IEEE80211_BPARSE_BADIELEN
@ IEEE80211_BPARSE_CSA_INVALID
@ IEEE80211_BPARSE_SSID_INVALID
@ IEEE80211_BPARSE_RATES_INVALID
#define IEEE80211_MSG_AUTH
#define IEEE80211_DISCARD_IE(_vap, _m, _wh, _type, _fmt,...)
#define IEEE80211_ADDR_COPY(dst, src)
#define IEEE80211_MSG_XRATE
#define IEEE80211_MSG_ELEMID
#define IEEE80211_ADDR_EQ(a1, a2)
#define IEEE80211_MSG_DEBUG
#define IEEE80211_NOTE(_vap, _m, _ni, _fmt,...)
#define IEEE80211_FHT_HTCOMPAT
#define IEEE80211_MSG_INPUT
#define IEEE80211_DISCARD(_vap, _m, _wh, _type, _fmt,...)
uint8_t i_addr1[IEEE80211_ADDR_LEN]
uint8_t i_addr2[IEEE80211_ADDR_LEN]
uint8_t i_addr3[IEEE80211_ADDR_LEN]
uint8_t ni_mimo_noise_ctl[IEEE80211_MAX_CHAINS]
struct ieee80211_rateset ni_rates
struct ieee80211com * ni_ic
struct ieee80211_node_table * ni_table
struct ieee80211vap * ni_vap
struct mbuf * ni_rxfrag[3]
uint32_t ni_mimo_rssi_ext[IEEE80211_MAX_CHAINS]
uint8_t ni_mimo_noise_ext[IEEE80211_MAX_CHAINS]
uint32_t ni_mimo_rssi_ctl[IEEE80211_MAX_CHAINS]
uint8_t i_addr4[IEEE80211_ADDR_LEN]
uint8_t i_addr1[IEEE80211_ADDR_LEN]
uint8_t i_addr2[IEEE80211_ADDR_LEN]
uint8_t i_addr3[IEEE80211_ADDR_LEN]
uint8_t rs_rates[IEEE80211_RATE_MAXSIZE]
int16_t c_rssi_ext[IEEE80211_MAX_CHAINS]
int16_t c_nf_ctl[IEEE80211_MAX_CHAINS]
int16_t c_rssi_ctl[IEEE80211_MAX_CHAINS]
int16_t c_nf_ext[IEEE80211_MAX_CHAINS]
uint32_t is_rx_chanmismatch
uint32_t is_rx_elem_unknown
uint32_t is_rx_badbintval
uint32_t is_rx_elem_toobig
enum ieee80211_phytype ic_phytype
struct ieee80211_node * iv_bss
enum ieee80211_opmode iv_opmode
struct ieee80211_stats iv_stats
enum ieee80211_state iv_state
int(* iv_input)(struct ieee80211_node *, struct mbuf *, const struct ieee80211_rx_stats *, int, int)