summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_mesh.c
diff options
context:
space:
mode:
authormonthadar <monthadar@FreeBSD.org>2012-05-01 15:39:16 +0000
committermonthadar <monthadar@FreeBSD.org>2012-05-01 15:39:16 +0000
commit9d51d66dc0ef2e7c01208283595f080688e7a80e (patch)
tree18624426040b42cce0500934b9dc72ba5bb36b74 /sys/net80211/ieee80211_mesh.c
parent3b1abc639022bf902ec77bd4657fd906ef5264c0 (diff)
downloadFreeBSD-src-9d51d66dc0ef2e7c01208283595f080688e7a80e.zip
FreeBSD-src-9d51d66dc0ef2e7c01208283595f080688e7a80e.tar.gz
Modified structure and code that handles Mesh peering management.
* Old struct ieee80211_meshpeer_ie had wrong peer_proto field size; * Added IEEE80211_MPM_* size macros; * Created an enum for the Mesh Peering Protocol Identifier field according to the standard spec and removed old defines; * Abbreviated Handshake Protocol is not used by the standard anymore; * Modified mesh_verify_meshpeer to use IEEE80211_MPM_* macros for verification; * Modified mesh_parse_meshpeering_action to parse complete frame, also to parse it according to the standard spec; * Modified ieee80211_add_meshpeer to construct correct MPM frames according to the standard spec; Approved by: adrian
Diffstat (limited to 'sys/net80211/ieee80211_mesh.c')
-rw-r--r--sys/net80211/ieee80211_mesh.c77
1 files changed, 46 insertions, 31 deletions
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 0a66491..13ca62a 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -1573,8 +1573,7 @@ mesh_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
}
/*
- * Parse meshpeering action ie's for open+confirm frames; the
- * important bits are returned in the supplied structure.
+ * Parse meshpeering action ie's for open+confirm frames
*/
static const struct ieee80211_meshpeer_ie *
mesh_parse_meshpeering_action(struct ieee80211_node *ni,
@@ -1600,15 +1599,27 @@ mesh_parse_meshpeering_action(struct ieee80211_node *ni,
meshpeer = frm;
mpie = (const struct ieee80211_meshpeer_ie *) frm;
memset(mp, 0, sizeof(*mp));
+ mp->peer_proto = LE_READ_2(&mpie->peer_proto);
mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid);
- /* NB: peer link ID is optional on these frames */
- if (subtype == IEEE80211_ACTION_MESHPEERING_CLOSE &&
- mpie->peer_len == 8) {
- mp->peer_linkid = 0;
- mp->peer_rcode = LE_READ_2(&mpie->peer_linkid);
- } else {
- mp->peer_linkid = LE_READ_2(&mpie->peer_linkid);
- mp->peer_rcode = LE_READ_2(&mpie->peer_rcode);
+ switch (subtype) {
+ case IEEE80211_ACTION_MESHPEERING_CONFIRM:
+ mp->peer_linkid =
+ LE_READ_2(&mpie->peer_linkid);
+ break;
+ case IEEE80211_ACTION_MESHPEERING_CLOSE:
+ /* NB: peer link ID is optional */
+ if (mpie->peer_len ==
+ (IEEE80211_MPM_BASE_SZ + 2)) {
+ mp->peer_linkid = 0;
+ mp->peer_rcode =
+ LE_READ_2(&mpie->peer_linkid);
+ } else {
+ mp->peer_linkid =
+ LE_READ_2(&mpie->peer_linkid);
+ mp->peer_rcode =
+ LE_READ_2(&mpie->peer_rcode);
+ }
+ break;
}
break;
}
@@ -2337,22 +2348,31 @@ mesh_verify_meshpeer(struct ieee80211vap *vap, uint8_t subtype,
const struct ieee80211_meshpeer_ie *meshpeer =
(const struct ieee80211_meshpeer_ie *) ie;
- if (meshpeer == NULL || meshpeer->peer_len < 6 ||
- meshpeer->peer_len > 10)
+ if (meshpeer == NULL ||
+ meshpeer->peer_len < IEEE80211_MPM_BASE_SZ ||
+ meshpeer->peer_len > IEEE80211_MPM_MAX_SZ)
+ return 1;
+ if (meshpeer->peer_proto != IEEE80211_MPPID_MPM) {
+ IEEE80211_DPRINTF(vap,
+ IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
+ "Only MPM protocol is supported (proto: 0x%02X)",
+ meshpeer->peer_proto);
return 1;
+ }
switch (subtype) {
case IEEE80211_ACTION_MESHPEERING_OPEN:
- if (meshpeer->peer_len != 6)
+ if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ)
return 1;
break;
case IEEE80211_ACTION_MESHPEERING_CONFIRM:
- if (meshpeer->peer_len != 8)
+ if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ + 2)
return 1;
break;
case IEEE80211_ACTION_MESHPEERING_CLOSE:
- if (meshpeer->peer_len < 8)
+ if (meshpeer->peer_len < IEEE80211_MPM_BASE_SZ + 2)
return 1;
- if (meshpeer->peer_len == 8 && meshpeer->peer_linkid != 0)
+ if (meshpeer->peer_len == (IEEE80211_MPM_BASE_SZ + 2) &&
+ meshpeer->peer_linkid != 0)
return 1;
if (meshpeer->peer_rcode == 0)
return 1;
@@ -2418,34 +2438,29 @@ uint8_t *
ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid,
uint16_t peerid, uint16_t reason)
{
- /* XXX change for AH */
- static const uint8_t meshpeerproto[4] = IEEE80211_MESH_PEER_PROTO;
KASSERT(localid != 0, ("localid == 0"));
*frm++ = IEEE80211_ELEMID_MESHPEER;
switch (subtype) {
case IEEE80211_ACTION_MESHPEERING_OPEN:
- *frm++ = 6; /* length */
- memcpy(frm, meshpeerproto, 4);
- frm += 4;
- ADDSHORT(frm, localid); /* local ID */
+ *frm++ = IEEE80211_MPM_BASE_SZ; /* length */
+ ADDSHORT(frm, IEEE80211_MPPID_MPM); /* proto */
+ ADDSHORT(frm, localid); /* local ID */
break;
case IEEE80211_ACTION_MESHPEERING_CONFIRM:
KASSERT(peerid != 0, ("sending peer confirm without peer id"));
- *frm++ = 8; /* length */
- memcpy(frm, meshpeerproto, 4);
- frm += 4;
- ADDSHORT(frm, localid); /* local ID */
- ADDSHORT(frm, peerid); /* peer ID */
+ *frm++ = IEEE80211_MPM_BASE_SZ + 2; /* length */
+ ADDSHORT(frm, IEEE80211_MPPID_MPM); /* proto */
+ ADDSHORT(frm, localid); /* local ID */
+ ADDSHORT(frm, peerid); /* peer ID */
break;
case IEEE80211_ACTION_MESHPEERING_CLOSE:
if (peerid)
- *frm++ = 10; /* length */
+ *frm++ = IEEE80211_MPM_MAX_SZ; /* length */
else
- *frm++ = 8; /* length */
- memcpy(frm, meshpeerproto, 4);
- frm += 4;
+ *frm++ = IEEE80211_MPM_BASE_SZ + 2; /* length */
+ ADDSHORT(frm, IEEE80211_MPPID_MPM); /* proto */
ADDSHORT(frm, localid); /* local ID */
if (peerid)
ADDSHORT(frm, peerid); /* peer ID */
OpenPOWER on IntegriCloud