[4/5] ieee80211: ethernet independency

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Makes the 802.11 layer independent of ethernet. (The previous implementation
had the ethernet headers built by the ethernet layer and then parsed them and
rebuilt them into 802.11 headers.)


Signed-off-by: Jiri Benc <[email protected]>
Signed-off-by: Jirka Bohac <[email protected]>

--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -83,13 +83,18 @@
  *	used.
  */
  
-#if !defined(CONFIG_AX25) && !defined(CONFIG_AX25_MODULE) && !defined(CONFIG_TR)
+#if !defined(CONFIG_AX25) && !defined(CONFIG_AX25_MODULE) && !defined(CONFIG_TR) \
+	&& !defined(CONFIG_IEEE80211)
 #define LL_MAX_HEADER	32
 #else
 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
 #define LL_MAX_HEADER	96
 #else
+#if defined(CONFIG_TR)
 #define LL_MAX_HEADER	48
+#else
+#define LL_MAX_HEADER	38
+#endif
 #endif
 #endif
 
--- a/include/net/ieee80211.h
+++ b/include/net/ieee80211.h
@@ -20,7 +20,6 @@
  */
 #ifndef IEEE80211_H
 #define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
 #include <linux/kernel.h>   /* ARRAY_SIZE */
 
 #if WIRELESS_EXT < 17
@@ -42,25 +41,26 @@
    WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
 
 
+#define IEEE80211_ALEN			6
 #define IEEE80211_HLEN			30
 #define IEEE80211_FRAME_LEN		(IEEE80211_DATA_LEN + IEEE80211_HLEN)
 
 struct ieee80211_hdr {
 	u16 frame_ctl;
 	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
+	u8 addr1[IEEE80211_ALEN];
+	u8 addr2[IEEE80211_ALEN];
+	u8 addr3[IEEE80211_ALEN];
 	u16 seq_ctl;
-	u8 addr4[ETH_ALEN];
+	u8 addr4[IEEE80211_ALEN];
 } __attribute__ ((packed));
 
 struct ieee80211_hdr_3addr {
 	u16 frame_ctl;
 	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
+	u8 addr1[IEEE80211_ALEN];
+	u8 addr2[IEEE80211_ALEN];
+	u8 addr3[IEEE80211_ALEN];
 	u16 seq_ctl;
 } __attribute__ ((packed));
 
@@ -233,7 +233,7 @@
 #define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
 
 #ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
+#define ETH_P_80211_RAW 0x0003
 #endif
 
 /* IEEE 802.11 defines */
@@ -246,11 +246,29 @@
         u8    ssap;   /* always 0xAA */
         u8    ctrl;   /* always 0x03 */
         u8    oui[P80211_OUI_LEN];    /* organizational universal id */
+	u16   type;   /* packet type ID field */
 
 } __attribute__ ((packed));
 
 #define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
 
+#define IEEE80211_SNAP_IS_RFC1042(snap) \
+		((snap)->oui[0] == 0 && (snap)->oui[1] == 0 && (snap)->oui[2] == 0)
+#define IEEE80211_SNAP_IS_BRIDGE_TUNNEL(snap) \
+		((snap)->oui[0] == 0 && (snap)->oui[1] == 0 && (snap)->oui[2] == 0xf8)
+
+#define IEEE80211_FC_GET_TODS(hdr) \
+		((hdr)->frame_ctl & __constant_cpu_to_le16(IEEE80211_FCTL_TODS))
+#define IEEE80211_FC_GET_FROMDS(hdr) \
+		((hdr)->frame_ctl & __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS))
+#define IEEE80211_GET_DADDR(hdr) \
+		(IEEE80211_FC_GET_TODS(hdr) ? (hdr)->addr3 : (hdr)->addr1)
+#define IEEE80211_GET_SADDR(hdr) \
+		(IEEE80211_FC_GET_FROMDS(hdr) ? \
+			(IEEE80211_FC_GET_TODS(hdr) ? (hdr)->addr4 : (hdr)->addr3) \
+			: (hdr)->addr2)
+/* IEEE80211_GET_xADDR do not work when both TODS and FROMDS are set. */
+
 #define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
 #define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
 
@@ -395,8 +413,8 @@
 	unsigned int seq;
 	unsigned int last_frag;
 	struct sk_buff *skb;
