diff options
author | monthadar <monthadar@FreeBSD.org> | 2012-05-01 15:39:16 +0000 |
---|---|---|
committer | monthadar <monthadar@FreeBSD.org> | 2012-05-01 15:39:16 +0000 |
commit | 9d51d66dc0ef2e7c01208283595f080688e7a80e (patch) | |
tree | 18624426040b42cce0500934b9dc72ba5bb36b74 /sys/net80211/ieee80211_mesh.c | |
parent | 3b1abc639022bf902ec77bd4657fd906ef5264c0 (diff) | |
download | FreeBSD-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.c | 77 |
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 */ |