Page MenuHomeFreeBSD

D49575.id152857.diff
No OneTemporary

D49575.id152857.diff

diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -2732,3 +2732,40 @@
*/
return (!ieee80211_is_key_global(vap, key));
}
+
+/**
+ * Determine whether the given control frame is from a known node
+ * and destined to us.
+ *
+ * In some instances a control frame won't have a TA (eg ACKs), so
+ * we should only verify the RA for those.
+ *
+ * @param ni ieee80211_node representing the sender, or BSS node
+ * @param m0 mbuf representing the 802.11 frame.
+ * @returns true if the frame is not a CTL frame (but with a warning
+ * logged);
+ * true if the frame is from a known sender / valid recipient,
+ * false otherwise.
+ */
+bool
+ieee80211_is_ctl_frame_for_vap(struct ieee80211_node *ni, const struct mbuf *m0)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ifnet *ifp = vap->iv_ifp;
+ const struct ieee80211_frame *wh;
+
+ wh = mtod(m0, const struct ieee80211_frame *);
+
+ /* Verify it's a ctl frame. */
+ if (!IEEE80211_IS_CTL(wh)) {
+ if_printf(vap->iv_ifp,
+ "%s: not a control frame (fc[0]=0x%04x)\n",
+ __func__, (wh)->i_fc[0]);
+ return (true);
+ }
+
+ /* TODO: verify the TA if the frame format has a TA */
+
+ /* Verify the RA */
+ return (IEEE80211_ADDR_EQ(wh->i_addr1, IF_LLADDR(ifp)));
+}
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
@@ -1047,6 +1047,16 @@
static void
adhoc_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+ struct ieee80211vap *vap = ni->ni_vap;
+ const struct ieee80211_frame *wh;
+
+ wh = mtod(m, const struct ieee80211_frame *);
+ if (! ieee80211_is_ctl_frame_for_vap(ni, m)) {
+ ic_printf(vap->iv_ic,
+ "%s: ignoring CTL frame (%d) not meant for us (%6D->%6D)\n",
+ __func__, subtype, wh->i_addr2, ":", wh->i_addr1, ":");
+ return;
+ }
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_BAR:
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
@@ -2418,6 +2418,17 @@
static void
hostap_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+ struct ieee80211vap *vap = ni->ni_vap;
+ const struct ieee80211_frame *wh;
+
+ wh = mtod(m, const struct ieee80211_frame *);
+ if (! ieee80211_is_ctl_frame_for_vap(ni, m)) {
+ ic_printf(vap->iv_ic,
+ "%s: ignoring CTL frame (%d) not meant for us (%6D->%6D)\n",
+ __func__, subtype, wh->i_addr2, ":", wh->i_addr1, ":");
+ return;
+ }
+
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_PS_POLL:
ni->ni_vap->iv_recv_pspoll(ni, m);
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
@@ -2089,6 +2089,17 @@
static void
mesh_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+ struct ieee80211vap *vap = ni->ni_vap;
+ const struct ieee80211_frame *wh;
+
+ wh = mtod(m, const struct ieee80211_frame *);
+ if (! ieee80211_is_ctl_frame_for_vap(ni, m)) {
+ ic_printf(vap->iv_ic,
+ "%s: ignoring CTL frame (%d) not meant for us (%6D->%6D)\n",
+ __func__, subtype, wh->i_addr2, ":", wh->i_addr1, ":");
+ return;
+ }
+
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_BAR:
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
@@ -2054,6 +2054,17 @@
static void
sta_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
{
+ struct ieee80211vap *vap = ni->ni_vap;
+ const struct ieee80211_frame *wh;
+
+ wh = mtod(m, const struct ieee80211_frame *);
+ if (! ieee80211_is_ctl_frame_for_vap(ni, m)) {
+ ic_printf(vap->iv_ic,
+ "%s: ignoring CTL frame (%d) not meant for us (%6D->%6D)\n",
+ __func__, subtype, wh->i_addr2, ":", wh->i_addr1, ":");
+ return;
+ }
+
switch (subtype) {
case IEEE80211_FC0_SUBTYPE_BAR:
ieee80211_recv_bar(ni, m);
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -842,6 +842,9 @@
bool ieee80211_is_key_unicast(const struct ieee80211vap *vap,
const struct ieee80211_key *key);
+bool ieee80211_is_ctl_frame_for_vap(struct ieee80211_node *,
+ const struct mbuf *);
+
void ieee80211_radiotap_attach(struct ieee80211com *,
struct ieee80211_radiotap_header *th, int tlen,
uint32_t tx_radiotap,

File Metadata

Mime Type
text/plain
Expires
Wed, May 20, 9:42 PM (11 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33358008
Default Alt Text
D49575.id152857.diff (4 KB)

Event Timeline