summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDamien Bergamini <damien@cvs.openbsd.org>2007-07-05 20:19:22 +0000
committerDamien Bergamini <damien@cvs.openbsd.org>2007-07-05 20:19:22 +0000
commit91ca040fb17d65d03622ac098ff823691e7210d6 (patch)
tree724caef1203e24bbf97e246f7492ef8f07ac54b9 /sys
parent9ffd9f4c30314b05e4b7c0c0aae0b76e7625022f (diff)
split ieee80211_add_rsn() so that the code can be reused for
vendor-specific IE.
Diffstat (limited to 'sys')
-rw-r--r--sys/net80211/ieee80211_output.c75
-rw-r--r--sys/net80211/ieee80211_proto.h4
-rw-r--r--sys/net80211/ieee80211_var.h3
3 files changed, 64 insertions, 18 deletions
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index a671a06c72e..fb7c7502ab0 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_output.c,v 1.40 2007/07/04 20:18:00 damien Exp $ */
+/* $OpenBSD: ieee80211_output.c,v 1.41 2007/07/05 20:19:21 damien Exp $ */
/* $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $ */
/*-
@@ -69,6 +69,8 @@ enum ieee80211_edca_ac ieee80211_up_to_ac(struct ieee80211com *, int);
struct mbuf *ieee80211_classify(struct ieee80211com *, struct mbuf *, int *);
int ieee80211_mgmt_output(struct ifnet *, struct ieee80211_node *,
struct mbuf *, int);
+u_int8_t *ieee80211_add_rsn_body(u_int8_t *, struct ieee80211com *,
+ const struct ieee80211_node *, int);
struct mbuf *ieee80211_getmbuf(int, int, u_int);
struct mbuf *ieee80211_get_probe_req(struct ieee80211com *,
struct ieee80211_node *);
@@ -812,20 +814,18 @@ ieee80211_add_qos_capability(u_int8_t *frm, struct ieee80211com *ic)
* Add an RSN element to a frame (see 7.3.2.25).
*/
u_int8_t *
-ieee80211_add_rsn(u_int8_t *frm, struct ieee80211com *ic,
- const struct ieee80211_node *ni)
+ieee80211_add_rsn_body(u_int8_t *frm, struct ieee80211com *ic,
+ const struct ieee80211_node *ni, int wpa1)
{
- u_int8_t *plen, *pcount;
+ const u_int8_t *oui = wpa1 ? MICROSOFT_OUI : IEEE80211_OUI;
+ u_int8_t *pcount;
u_int16_t count;
- *frm++ = IEEE80211_ELEMID_RSN;
- plen = frm++; /* length filled in later */
-
/* write Version field */
LE_WRITE_2(frm, 1); frm += 2;
/* write Group Cipher Suite field (see Table 20da) */
- memcpy(frm, IEEE80211_OUI, 3); frm += 3;
+ memcpy(frm, oui, 3); frm += 3;
switch (ni->ni_group_cipher) {
case IEEE80211_CIPHER_USEGROUP:
/* can't get there */
@@ -849,17 +849,17 @@ ieee80211_add_rsn(u_int8_t *frm, struct ieee80211com *ic,
count = 0;
/* write Pairwise Cipher Suite List */
if (ni->ni_pairwise_cipherset & IEEE80211_CIPHER_USEGROUP) {
- memcpy(frm, IEEE80211_OUI, 3); frm += 3;
+ memcpy(frm, oui, 3); frm += 3;
*frm++ = 0;
count++;
}
if (ni->ni_pairwise_cipherset & IEEE80211_CIPHER_TKIP) {
- memcpy(frm, IEEE80211_OUI, 3); frm += 3;
+ memcpy(frm, oui, 3); frm += 3;
*frm++ = 2;
count++;
}
if (ni->ni_pairwise_cipherset & IEEE80211_CIPHER_CCMP) {
- memcpy(frm, IEEE80211_OUI, 3); frm += 3;
+ memcpy(frm, oui, 3); frm += 3;
*frm++ = 3;
count++;
}
@@ -870,12 +870,12 @@ ieee80211_add_rsn(u_int8_t *frm, struct ieee80211com *ic,
count = 0;
/* write AKM Suite List (see Table 20dc) */
if (ni->ni_akmset & IEEE80211_AKM_IEEE8021X) {
- memcpy(frm, IEEE80211_OUI, 3); frm += 3;
+ memcpy(frm, oui, 3); frm += 3;
*frm++ = 1;
count++;
}
if (ni->ni_akmset & IEEE80211_AKM_PSK) {
- memcpy(frm, IEEE80211_OUI, 3); frm += 3;
+ memcpy(frm, oui, 3); frm += 3;
*frm++ = 2;
count++;
}
@@ -887,6 +887,40 @@ ieee80211_add_rsn(u_int8_t *frm, struct ieee80211com *ic,
/* no PMKID List for now */
+ return frm;
+}
+
+u_int8_t *
+ieee80211_add_rsn(u_int8_t *frm, struct ieee80211com *ic,
+ const struct ieee80211_node *ni)
+{
+ u_int8_t *plen;
+
+ *frm++ = IEEE80211_ELEMID_RSN;
+ plen = frm++; /* length filled in later */
+ frm = ieee80211_add_rsn_body(frm, ic, ni, 0);
+
+ /* write length field */
+ *plen = frm - plen + 1;
+ return frm;
+}
+
+/*
+ * Add a vendor specific WPA1 element to a frame.
+ * This is required for compatibility with Wi-Fi Alliance WPA1/WPA1+WPA2.
+ */
+u_int8_t *
+ieee80211_add_wpa1(u_int8_t *frm, struct ieee80211com *ic,
+ const struct ieee80211_node *ni)
+{
+ u_int8_t *plen;
+
+ *frm++ = IEEE80211_ELEMID_VENDOR;
+ plen = frm++; /* length filled in later */
+ memcpy(frm, MICROSOFT_OUI, 3); frm += 3;
+ *frm++ = 1; /* WPA1 */
+ frm = ieee80211_add_rsn_body(frm, ic, ni, 1);
+
/* write length field */
*plen = frm - plen + 1;
return frm;
@@ -991,7 +1025,8 @@ ieee80211_get_probe_resp(struct ieee80211com *ic, struct ieee80211_node *ni)
2 + 1 + /* extended rate phy (ERP) */
2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) +
2 + 44 + /* RSN (XXX 44) */
- 2 + 18); /* parameter set (EDCA) */
+ 2 + 18 + /* parameter set (EDCA) */
+ 2 + 48); /* WPA (XXX 48) */
if (m == NULL)
return NULL;
@@ -1021,6 +1056,8 @@ ieee80211_get_probe_resp(struct ieee80211com *ic, struct ieee80211_node *ni)
frm = ieee80211_add_rsn(frm, ic, ic->ic_bss);
if (ic->ic_flags & IEEE80211_F_QOS)
frm = ieee80211_add_edca_params(frm, ic);
+ if (ic->ic_flags & IEEE80211_F_WPA1)
+ frm = ieee80211_add_wpa1(frm, ic, ic->ic_bss);
m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
@@ -1130,7 +1167,8 @@ ieee80211_get_assoc_req(struct ieee80211com *ic, struct ieee80211_node *ni,
2 + IEEE80211_RATE_SIZE + /* supported rates */
2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) +
2 + 44 + /* RSN (XXX 44) */
- 2 + 1); /* QoS capability */
+ 2 + 1 + /* QoS capability */
+ 2 + 48); /* WPA (XXX 48) */
if (m == NULL)
return NULL;
@@ -1171,6 +1209,8 @@ ieee80211_get_assoc_req(struct ieee80211com *ic, struct ieee80211_node *ni,
if ((ic->ic_flags & IEEE80211_F_QOS) &&
(ni->ni_flags & IEEE80211_NODE_QOS))
frm = ieee80211_add_qos_capability(frm, ic);
+ if (ic->ic_flags & IEEE80211_F_WPA1)
+ frm = ieee80211_add_wpa1(frm, ic, ic->ic_bss);
m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
@@ -1436,7 +1476,8 @@ ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni)
2 + 1 + /* extended rate phy (ERP) */
2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE) +
2 + 44 + /* RSN (XXX 44) */
- 2 + 18); /* parameter set (EDCA) */
+ 2 + 18 + /* parameter set (EDCA) */
+ 2 + 48); /* WPA (XXX 48) */
if (m == NULL)
return NULL;
@@ -1481,6 +1522,8 @@ ieee80211_beacon_alloc(struct ieee80211com *ic, struct ieee80211_node *ni)
frm = ieee80211_add_rsn(frm, ic, ni);
if (ic->ic_flags & IEEE80211_F_QOS)
frm = ieee80211_add_edca_params(frm, ic);
+ if (ic->ic_flags & IEEE80211_F_WPA1)
+ frm = ieee80211_add_wpa1(frm, ic, ni);
m->m_pkthdr.len = m->m_len = frm - mtod(m, u_int8_t *);
m->m_pkthdr.rcvif = (void *)ni;
diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h
index 5cf24aa3016..902c9309fb1 100644
--- a/sys/net80211/ieee80211_proto.h
+++ b/sys/net80211/ieee80211_proto.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_proto.h,v 1.18 2007/07/03 19:44:54 damien Exp $ */
+/* $OpenBSD: ieee80211_proto.h,v 1.19 2007/07/05 20:19:21 damien Exp $ */
/* $NetBSD: ieee80211_proto.h,v 1.3 2003/10/13 04:23:56 dyoung Exp $ */
/*-
@@ -97,6 +97,8 @@ extern u_int8_t *ieee80211_add_qos_capability(u_int8_t *,
struct ieee80211com *);
extern u_int8_t *ieee80211_add_rsn(u_int8_t *, struct ieee80211com *,
const struct ieee80211_node *);
+extern u_int8_t *ieee80211_add_wpa1(u_int8_t *, struct ieee80211com *,
+ const struct ieee80211_node *);
extern u_int8_t *ieee80211_add_xrates(u_int8_t *,
const struct ieee80211_rateset *);
extern void ieee80211_print_essid(const u_int8_t *, int);
diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h
index 21cb221e4f1..0894f3e3a68 100644
--- a/sys/net80211/ieee80211_var.h
+++ b/sys/net80211/ieee80211_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_var.h,v 1.28 2007/07/04 20:16:25 damien Exp $ */
+/* $OpenBSD: ieee80211_var.h,v 1.29 2007/07/05 20:19:21 damien Exp $ */
/* $NetBSD: ieee80211_var.h,v 1.7 2004/05/06 03:07:10 dyoung Exp $ */
/*-
@@ -288,6 +288,7 @@ extern struct ieee80211com_head ieee80211com_head;
#define IEEE80211_F_QOS 0x00080000 /* CONF: QoS enabled */
#define IEEE80211_F_USEPROT 0x00100000 /* STATUS: protection enabled */
#define IEEE80211_F_RSN 0x00200000 /* CONF: RSN enabled */
+#define IEEE80211_F_WPA1 0x00400000 /* CONF: WPA1 enabled */
#define IEEE80211_F_USERMASK 0xf0000000 /* CONF: ioctl flag mask */
/* ic_caps */