-	u8 src_addr[ETH_ALEN];
-	u8 dst_addr[ETH_ALEN];
+	u8 src_addr[IEEE80211_ALEN];
+	u8 dst_addr[IEEE80211_ALEN];
 };
 
 struct ieee80211_stats {
@@ -507,7 +525,7 @@
 	u16 auth_sequence;
 	u16 beacon_interval;
 	u16 capability;
-	u8 current_ap[ETH_ALEN];
+	u8 current_ap[IEEE80211_ALEN];
 	u16 listen_interval;
 	struct {
 		u16 association_id:14, reserved:2;
@@ -537,7 +555,7 @@
 struct ieee80211_assoc_request_frame {
 	u16 capability;
 	u16 listen_interval;
-	u8 current_ap[ETH_ALEN];
+	u8 current_ap[IEEE80211_ALEN];
 	struct ieee80211_info_element info_element;
 } __attribute__ ((packed));
 
@@ -581,7 +599,7 @@
 
 struct ieee80211_network {
 	/* These entries are used to identify a unique network */
-	u8 bssid[ETH_ALEN];
+	u8 bssid[IEEE80211_ALEN];
 	u8 channel;
 	/* Ensure null-terminated for any debug msgs */
 	u8 ssid[IW_ESSID_MAX_SIZE + 1];
@@ -625,12 +643,12 @@
 #define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
 
 
-extern inline int is_multicast_ether_addr(const u8 *addr)
+extern inline int is_multicast_ieee80211_addr(const u8 *addr)
 {
 	return ((addr[0] != 0xff) && (0x01 & addr[0]));
 }
 
-extern inline int is_broadcast_ether_addr(const u8 *addr)
+extern inline int is_broadcast_ieee80211_addr(const u8 *addr)
 {
 	return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&   \
 		(addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
@@ -694,7 +712,7 @@
 	u16 fts; /* Fragmentation Threshold */
 
 	/* Association info */
-	u8 bssid[ETH_ALEN];
+	u8 bssid[IEEE80211_ALEN];
 
 	enum ieee80211_state state;
 
@@ -774,7 +792,7 @@
 	return 0;
 }
 
-extern inline int ieee80211_get_hdrlen(u16 fc)
+extern inline int __ieee80211_get_hdrlen(u16 fc)
 {
 	int hdrlen = IEEE80211_3ADDR_LEN;
 
@@ -798,12 +816,29 @@
 
 	return hdrlen;
 }
+#define ieee80211_get_hdrlen(hdr) __ieee80211_get_hdrlen(le16_to_cpu((hdr)->frame_ctl))
+
+#define IEEE80211_GET_DATA_HDR_LEN(hdr) \
+		((((hdr)->frame_ctl & \
+			__constant_cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) \
+		 == __constant_cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) \
+		 ? IEEE80211_4ADDR_LEN : IEEE80211_3ADDR_LEN)
+#define IEEE80211_GET_SNAP(hdr) \
+		((struct ieee80211_snap_hdr *) \
+		((u8 *)(hdr) + IEEE80211_GET_DATA_HDR_LEN(hdr)))
 
+extern inline int ieee80211_get_proto(struct ieee80211_hdr *header)
+{
+	struct ieee80211_snap_hdr *snap = IEEE80211_GET_SNAP(header);
+	return (snap->dsap == 0xaa && snap->ssap == 0xaa ?
+		ntohs(snap->type) : ETH_P_802_2);
+}
 
 
 /* ieee80211.c */
 extern void free_ieee80211(struct ieee80211_device *ieee);
 extern struct ieee80211_device *alloc_ieee80211(int sizeof_priv);
+extern void ieee80211_setup(struct net_device *dev);
 
 extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
 
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -42,11 +42,10 @@
 					struct ieee80211_rx_stats *rx_stats)
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	u16 fc = le16_to_cpu(hdr->frame_ctl);
 
 	skb->dev = ieee->dev;
 	skb->mac.raw = skb->data;
-	skb_pull(skb, ieee80211_get_hdrlen(fc));
+	skb_pull(skb, ieee80211_get_hdrlen(hdr));
 	skb->pkt_type = PACKET_OTHERHOST;
 	skb->protocol = __constant_htons(ETH_P_80211_RAW);
 	memset(skb->cb, 0, sizeof(skb->cb));
@@ -76,8 +75,8 @@
 
 		if (entry->skb != NULL && entry->seq == seq &&
 		    (entry->last_frag + 1 == frag || frag == -1) &&
-		    memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
-		    memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
+		    memcmp(entry->src_addr, src, IEEE80211_ALEN) == 0 &&
+		    memcmp(entry->dst_addr, dst, IEEE80211_ALEN) == 0)
 			return entry;
 	}
 
@@ -104,7 +103,7 @@
 				    sizeof(struct ieee80211_hdr) +
 				    8 /* LLC */ +
 				    2 /* alignment */ +
-				    8 /* WEP */ + ETH_ALEN /* WDS */);
+				    8 /* WEP */ + IEEE80211_ALEN /* WDS */);
 		if (skb == NULL)
 			return NULL;
 
@@ -120,8 +119,8 @@
 		entry->seq = seq;
 		entry->last_frag = frag;
 		entry->skb = skb;
-		memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
-		memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
+		memcpy(entry->src_addr, hdr->addr2, IEEE80211_ALEN);
+		memcpy(entry->dst_addr, hdr->addr1, IEEE80211_ALEN);
 	} else {
 		/* received a fragment of a frame for which the head fragment
 		 * should have already been received */
@@ -221,15 +220,6 @@
 #endif
 
 
-/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
-/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static unsigned char bridge_tunnel_header[] =
-{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-/* No encapsulation header if EtherType < 0x600 (=length) */
-
 /* Called by ieee80211_rx_frame_decrypt */
 static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
 				    struct sk_buff *skb)
@@ -237,7 +227,6 @@
 	struct net_device *dev = ieee80211_dev(ieee);
 	u16 fc, ethertype;
 	struct ieee80211_hdr *hdr;
-	u8 *pos;
 
 	if (skb->len < 24)
 		return 0;
@@ -248,12 +237,12 @@
 	/* check that the frame is unicast frame to us */
 	if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 	    IEEE80211_FCTL_TODS &&
-	    memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
-	    memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
+	    memcmp(hdr->addr1, dev->dev_addr, IEEE80211_ALEN) == 0 &&
+	    memcmp(hdr->addr3, dev->dev_addr, IEEE80211_ALEN) == 0) {
 		/* ToDS frame with own addr BSSID and DA */
 	} else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
 		   IEEE80211_FCTL_FROMDS &&
