Page MenuHomeFreeBSD

D30663.diff
No OneTemporary

D30663.diff

diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -531,7 +531,7 @@
* Next up, any fragmentation.
*/
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- m = ieee80211_defrag(ni, m, hdrspace);
+ m = ieee80211_defrag(ni, m, hdrspace, has_decrypted);
if (m == NULL) {
/* Fragment dropped or frame not complete yet */
goto out;
diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c
--- a/sys/net80211/ieee80211_hostap.c
+++ b/sys/net80211/ieee80211_hostap.c
@@ -719,7 +719,7 @@
* Next up, any fragmentation.
*/
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- m = ieee80211_defrag(ni, m, hdrspace);
+ m = ieee80211_defrag(ni, m, hdrspace, has_decrypted);
if (m == NULL) {
/* Fragment dropped or frame not complete yet */
goto out;
diff --git a/sys/net80211/ieee80211_input.h b/sys/net80211/ieee80211_input.h
--- a/sys/net80211/ieee80211_input.h
+++ b/sys/net80211/ieee80211_input.h
@@ -309,7 +309,7 @@
void ieee80211_deliver_data(struct ieee80211vap *,
struct ieee80211_node *, struct mbuf *);
struct mbuf *ieee80211_defrag(struct ieee80211_node *,
- struct mbuf *, int);
+ struct mbuf *, int, int);
struct mbuf *ieee80211_realign(struct ieee80211vap *, struct mbuf *, size_t);
struct mbuf *ieee80211_decap(struct ieee80211vap *, struct mbuf *, int);
struct mbuf *ieee80211_decap1(struct mbuf *, int *);
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -170,7 +170,8 @@
* XXX should handle 3 concurrent reassemblies per-spec.
*/
struct mbuf *
-ieee80211_defrag(struct ieee80211_node *ni, struct mbuf *m, int hdrspace)
+ieee80211_defrag(struct ieee80211_node *ni, struct mbuf *m, int hdrspace,
+ int has_decrypted)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
@@ -189,6 +190,11 @@
if (!more_frag && fragno == 0 && ni->ni_rxfrag[0] == NULL)
return m;
+ /* Temporarily set flag to remember if fragment was encrypted. */
+ /* XXX use a non-packet altering storage for this in the future. */
+ if (has_decrypted)
+ wh->i_fc[1] |= IEEE80211_FC1_PROTECTED;
+
/*
* Remove frag to insure it doesn't get reaped by timer.
*/
@@ -219,10 +225,14 @@
lwh = mtod(mfrag, struct ieee80211_frame *);
last_rxseq = le16toh(*(uint16_t *)lwh->i_seq);
- /* NB: check seq # and frag together */
+ /*
+ * NB: check seq # and frag together. Also check that both
+ * fragments are plaintext or that both are encrypted.
+ */
if (rxseq == last_rxseq+1 &&
IEEE80211_ADDR_EQ(wh->i_addr1, lwh->i_addr1) &&
- IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2)) {
+ IEEE80211_ADDR_EQ(wh->i_addr2, lwh->i_addr2) &&
+ !((wh->i_fc[1] ^ lwh->i_fc[1]) & IEEE80211_FC1_PROTECTED)) {
/* XXX clear MORE_FRAG bit? */
/* track last seqnum and fragno */
*(uint16_t *) lwh->i_seq = *(uint16_t *) wh->i_seq;
@@ -253,6 +263,11 @@
ni->ni_rxfrag[0] = mfrag;
mfrag = NULL;
}
+ /* Remember to clear protected flag that was temporarily set. */
+ if (mfrag != NULL) {
+ wh = mtod(mfrag, struct ieee80211_frame *);
+ wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
+ }
return mfrag;
}
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -1641,7 +1641,7 @@
*/
hdrspace = ieee80211_hdrspace(ic, wh);
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- m = ieee80211_defrag(ni, m, hdrspace);
+ m = ieee80211_defrag(ni, m, hdrspace, 0);
if (m == NULL) {
/* Fragment dropped or frame not complete yet */
goto out;
diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c
--- a/sys/net80211/ieee80211_sta.c
+++ b/sys/net80211/ieee80211_sta.c
@@ -795,7 +795,7 @@
* Next up, any fragmentation.
*/
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- m = ieee80211_defrag(ni, m, hdrspace);
+ m = ieee80211_defrag(ni, m, hdrspace, has_decrypted);
if (m == NULL) {
/* Fragment dropped or frame not complete yet */
goto out;
diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c
--- a/sys/net80211/ieee80211_wds.c
+++ b/sys/net80211/ieee80211_wds.c
@@ -594,7 +594,7 @@
* Next up, any fragmentation.
*/
if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- m = ieee80211_defrag(ni, m, hdrspace);
+ m = ieee80211_defrag(ni, m, hdrspace, has_decrypted);
if (m == NULL) {
/* Fragment dropped or frame not complete yet */
goto out;

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 5, 6:40 PM (4 h, 25 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29276098
Default Alt Text
D30663.diff (4 KB)

Event Timeline