Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Aug 2008 03:02:25 GMT
From:      Sam Leffler <sam@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 148767 for review
Message-ID:  <200808290302.m7T32P13033794@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=148767

Change 148767 by sam@sam_ebb on 2008/08/29 03:01:36

	update

Affected files ...

.. //depot/projects/vap/tools/regression/net80211/wep/test_wep.c#3 edit

Differences ...

==== //depot/projects/vap/tools/regression/net80211/wep/test_wep.c#3 (text+ko) ====

@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2004 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2008 Sam Leffler, Errno Consulting
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -54,8 +54,11 @@
 
 #include <net/if.h>
 #include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_clone.h>
 
 #include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_regdomain.h>
 
 /*
 MPDU data
@@ -177,18 +180,72 @@
 	dumpdata("Reference", ref, reflen);
 }
 
+static struct mbuf *
+formpacket(const struct ieee80211_cipher *cip, const void *plaintext,
+	int len, int remainder)
+{
+	struct mbuf *m, *n;
+	const uint8_t *p = plaintext;
+
+	printf("(packet %d+%d) ", len-remainder, remainder);
+
+	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+	KASSERT(m != NULL, ("cannot allocate mbuf!"));
+
+	m->m_data += cip->ic_header;
+	m_append(m, len-remainder, p);
+
+	if (remainder) {
+		n = m_get(M_NOWAIT, MT_DATA);
+		KASSERT(n != NULL, ("cannot split mbuf chain!"));
+		m_append(n, remainder, p + (len-remainder));
+		m->m_next = n;
+		m->m_pkthdr.len += remainder;
+	}
+
+	return m;
+}
+
+static int
+verifypacket(const struct mbuf *m, const void *data, int len, const char *what)
+{
+	void *buf;
+	int ok;
+
+	if (m->m_pkthdr.len != len) {
+		printf("FAIL: %s botch; length mismatch\n", what);
+		cmpfail(mtod(m, const void *), m->m_pkthdr.len, data, len);
+		return 0;
+	}
+
+	buf = malloc(m->m_pkthdr.len, M_TEMP, M_NOWAIT);
+	if (buf == NULL) {
+		printf("ERROR: cannot allocate temp buffer for packet check\n");
+		return 0;
+	}
+	m_copydata(m, 0, m->m_pkthdr.len, buf);
+	ok = (memcmp(buf, data, len) == 0);
+	free(buf, M_TEMP);
+	if (!ok) {
+		printf("FAIL: %s does not compare\n", what);
+		cmpfail(buf, m->m_pkthdr.len, data, len);
+	}
+	return ok;
+}
+
 struct wep_ctx_hw {			/* for use with h/w support */
-	struct ieee80211com *wc_ic;	/* for diagnostics */
+	struct ieee80211vap *wc_vap;	/* for diagnostics+statistics */
+	struct ieee80211com *wc_ic;
 	u_int32_t	wc_iv;		/* initial vector for crypto */
 };
 
 static int