-		   memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
+		   memcmp(hdr->addr1, dev->dev_addr, IEEE80211_ALEN) == 0) {
 		/* FromDS frame with own addr as DA */
 	} else
 		return 0;
@@ -262,8 +251,7 @@
 		return 0;
 
 	/* check for port access entity Ethernet type */
-	pos = skb->data + 24;
-	ethertype = (pos[6] << 8) | pos[7];
+	ethertype = ieee80211_get_proto(hdr);
 	if (ethertype == ETH_P_PAE)
 		return 1;
 
@@ -282,7 +270,7 @@
 		return 0;
 
 	hdr = (struct ieee80211_hdr *) skb->data;
-	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+	hdrlen = ieee80211_get_hdrlen(hdr);
 
 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
 	if (ieee->tkip_countermeasures &&
@@ -327,7 +315,7 @@
 		return 0;
 
 	hdr = (struct ieee80211_hdr *) skb->data;
-	hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
+	hdrlen = ieee80211_get_hdrlen(hdr);
 
 	atomic_inc(&crypt->refcnt);
 	res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
@@ -343,6 +331,44 @@
 }
 
 
+unsigned short ieee80211_type_trans(struct sk_buff *skb,
+		struct ieee80211_device *ieee)
+{
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+	struct ieee80211_snap_hdr *snap;
+	int hdrlen;
+	u8 *daddr = IEEE80211_GET_DADDR(hdr);
+	unsigned short type;
+
+	skb->mac.raw = skb->data;
+
+	hdrlen = ieee80211_get_hdrlen(hdr);
+	snap = (struct ieee80211_snap_hdr *)(skb->data + hdrlen);
+	if (snap->dsap == 0xaa && snap->ssap == 0xaa &&
+			((IEEE80211_SNAP_IS_RFC1042(snap) &&
+			  snap->type != __constant_htons(ETH_P_AARP) &&
+			  snap->type != __constant_htons(ETH_P_IPX)) ||
+			 IEEE80211_SNAP_IS_BRIDGE_TUNNEL(snap))) {
+		type = snap->type;
+		skb_pull(skb, hdrlen + SNAP_SIZE);
+	}
+	else {
+		type = __constant_htons(ETH_P_802_2);
+		skb_pull(skb, hdrlen);
+	}
+
+	skb->input_dev = ieee->dev;
+	if (is_broadcast_ieee80211_addr(daddr))
+		skb->pkt_type = PACKET_BROADCAST;
+	else if (is_multicast_ieee80211_addr(daddr))
+		skb->pkt_type = PACKET_MULTICAST;
+	else if (memcmp(daddr, ieee->dev->dev_addr, IEEE80211_ALEN))
+		skb->pkt_type = PACKET_OTHERHOST;
+
+	return type;
+}
+
+
 /* All received frames are sent to this function. @skb contains the frame in
  * IEEE 802.11 format, i.e., in the format it was sent over air.
  * This function is called only as a tasklet (software IRQ). */
@@ -355,8 +381,6 @@
 	u16 fc, type, stype, sc;
 	struct net_device_stats *stats;
 	unsigned int frag;
-	u8 *payload;
-	u16 ethertype;
 #ifdef NOT_YET
 	struct net_device *wds = NULL;
 	struct sk_buff *skb2 = NULL;
@@ -365,8 +389,8 @@
 	int from_assoc_ap = 0;
 	void *sta = NULL;
 #endif
-	u8 dst[ETH_ALEN];
-	u8 src[ETH_ALEN];
+	u8 dst[IEEE80211_ALEN];
+	u8 src[IEEE80211_ALEN];
 	struct ieee80211_crypt_data *crypt = NULL;
 	int keyidx = 0;
 
@@ -384,7 +408,7 @@
 	stype = WLAN_FC_GET_STYPE(fc);
 	sc = le16_to_cpu(hdr->seq_ctl);
 	frag = WLAN_GET_SEQ_FRAG(sc);
-	hdrlen = ieee80211_get_hdrlen(fc);
+	hdrlen = __ieee80211_get_hdrlen(fc);
 
 #ifdef NOT_YET
 #if WIRELESS_EXT > 15
@@ -480,22 +504,23 @@
 
 	switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
 	case IEEE80211_FCTL_FROMDS:
-		memcpy(dst, hdr->addr1, ETH_ALEN);
-		memcpy(src, hdr->addr3, ETH_ALEN);
+		memcpy(dst, hdr->addr1, IEEE80211_ALEN);
+		memcpy(src, hdr->addr3, IEEE80211_ALEN);
 		break;
 	case IEEE80211_FCTL_TODS:
-		memcpy(dst, hdr->addr3, ETH_ALEN);
-		memcpy(src, hdr->addr2, ETH_ALEN);
+		memcpy(dst, hdr->addr3, IEEE80211_ALEN);
+		memcpy(src, hdr->addr2, IEEE80211_ALEN);
 		break;
 	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
 		if (skb->len < IEEE80211_4ADDR_LEN)
 			goto rx_dropped;
-		memcpy(dst, hdr->addr3, ETH_ALEN);
-		memcpy(src, hdr->addr4, ETH_ALEN);
+		memcpy(dst, hdr->addr3, IEEE80211_ALEN);
+		memcpy(src, hdr->addr4, IEEE80211_ALEN);
+		/* FIXME: this is wrong */
 		break;
 	case 0:
