Changeset View
Changeset View
Standalone View
Standalone View
sys/net80211/ieee80211_input.c
Show First 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | ieee80211_defrag(struct ieee80211_node *ni, struct mbuf *m, int hdrspace, | |||||||||
rxseq = le16toh(*(uint16_t *)wh->i_seq); | rxseq = le16toh(*(uint16_t *)wh->i_seq); | |||||||||
fragno = rxseq & IEEE80211_SEQ_FRAG_MASK; | fragno = rxseq & IEEE80211_SEQ_FRAG_MASK; | |||||||||
/* Quick way out, if there's nothing to defragment */ | /* Quick way out, if there's nothing to defragment */ | |||||||||
if (!more_frag && fragno == 0 && ni->ni_rxfrag[0] == NULL) | if (!more_frag && fragno == 0 && ni->ni_rxfrag[0] == NULL) | |||||||||
return m; | return m; | |||||||||
/* Temporarily set flag to remember if fragment was encrypted */ | /* Temporarily set flag to remember if fragment was encrypted */ | |||||||||
emaste: I made a comment in D30663 on this | ||||||||||
Done Inline ActionsNoted. bz: Noted.
I think something went from with arc --update and relative changes to another non-main… | ||||||||||
Done Inline Actions
bz: > Noted.
> I think something went from with arc --update and relative changes to another non… | ||||||||||
if (has_decrypted) | if (has_decrypted) | |||||||||
wh->i_fc[1] |= IEEE80211_FC1_PROTECTED; | wh->i_fc[1] |= IEEE80211_FC1_PROTECTED; | |||||||||
/* | /* | |||||||||
* Remove frag to insure it doesn't get reaped by timer. | * Remove frag to insure it doesn't get reaped by timer. | |||||||||
*/ | */ | |||||||||
if (ni->ni_table == NULL) { | if (ni->ni_table == NULL) { | |||||||||
/* | /* | |||||||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | if (ni->ni_vlan != 0) { | |||||||||
/* attach vlan tag */ | /* attach vlan tag */ | |||||||||
m->m_pkthdr.ether_vtag = ni->ni_vlan; | m->m_pkthdr.ether_vtag = ni->ni_vlan; | |||||||||
m->m_flags |= M_VLANTAG; | m->m_flags |= M_VLANTAG; | |||||||||
} | } | |||||||||
ifp->if_input(ifp, m); | ifp->if_input(ifp, m); | |||||||||
} | } | |||||||||
struct mbuf * | struct mbuf * | |||||||||
ieee80211_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen) | ieee80211_decap(struct ieee80211vap *vap, struct mbuf *m, int hdrlen, | |||||||||
uint8_t qos) | ||||||||||
{ | { | |||||||||
struct ieee80211_qosframe_addr4 wh; | struct ieee80211_qosframe_addr4 wh; | |||||||||
struct ether_header *eh; | struct ether_header *eh; | |||||||||
struct llc *llc; | struct llc *llc; | |||||||||
KASSERT(hdrlen <= sizeof(wh), | KASSERT(hdrlen <= sizeof(wh), | |||||||||
("hdrlen %d > max %zd", hdrlen, sizeof(wh))); | ("hdrlen %d > max %zd", hdrlen, sizeof(wh))); | |||||||||
if (m->m_len < hdrlen + sizeof(*llc) && | if (m->m_len < hdrlen + sizeof(*llc) && | |||||||||
(m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) { | (m = m_pullup(m, hdrlen + sizeof(*llc))) == NULL) { | |||||||||
vap->iv_stats.is_rx_tooshort++; | vap->iv_stats.is_rx_tooshort++; | |||||||||
/* XXX msg */ | /* XXX msg */ | |||||||||
return NULL; | return NULL; | |||||||||
} | } | |||||||||
memcpy(&wh, mtod(m, caddr_t), hdrlen); | memcpy(&wh, mtod(m, caddr_t), hdrlen); | |||||||||
llc = (struct llc *)(mtod(m, caddr_t) + hdrlen); | llc = (struct llc *)(mtod(m, caddr_t) + hdrlen); | |||||||||
if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && | if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && | |||||||||
llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && | llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && | |||||||||
llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0 && | llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0 && | |||||||||
/* NB: preserve AppleTalk frames that have a native SNAP hdr */ | /* NB: preserve AppleTalk frames that have a native SNAP hdr */ | |||||||||
!(llc->llc_snap.ether_type == htons(ETHERTYPE_AARP) || | !(llc->llc_snap.ether_type == htons(ETHERTYPE_AARP) || | |||||||||
llc->llc_snap.ether_type == htons(ETHERTYPE_IPX))) { | llc->llc_snap.ether_type == htons(ETHERTYPE_IPX)) && | |||||||||
/* Do not want to touch A-MSDU frames. */ | ||||||||||
!(qos & IEEE80211_QOS_AMSDU)) { | ||||||||||
m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh)); | m_adj(m, hdrlen + sizeof(struct llc) - sizeof(*eh)); | |||||||||
llc = NULL; | llc = NULL; | |||||||||
} else { | } else { | |||||||||
m_adj(m, hdrlen - sizeof(*eh)); | m_adj(m, hdrlen - sizeof(*eh)); | |||||||||
} | } | |||||||||
eh = mtod(m, struct ether_header *); | eh = mtod(m, struct ether_header *); | |||||||||
switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { | switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { | |||||||||
case IEEE80211_FC1_DIR_NODS: | case IEEE80211_FC1_DIR_NODS: | |||||||||
Show All 31 Lines | ||||||||||
* Decap a frame encapsulated in a fast-frame/A-MSDU. | * Decap a frame encapsulated in a fast-frame/A-MSDU. | |||||||||
*/ | */ | |||||||||
struct mbuf * | struct mbuf * | |||||||||
ieee80211_decap1(struct mbuf *m, int *framelen) | ieee80211_decap1(struct mbuf *m, int *framelen) | |||||||||
{ | { | |||||||||
#define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc)) | #define FF_LLC_SIZE (sizeof(struct ether_header) + sizeof(struct llc)) | |||||||||
struct ether_header *eh; | struct ether_header *eh; | |||||||||
struct llc *llc; | struct llc *llc; | |||||||||
const uint8_t llc_hdr_mac[ETHER_ADDR_LEN] = { | ||||||||||
/* MAC address matching the 802.2 LLC header */ | ||||||||||
LLC_SNAP_LSAP, LLC_SNAP_LSAP, LLC_UI, 0, 0, 0 | ||||||||||
}; | ||||||||||
/* | /* | |||||||||
* The frame has an 802.3 header followed by an 802.2 | * The frame has an 802.3 header followed by an 802.2 | |||||||||
* LLC header. The encapsulated frame length is in the | * LLC header. The encapsulated frame length is in the | |||||||||
* first header type field; save that and overwrite it | * first header type field; save that and overwrite it | |||||||||
* with the true type field found in the second. Then | * with the true type field found in the second. Then | |||||||||
* copy the 802.3 header up to where it belongs and | * copy the 802.3 header up to where it belongs and | |||||||||
* adjust the mbuf contents to remove the void. | * adjust the mbuf contents to remove the void. | |||||||||
*/ | */ | |||||||||
if (m->m_len < FF_LLC_SIZE && (m = m_pullup(m, FF_LLC_SIZE)) == NULL) | if (m->m_len < FF_LLC_SIZE && (m = m_pullup(m, FF_LLC_SIZE)) == NULL) | |||||||||
return NULL; | return NULL; | |||||||||
eh = mtod(m, struct ether_header *); /* 802.3 header is first */ | eh = mtod(m, struct ether_header *); /* 802.3 header is first */ | |||||||||
/* | ||||||||||
* Detect possible attack where a single 802.11 frame is processed | ||||||||||
* as an A-MSDU frame due to an adversary setting the A-MSDU present | ||||||||||
* bit in the 802.11 QoS header. [FragAttacks] | ||||||||||
*/ | ||||||||||
if (memcmp(eh->ether_dhost, llc_hdr_mac, 6) == 0) | ||||||||||
markjUnsubmitted Done Inline Actions
markj: | ||||||||||
bzAuthorUnsubmitted Done Inline ActionsIEEE80211_ADDR_LEN actually then. Will do. bz: IEEE80211_ADDR_LEN actually then. Will do. | ||||||||||
bzAuthorUnsubmitted Done Inline ActionsaRGH; of course in this case you are right; my bad; sorry for the noise. bz: aRGH; of course in this case you are right; my bad; sorry for the noise. | ||||||||||
return NULL; | ||||||||||
llc = (struct llc *)&eh[1]; /* 802.2 header follows */ | llc = (struct llc *)&eh[1]; /* 802.2 header follows */ | |||||||||
*framelen = ntohs(eh->ether_type) /* encap'd frame size */ | *framelen = ntohs(eh->ether_type) /* encap'd frame size */ | |||||||||
+ sizeof(struct ether_header) - sizeof(struct llc); | + sizeof(struct ether_header) - sizeof(struct llc); | |||||||||
eh->ether_type = llc->llc_un.type_snap.ether_type; | eh->ether_type = llc->llc_un.type_snap.ether_type; | |||||||||
ovbcopy(eh, mtod(m, uint8_t *) + sizeof(struct llc), | ovbcopy(eh, mtod(m, uint8_t *) + sizeof(struct llc), | |||||||||
sizeof(struct ether_header)); | sizeof(struct ether_header)); | |||||||||
m_adj(m, sizeof(struct llc)); | m_adj(m, sizeof(struct llc)); | |||||||||
return m; | return m; | |||||||||
▲ Show 20 Lines • Show All 614 Lines • Show Last 20 Lines |
I made a comment in D30663 on this