-runtest(struct ieee80211com *ic, struct ciphertest *t)
+runtest(struct ieee80211vap *vap, struct ciphertest *t, int remainder)
 {
 	struct ieee80211_key key;
 	struct mbuf *m = NULL;
 	const struct ieee80211_cipher *cip;
-	u_int8_t mac[IEEE80211_ADDR_LEN];
+	int hdrlen, result = 0;
 	struct wep_ctx_hw *ctx;
 
 	printf("%s: ", t->name);
@@ -199,7 +256,7 @@
 	memset(&key, 0, sizeof(key));
 	key.wk_flags = IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV;
 	key.wk_cipher = &ieee80211_cipher_none;
-	if (!ieee80211_crypto_newkey(ic, t->cipher,
+	if (!ieee80211_crypto_newkey(vap, t->cipher,
 	    IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV, &key)) {
 		printf("FAIL: ieee80211_crypto_newkey failed\n");
 		goto bad;
@@ -207,25 +264,23 @@
 
 	memcpy(key.wk_key, t->key, t->key_len);
 	key.wk_keylen = t->key_len;
-	if (!ieee80211_crypto_setkey(ic, &key, mac)) {
+	if (!ieee80211_crypto_setkey(vap, &key)) {
 		printf("FAIL: ieee80211_crypto_setkey failed\n");
 		goto bad;
 	}
 	cip = key.wk_cipher;
 
 	/*
-	 * Craft frame from plaintext data.
+	 * Craft frame from encrypted data.
 	 */
 	cip = key.wk_cipher;
-	m = m_getcl(M_NOWAIT, MT_HEADER, M_PKTHDR);
-	memcpy(mtod(m, void *), t->encrypted, t->encrypted_len);
-	m->m_len = t->encrypted_len;
-	m->m_pkthdr.len = m->m_len;
+	m = formpacket(cip, t->encrypted, t->encrypted_len, remainder);
+	hdrlen = ieee80211_anyhdrsize(t->encrypted);
 
 	/*
 	 * Decrypt frame.
 	 */
-	if (!cip->ic_decap(&key, m)) {
+	if (!cip->ic_decap(&key, m, hdrlen)) {
 		printf("FAIL: wep decap failed\n");
 		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
 			t->plaintext, t->plaintext_len);
@@ -234,17 +289,8 @@
 	/*
 	 * Verify: frame length, frame contents.
 	 */
-	if (m->m_pkthdr.len != t->plaintext_len) {
-		printf("FAIL: decap botch; length mismatch\n");
-		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
-			t->plaintext, t->plaintext_len);
+	if (!verifypacket(m, t->plaintext, t->plaintext_len, "decap"))
 		goto bad;
-	} else if (memcmp(mtod(m, const void *), t->plaintext, t->plaintext_len)) {
-		printf("FAIL: decap botch; data does not compare\n");
-		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
-			t->plaintext, sizeof(t->plaintext));
-		goto bad;
-	}
 
 	/*
 	 * Encrypt frame.
@@ -258,27 +304,17 @@
 	/*
 	 * Verify: frame length, frame contents.
 	 */
-	if (m->m_pkthdr.len != t->encrypted_len) {
-		printf("FAIL: encap data length mismatch\n");
-		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
-			t->encrypted, t->encrypted_len);
-		goto bad;
-	} else if (memcmp(mtod(m, const void *), t->encrypted, m->m_pkthdr.len)) {
-		printf("FAIL: encrypt data does not compare\n");
-		cmpfail(mtod(m, const void *), m->m_pkthdr.len,
-			t->encrypted, t->encrypted_len);
+	if (!verifypacket(m, t->encrypted, t->encrypted_len, "encrypt data")) {
 		dumpdata("Plaintext", t->plaintext, t->plaintext_len);
 		goto bad;
 	}
-	m_freem(m);
-	ieee80211_crypto_delkey(ic, &key);
 	printf("PASS\n");
-	return 1;
+	result = 1;
 bad:
 	if (m != NULL)
 		m_freem(m);
-	ieee80211_crypto_delkey(ic, &key);
-	return 0;
+	ieee80211_crypto_delkey(vap, &key);
+	return result;
 }
 
 /*
@@ -288,27 +324,98 @@
 static	int tests = -1;
 static	int debug = 0;
 
+static struct ieee80211vap *
+fake_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
+	int opmode, int flags,
+	const uint8_t bssid[IEEE80211_ADDR_LEN],
+	const uint8_t mac[IEEE80211_ADDR_LEN])
+{
+	struct ieee80211vap *vap;
+
+	vap = malloc(sizeof(*vap), M_80211_VAP, M_WAITOK | M_ZERO);
+	ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac);
+	ieee80211_vap_attach(vap,
+	    ieee80211_media_change, ieee80211_media_status);
+	return vap;
+}
+
+static void
+fake_vap_delete(struct ieee80211vap *vap)
+{
+	ieee80211_vap_detach(vap);
+	free(vap, M_80211_VAP);
+}
+
 static int
 init_crypto_wep_test(void)
 {
 #define	N(a)	(sizeof(a)/sizeof(a[0]))
-	struct ieee80211com ic;
-	int i, pass, total;
+	struct ifnet *ifp, *vifp;
+	struct ieee80211com *ic;
+	struct ieee80211_clone_params icp;
+	char ifname[IFNAMSIZ];
+	struct ieee80211vap *vap;
+	int pass = 0, total = 0, i, error;
+	uint8_t bands;
+
+	ifp = if_alloc(IFT_IEEE80211);
+	if (ifp == NULL) {
+		printf("%s: unable to allocate ifnet!\n", __func__);
+		return -1;
+	}
+	if_initname(ifp, "fake", 0);
+	ifp->if_snd.ifq_maxlen = ifqmaxlen;
+
+	ic = ifp->if_l2com;
+	ic->ic_caps = IEEE80211_C_STA;
+	ic->ic_opmode = IEEE80211_M_STA;
+	ic->ic_vap_create = fake_vap_create;
+	ic->ic_vap_delete = fake_vap_delete;
+	bands = 0;
+	setbit(&bands, IEEE80211_MODE_11B);
+	ieee80211_init_channels(ic, NULL, &bands);
+	ieee80211_ifattach(ic);
+
+	memset(&icp, 0, sizeof(icp));
+	strlcpy(icp.icp_parent, ifp->if_xname, sizeof(icp.icp_parent));
+	icp.icp_opmode = IEEE80211_M_STA;
 
-	memset(&ic, 0, sizeof(ic));
+	strlcpy(ifname, "wlan", sizeof(ifname));
+	error = if_clone_create_sys(ifname, sizeof(ifname), (caddr_t) &icp);
+	if (error != 0) {
+		printf("%s: unable to clone vap (error %d)!\n",
+		    __func__, error);
+		pass = -1;
+		goto bad;
+	}
+	vifp = ifunit(ifname);
+	if (vifp == NULL) {
+		printf("%s: unable to locate vap %s!\n", __func__, ifname);
+		pass = -1;
+		goto bad;
+	}
+	vap = vifp->if_softc;
 	if (debug)
-		ic.ic_debug = IEEE80211_MSG_CRYPTO;
-	ieee80211_crypto_attach(&ic);
+		vap->iv_debug = IEEE80211_MSG_CRYPTO;
+
 	pass = 0;
 	total = 0;
 	for (i = 0; i < N(weptests); i++)
 		if (tests & (1<<i)) {
 			total++;
-			pass += runtest(&ic, &weptests[i]);
+			if (runtest(vap, &weptests[i], 0) &&
+			    runtest(vap, &weptests[i], 4) &&
+			    runtest(vap, &weptests[i], 5) &&
+			    runtest(vap, &weptests[i], 6) &&
+			    runtest(vap, &weptests[i], 7))
+				pass++;
 		}
 	printf("%u of %u 802.11i WEP test vectors passed\n", pass, total);
-	ieee80211_crypto_detach(&ic);
-	return (pass == total ? 0 : -1);
+bad:
+	ieee80211_ifdetach(ic);
+	if_free(ifp);
+
+	return (pass == -1 ? -1 : pass == total);
 #undef N
 }
 
@@ -317,7 +424,8 @@
 {
 	switch (type) {
 	case MOD_LOAD:
-		(void) init_crypto_wep_test();
+		if (init_crypto_wep_test() < 0)
+			return EIO;
 		return 0;
 	case MOD_UNLOAD:
 		return 0;
@@ -333,3 +441,4 @@
 DECLARE_MODULE(test_wep, test_wep_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
 MODULE_VERSION(test_wep, 1);
 MODULE_DEPEND(test_wep, wlan, 1, 1, 1);
+MODULE_DEPEND(test_wep, wlan_wep, 1, 1, 1);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808290302.m7T32P13033794>