-		memcpy(dst, hdr->addr1, ETH_ALEN);
-		memcpy(src, hdr->addr2, ETH_ALEN);
+		memcpy(dst, hdr->addr1, IEEE80211_ALEN);
+		memcpy(src, hdr->addr2, IEEE80211_ALEN);
 		break;
 	}
 
@@ -510,7 +535,7 @@
 	if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
 	    (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
 	    ieee->stadev &&
-	    memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
+	    memcmp(hdr->addr2, ieee->assoc_ap_addr, IEEE80211_ALEN) == 0) {
 		/* Frame from BSSID of the AP for which we are a client */
 		skb->dev = dev = ieee->stadev;
 		stats = hostap_get_stats(dev);
@@ -668,9 +693,6 @@
 
 	/* skb: hdr + (possible reassembled) full plaintext payload */
 
-	payload = skb->data + hdrlen;
-	ethertype = (payload[6] << 8) | payload[7];
-
 #ifdef NOT_YET
 	/* If IEEE 802.1X is used, check whether the port is authorized to send
 	 * the received frame. */
@@ -697,38 +719,6 @@
 	}
 #endif
 
-	/* convert hdr + possible LLC headers into Ethernet header */
-	if (skb->len - hdrlen >= 8 &&
-	    ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
-	      ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
-	     memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
-		/* remove RFC1042 or Bridge-Tunnel encapsulation and
-		 * replace EtherType */
-		skb_pull(skb, hdrlen + SNAP_SIZE);
-		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
-		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
-	} else {
-		u16 len;
-		/* Leave Ethernet header part of hdr and full payload */
-		skb_pull(skb, hdrlen);
-		len = htons(skb->len);
-		memcpy(skb_push(skb, 2), &len, 2);
-		memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
-		memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
-	}
-
-#ifdef NOT_YET
-	if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
-		    IEEE80211_FCTL_TODS) &&
-	    skb->len >= ETH_HLEN + ETH_ALEN) {
-		/* Non-standard frame: get addr4 from its bogus location after
-		 * the payload */
-		memcpy(skb->data + ETH_ALEN,
-		       skb->data + skb->len - ETH_ALEN, ETH_ALEN);
-		skb_trim(skb, skb->len - ETH_ALEN);
-	}
-#endif
-
 	stats->rx_packets++;
 	stats->rx_bytes += skb->len;
 
@@ -754,7 +744,7 @@
 
 	if (skb2 != NULL) {
 		/* send to wireless media */
-		skb2->protocol = __constant_htons(ETH_P_802_3);
+		skb2->protocol = ieee80211_type_trans(skb2, ieee);
 		skb2->mac.raw = skb2->nh.raw = skb2->data;
 		/* skb2->nh.raw = skb2->data + ETH_HLEN; */
 		skb2->dev = dev;
@@ -764,7 +754,7 @@
 #endif
 
 	if (skb) {
-		skb->protocol = eth_type_trans(skb, dev);
+		skb->protocol = ieee80211_type_trans(skb, ieee);
 		memset(skb->cb, 0, sizeof(skb->cb));
 		skb->dev = dev;
 		skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
@@ -821,7 +811,7 @@
 	u8 i;
 
 	/* Pull out fixed field data */
-	memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
+	memcpy(network->bssid, beacon->header.addr3, IEEE80211_ALEN);
 	network->capability = beacon->capability;
 	network->last_scanned = jiffies;
 	network->time_stamp[0] = beacon->time_stamp[0];
@@ -849,7 +839,7 @@
 	while (left >= sizeof(struct ieee80211_info_element_hdr)) {
 		if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
 			IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
-					     info_element->len + sizeof(struct ieee80211_info_element),
+					     info_element->len + (int)sizeof(struct ieee80211_info_element),
 					     left);
 			return 1;
                	}
@@ -1017,7 +1007,7 @@
 	 * as one network */
 	return ((src->ssid_len == dst->ssid_len) &&
 		(src->channel == dst->channel) &&
-		!memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
+		!memcmp(src->bssid, dst->bssid, IEEE80211_ALEN) &&
 		!memcmp(src->ssid, dst->ssid, src->ssid_len));
 }
 
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -48,7 +48,6 @@
 #include <linux/types.h>
 #include <linux/version.h>
 #include <linux/wireless.h>
-#include <linux/etherdevice.h>
 #include <asm/uaccess.h>
 #include <net/arp.h>
 
@@ -99,28 +98,230 @@
 }
 
 
+static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
+{
+	if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN - 8 - SNAP_SIZE))
+		return -EINVAL;
+	dev->mtu = new_mtu;
+	return 0;
+}
+
+
+static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
+static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
+
+static inline int __ieee80211_put_snap(u8 *data, u16 h_proto)
+{
+	struct ieee80211_snap_hdr *snap;
+	u8 *oui;
+
+	snap = (struct ieee80211_snap_hdr *)data;
+	snap->dsap = 0xaa;
+	snap->ssap = 0xaa;
+	snap->ctrl = 0x03;
+
+	if (h_proto == __constant_htons(ETH_P_IPX) ||
+			h_proto == __constant_htons(ETH_P_AARP))
+		oui = P802_1H_OUI;
+	else
+		oui = RFC1042_OUI;
+	snap->oui[0] = oui[0];
+	snap->oui[1] = oui[1];
+	snap->oui[2] = oui[2];
+
+	snap->type = h_proto;
+
+	return SNAP_SIZE;
+}
+
+static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
+{
+	return __ieee80211_put_snap(data, htons(h_proto));
+}
+
+/*
+ *       Create the IEEE 802.11 MAC header for an arbitrary protocol layer
+ *
+ *      saddr=NULL      means use device source address
+ *      daddr=NULL      means leave destination address (eg unresolved arp)
+ */
+static int ieee80211_header(struct sk_buff *skb, struct net_device *dev,
+		unsigned short type, void *daddr, void *saddr, unsigned len)
+{
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	struct ieee80211_hdr *header;
+	int fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
+	int hdr_len = IEEE80211_3ADDR_LEN;
+	
+	if (type != ETH_P_802_3 && type != ETH_P_802_2) {
+		ieee80211_put_snap(skb_push(skb, SNAP_SIZE), type);
+		hdr_len += SNAP_SIZE;
+	}
+
+	if (!saddr) saddr = dev->dev_addr;
+	header = (struct ieee80211_hdr *)skb_push(skb, IEEE80211_3ADDR_LEN);
+	header->duration_id = header->seq_ctl = 0;
+	if (ieee->iw_mode == IW_MODE_INFRA) {
+		fc |= IEEE80211_FCTL_TODS;
+		/* To DS: Addr1 = BSSID, Addr2 = SA,
+		   Addr3 = DA */
+		memcpy(header->addr1, ieee->bssid, IEEE80211_ALEN);
+		memcpy(header->addr2, saddr, IEEE80211_ALEN);
+		if (daddr)
+			memcpy(header->addr3, daddr, IEEE80211_ALEN);
+		else
+			memset(header->addr3, 0, IEEE80211_ALEN);
+	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
+		/* not From/To DS: Addr1 = DA, Addr2 = SA,
+		   Addr3 = BSSID */
+		if (daddr)
+			memcpy(header->addr1, daddr, IEEE80211_ALEN);
+		else
+			memset(header->addr1, 0, IEEE80211_ALEN);
+		memcpy(header->addr2, saddr, IEEE80211_ALEN);
+		memcpy(header->addr3, ieee->bssid, IEEE80211_ALEN);
+	}
+	header->frame_ctl = cpu_to_le16(fc);
+
+	if (!daddr || (dev->flags & (IFF_LOOPBACK | IFF_NOARP)))
+		return -hdr_len;
+	return hdr_len;
+}
+
+static int ieee80211_rebuild_header(struct sk_buff *skb)
+{
+	struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data;
+	struct net_device *dev = skb->dev;
+	unsigned short type;
+
+	type = ieee80211_get_proto(header);
+
+	switch (type) {
+#ifdef CONFIG_INET
+	case ETH_P_IP:
+		return arp_find(IEEE80211_GET_DADDR(header), skb);
+#endif
+	default:
+		printk(KERN_DEBUG
+			"%s: unable to resolve type %X addresses.\n",
+			dev->name, type);
+		break;
+	}
+	
+	return 0;
+}
+
+static int ieee80211_mac_addr(struct net_device *dev, void *p)
+{
+	struct sockaddr *addr = p;
+
+	if (netif_running(dev))
+		return -EBUSY;
+	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+	return 0;
+}
+
+static int ieee80211_header_cache(struct neighbour *neigh, struct hh_cache *hh)
+{
+	struct net_device *dev = neigh->dev;
+	struct ieee80211_device *ieee = netdev_priv(dev);
+	unsigned short type = hh->hh_type;
+	struct ieee80211_hdr *header;
+	int fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
+
+	if (type == __constant_htons(ETH_P_802_3) ||
+			type == __constant_htons(ETH_P_802_2))
+		return -1;
+
+	header = (struct ieee80211_hdr *)
+		(((u8 *)hh->hh_data) +
+			(HH_DATA_OFF(IEEE80211_3ADDR_LEN + SNAP_SIZE)));
+	__ieee80211_put_snap((u8 *)header + IEEE80211_3ADDR_LEN, type);
+	
+	header->duration_id = header->seq_ctl = 0;
+	if (ieee->iw_mode == IW_MODE_INFRA) {
+		fc |= IEEE80211_FCTL_TODS;
+		/* To DS: Addr1 = BSSID, Addr2 = SA,
+		   Addr3 = DA */
+		memcpy(header->addr1, ieee->bssid, IEEE80211_ALEN);
+		memcpy(header->addr2, dev->dev_addr, IEEE80211_ALEN);
+		memcpy(header->addr3, neigh->ha, IEEE80211_ALEN);
+	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
+		/* not From/To DS: Addr1 = DA, Addr2 = SA,
+		   Addr3 = BSSID */
+		memcpy(header->addr1, neigh->ha, IEEE80211_ALEN);
+		memcpy(header->addr2, dev->dev_addr, IEEE80211_ALEN);
+		memcpy(header->addr3, ieee->bssid, IEEE80211_ALEN);
+	}
+	header->frame_ctl = cpu_to_le16(fc);
+
+	hh->hh_len = IEEE80211_3ADDR_LEN + SNAP_SIZE;
+	return 0;
+}
+
+static void ieee80211_header_cache_update(struct hh_cache *hh,
+		struct net_device *dev, unsigned char *haddr)
+{
+	struct ieee80211_hdr *header;
+
+	header = (struct ieee80211_hdr *)
+		(((u8 *)hh->hh_data) +
+			(HH_DATA_OFF(IEEE80211_3ADDR_LEN + SNAP_SIZE)));
+	memcpy(IEEE80211_GET_DADDR(header), haddr, dev->addr_len);
+}
+
+static int ieee80211_header_parse(struct sk_buff *skb, unsigned char *haddr)
+{
+	struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data;
+
+	memcpy(haddr, IEEE80211_GET_SADDR(header), IEEE80211_ALEN);
+	return IEEE80211_ALEN;
+}
+
+
+void ieee80211_setup(struct net_device *dev)
+{
+	dev->change_mtu		 = ieee80211_change_mtu;
+	dev->hard_header	 = ieee80211_header;
+	dev->rebuild_header	 = ieee80211_rebuild_header;
+	dev->set_mac_address	 = ieee80211_mac_addr;
+	dev->hard_header_cache	 = ieee80211_header_cache;
+	dev->header_cache_update = ieee80211_header_cache_update;
+	dev->hard_header_parse	 = ieee80211_header_parse;
+
+	dev->hard_start_xmit     = ieee80211_xmit;
+
+	dev->type		 = ARPHRD_ETHER;
+	dev->hard_header_len	 = IEEE80211_3ADDR_LEN + SNAP_SIZE;
+	dev->mtu		 = IEEE80211_DATA_LEN - 8 - SNAP_SIZE;
+	dev->addr_len		 = IEEE80211_ALEN;
+	dev->tx_queue_len	 = 1000;
+	dev->flags		 = IFF_BROADCAST | IFF_MULTICAST;
+	
+	memset(dev->broadcast, 0xFF, IEEE80211_ALEN);
+}
+
+
 struct ieee80211_device *alloc_ieee80211(int sizeof_priv)
 {
 	struct ieee80211_device *ieee;
 	struct net_device *dev;
-	int alloc_size;
+ 	int alloc_size;
 	int err;
 
 	IEEE80211_DEBUG_INFO("Initializing...\n");
 
-	alloc_size = ((sizeof(struct ieee80211_device) + NETDEV_ALIGN_CONST) 
-			& ~NETDEV_ALIGN_CONST) 
-			+ sizeof_priv;
-	dev = alloc_etherdev(alloc_size);
+ 	alloc_size = ((sizeof(struct ieee80211_device) + NETDEV_ALIGN_CONST) 
+ 			& ~NETDEV_ALIGN_CONST) 
+ 			+ sizeof_priv;
+	dev = alloc_netdev(alloc_size, "wlan%d", ieee80211_setup);
 	if (!dev) {
-		IEEE80211_ERROR("Unable to network device.\n");
+		IEEE80211_ERROR("Unable to allocate network device.\n");
 		goto failed;
 	}
 	ieee = netdev_priv(dev);
 	ieee->dev = dev;
 	ieee->priv = ieee80211_priv(ieee);
-	
-	dev->hard_start_xmit = ieee80211_xmit;
 
 	err = ieee80211_networks_allocate(ieee);
 	if (err) {
@@ -201,7 +402,7 @@
 			     unsigned long count, void *data)
 {
 	char buf[] = "0x00000000";
-	unsigned long len = min(sizeof(buf) - 1, (u32)count);
+	unsigned long len = min((unsigned long)sizeof(buf) - 1, count);
 	char *p = (char *)buf;
 	unsigned long val;
 
@@ -268,4 +469,5 @@
 #endif
 
+EXPORT_SYMBOL(ieee80211_setup);
 EXPORT_SYMBOL(alloc_ieee80211);
 EXPORT_SYMBOL(free_ieee80211);
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -84,16 +84,6 @@
 Total: 8 non-data bytes
 
 
-802.3 Ethernet Data Frame
-
-      ,-----------------------------------------.
-Bytes |   6   |   6   |  2   |  Variable |   4  |
-      |-------|-------|------|-----------|------|
-Desc. | Dest. | Source| Type | IP Packet |  fcs |
-      |  MAC  |  MAC  |      |           |      |
-      `-----------------------------------------'
-Total: 18 non-data bytes
-
 In the event that fragmentation is required, the incoming payload is split into
 N parts of size ieee->fts.  The first fragment contains the SNAP header and the
 remaining packets are just data.
@@ -104,56 +94,8 @@
 encryption it will take 3 frames.  With WEP it will take 4 frames as the
 payload of each frame is reduced to 492 bytes.
 
-* SKB visualization
-*
-*  ,- skb->data
-* |
-* |    ETHERNET HEADER        ,-<-- PAYLOAD
-* |                           |     14 bytes from skb->data
-* |  2 bytes for Type --> ,T. |     (sizeof ethhdr)
-* |                       | | |
-* |,-Dest.--. ,--Src.---. | | |
-* |  6 bytes| | 6 bytes | | | |
-* v         | |         | | | |
-* 0         | v       1 | v | v           2
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-*     ^     | ^         | ^ |
-*     |     | |         | | |
-*     |     | |         | `T' <---- 2 bytes for Type
-*     |     | |         |
-*     |     | '---SNAP--' <-------- 6 bytes for SNAP
-*     |     |
-*     `-IV--' <-------------------- 4 bytes for IV (WEP)
-*
-*      SNAP HEADER
-*
 */
 
-static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
-static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-
-static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
-{
-	struct ieee80211_snap_hdr *snap;
-	u8 *oui;
-
-	snap = (struct ieee80211_snap_hdr *)data;
-	snap->dsap = 0xaa;
-	snap->ssap = 0xaa;
-	snap->ctrl = 0x03;
-
-	if (h_proto == 0x8137 || h_proto == 0x80f3)
-		oui = P802_1H_OUI;
-	else
-		oui = RFC1042_OUI;
-	snap->oui[0] = oui[0];
-	snap->oui[1] = oui[1];
-	snap->oui[2] = oui[2];
-
-	*(u16 *)(data + SNAP_SIZE) = htons(h_proto);
-
-	return SNAP_SIZE + sizeof(u16);
-}
 
 static inline int ieee80211_encrypt_fragment(
 	struct ieee80211_device *ieee,
@@ -248,19 +190,16 @@
 		   struct net_device *dev)
 {
 	struct ieee80211_device *ieee = netdev_priv(dev);
+	struct ieee80211_hdr *header = (struct ieee80211_hdr *)skb->data;
 	struct ieee80211_txb *txb = NULL;
 	struct ieee80211_hdr *frag_hdr;
 	int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
 	unsigned long flags;
 	struct net_device_stats *stats = &ieee->stats;
-	int ether_type, encrypt;
+	int type, encrypt;
 	int bytes, fc, hdr_len;
 	struct sk_buff *skb_frag;
-	struct ieee80211_hdr header = { /* Ensure zero initialized */
-		.duration_id = 0,
-		.seq_ctl = 0
-	};
-	u8 dest[ETH_ALEN], src[ETH_ALEN];
+	u8 *dest;
 
 	struct ieee80211_crypt_data* crypt;
 
@@ -269,76 +208,48 @@
 	/* If there is no driver handler to take the TXB, dont' bother
 	 * creating it... */
 	if (!ieee->hard_start_xmit) {
-		printk(KERN_WARNING "%s: No xmit handler.\n",
-		       dev->name);
+		if (printk_ratelimit())
+			printk(KERN_WARNING "%s: No xmit handler.\n",
+				dev->name);
 		goto success;
 	}
 
-	if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
-		printk(KERN_WARNING "%s: skb too small (%d).\n",
-		       dev->name, skb->len);
-		goto success;
-	}
-
-	ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
+	type = ieee80211_get_proto(header);
+	dest = IEEE80211_GET_DADDR(header);
+	hdr_len = ieee80211_get_hdrlen(header);
 
 	crypt = ieee->crypt[ieee->tx_keyidx];
 
-	encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
+	encrypt = !(type == ETH_P_PAE && ieee->ieee802_1x) &&
 		ieee->host_encrypt && crypt && crypt->ops;
 
 	if (!encrypt && ieee->ieee802_1x &&
-	    ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
+	    ieee->drop_unencrypted && type != ETH_P_PAE) {
 		stats->tx_dropped++;
 		goto success;
 	}
 
 #ifdef CONFIG_IEEE80211_DEBUG
-	if (crypt && !encrypt && ether_type == ETH_P_PAE) {
-		struct eapol *eap = (struct eapol *)(skb->data +
-			sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
+	if (crypt && !encrypt && type == ETH_P_PAE) {
+		struct eapol *eap = (struct eapol *)(skb->data + hdr_len);
 		IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
 			eap_get_type(eap->type));
 	}
 #endif
 
-	/* Save source and destination addresses */
-	memcpy(&dest, skb->data, ETH_ALEN);
-	memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
-
-	/* Advance the SKB to the start of the payload */
-	skb_pull(skb, sizeof(struct ethhdr));
-
 	/* Determine total amount of storage required for TXB packets */
-	bytes = skb->len + SNAP_SIZE + sizeof(u16);
+	bytes = skb->len - hdr_len;
 
+	fc = le16_to_cpu(header->frame_ctl);
 	if (encrypt)
-		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
-			IEEE80211_FCTL_WEP;
-	else
-		fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
+		fc |= IEEE80211_FCTL_WEP;
 
-	if (ieee->iw_mode == IW_MODE_INFRA) {
-		fc |= IEEE80211_FCTL_TODS;
-		/* To DS: Addr1 = BSSID, Addr2 = SA,
-		   Addr3 = DA */
-		memcpy(&header.addr1, ieee->bssid, ETH_ALEN);
-		memcpy(&header.addr2, &src, ETH_ALEN);
-		memcpy(&header.addr3, &dest, ETH_ALEN);
-	} else if (ieee->iw_mode == IW_MODE_ADHOC) {
-		/* not From/To DS: Addr1 = DA, Addr2 = SA,
-		   Addr3 = BSSID */
-		memcpy(&header.addr1, dest, ETH_ALEN);
-		memcpy(&header.addr2, src, ETH_ALEN);
-		memcpy(&header.addr3, ieee->bssid, ETH_ALEN);
-	}
-	header.frame_ctl = cpu_to_le16(fc);
-	hdr_len = IEEE80211_3ADDR_LEN;
+	header->frame_ctl = cpu_to_le16(fc);
 
 	/* Determine fragmentation size based on destination (multicast
 	 * and broadcast are not fragmented) */
-	if (is_multicast_ether_addr(dest) ||
-	    is_broadcast_ether_addr(dest))
+	if (is_multicast_ieee80211_addr(dest) ||
+	    is_broadcast_ieee80211_addr(dest))
 		frag_size = MAX_FRAG_THRESHOLD;
 	else
 		frag_size = ieee->fts;
@@ -347,7 +258,7 @@
 	 * this stack is providing the full 802.11 header, one will
 	 * eventually be affixed to this fragment -- so we must account for
 	 * it when determining the amount of payload space. */
-	bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN;
+	bytes_per_frag = frag_size - hdr_len;
 	if (ieee->config &
 	    (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
 		bytes_per_frag -= IEEE80211_FCS_LEN;
@@ -378,6 +289,8 @@
 	txb->encrypted = encrypt;
 	txb->payload_size = bytes;
 
+	skb_pull(skb, hdr_len);
+
 	for (i = 0; i < nr_frags; i++) {
 		skb_frag = txb->fragments[i];
 
@@ -385,7 +298,7 @@
 			skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
 
 		frag_hdr = (struct ieee80211_hdr *)skb_put(skb_frag, hdr_len);
-		memcpy(frag_hdr, &header, hdr_len);
+		memcpy(frag_hdr, header, hdr_len);
 
 		/* If this is not the last fragment, then add the MOREFRAGS
 		 * bit to the frame control */
@@ -398,14 +311,6 @@
 			bytes = bytes_last_frag;
 		}
 
-	       	/* Put a SNAP header on the first fragment */
-		if (i == 0) {
-			ieee80211_put_snap(
-				skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
-				ether_type);
-			bytes -= SNAP_SIZE + sizeof(u16);
-		}
-
 		memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
 
 		/* Advance the SKB... */
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -53,7 +53,7 @@
 	/* First entry *MUST* be the AP MAC address */
 	iwe.cmd = SIOCGIWAP;
 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-	memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
+	memcpy(iwe.u.ap_addr.sa_data, network->bssid, IEEE80211_ALEN);
 	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
 
 	/* Remaining entries will be displayed in the order we provide them */
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -17,7 +17,6 @@
 #include <linux/random.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/if_ether.h>
 #include <linux/if_arp.h>
 #include <asm/string.h>
 #include <linux/wireless.h>
@@ -156,7 +155,7 @@
 	 * Dlen */
 	b0[0] = 0x59;
 	b0[1] = qc;
-	memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
+	memcpy(b0 + 2, hdr->addr2, IEEE80211_ALEN);
 	memcpy(b0 + 8, pn, CCMP_PN_LEN);
 	b0[14] = (dlen >> 8) & 0xff;
 	b0[15] = dlen & 0xff;
@@ -173,13 +172,13 @@
 	aad[1] = aad_len & 0xff;
 	aad[2] = pos[0] & 0x8f;
 	aad[3] = pos[1] & 0xc7;
-	memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
+	memcpy(aad + 4, hdr->addr1, 3 * IEEE80211_ALEN);
 	pos = (u8 *) &hdr->seq_ctl;
 	aad[22] = pos[0] & 0x0f;
 	aad[23] = 0; /* all bits masked */
 	memset(aad + 24, 0, 8);
 	if (a4_included)
-		memcpy(aad + 24, hdr->addr4, ETH_ALEN);
+		memcpy(aad + 24, hdr->addr4, IEEE80211_ALEN);
 	if (qc_included) {
 		aad[a4_included ? 30 : 24] = qc;
 		/* rest of QC masked */
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -17,7 +17,6 @@
 #include <linux/random.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
-#include <linux/if_ether.h>
 #include <linux/if_arp.h>
 #include <asm/string.h>
 
@@ -461,20 +460,20 @@
 	switch (le16_to_cpu(hdr11->frame_ctl) &
 		(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
 	case IEEE80211_FCTL_TODS:
-		memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
+		memcpy(hdr, hdr11->addr3, IEEE80211_ALEN); /* DA */
+		memcpy(hdr + IEEE80211_ALEN, hdr11->addr2, IEEE80211_ALEN); /* SA */
 		break;
 	case IEEE80211_FCTL_FROMDS:
-		memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
+		memcpy(hdr, hdr11->addr1, IEEE80211_ALEN); /* DA */
+		memcpy(hdr + IEEE80211_ALEN, hdr11->addr3, IEEE80211_ALEN); /* SA */
 		break;
 	case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
-		memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
+		memcpy(hdr, hdr11->addr3, IEEE80211_ALEN); /* DA */
+		memcpy(hdr + IEEE80211_ALEN, hdr11->addr4, IEEE80211_ALEN); /* SA */
 		break;
 	case 0:
-		memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
-		memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
+		memcpy(hdr, hdr11->addr1, IEEE80211_ALEN); /* DA */
+		memcpy(hdr + IEEE80211_ALEN, hdr11->addr2, IEEE80211_ALEN); /* SA */
 		break;
 	}
 
@@ -521,7 +520,7 @@
 	else
 		ev.flags |= IW_MICFAILURE_PAIRWISE;
 	ev.src_addr.sa_family = ARPHRD_ETHER;
-	memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
+	memcpy(ev.src_addr.sa_data, hdr->addr2, IEEE80211_ALEN);
 	memset(&wrqu, 0, sizeof(wrqu));
 	wrqu.data.length = sizeof(ev);
 	wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);


--
Jiri Benc
SUSE Labs
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux