Changeset 4
- Timestamp:
- 03/15/03 19:30:16 (6 years ago)
- Files:
-
- cvs-import/trunk/wlan/Makefile (added)
- cvs-import/trunk/wlan/if_ethersubr.h (added)
- cvs-import/trunk/wlan/if_ieee80211.h (modified) (8 diffs)
- cvs-import/trunk/wlan/if_ieee80211subr.c (modified) (133 diffs)
- cvs-import/trunk/wlan/if_llc.h (added)
- cvs-import/trunk/wlan/rc4.c (added)
- cvs-import/trunk/wlan/rc4.h (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
cvs-import/trunk/wlan/if_ieee80211.h
r3 r4 38 38 #define _NET_IF_IEEE80211_H_ 39 39 40 #include <net/ethernet.h> 41 #include <net/if_arp.h> 42 43 /* XXX */ 44 typedef struct sk_buff os_buf_t; 45 typedef struct netdevice os_ifnet_t; 46 47 #define IEEE80211_ADDR_LEN ETHER_ADDR_LEN 40 #include <sys/queue.h> 41 42 /* 43 * BSD portability stuff. 44 */ 45 #ifndef NBBY 46 #define NBBY 8 /* number of bits/byte */ 47 #endif 48 #ifndef roundup 49 #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */ 50 #endif 51 52 #define IEEE80211_ADDR_LEN 6 48 53 49 54 /* … … 290 295 */ 291 296 297 #ifndef SIOCSIFGENERIC 298 #define SIOCSIFGENERIC _IOW('i', 57, struct ifreq) /* generic IF set op */ 299 #endif 300 #ifndef SIOCGIFGENERIC 301 #define SIOCGIFGENERIC _IOWR('i', 58, struct ifreq) /* generic IF get op */ 302 #endif 303 292 304 /* nwid is pointed at by ifr.ifr_data */ 293 305 struct ieee80211_nwid { … … 402 414 #define IEEE80211_IOC_POWERSAVESLEEP 11 403 415 404 #ifdef _ KERNEL416 #ifdef __KERNEL__ 405 417 406 418 #define IEEE80211_ASCAN_WAIT 2 /* active scan wait */ … … 500 512 501 513 struct ieee80211com { 502 #ifdef __NetBSD__ 503 struct ethercom ic_ec; 504 #endif 505 #ifdef __FreeBSD__ 506 struct arpcom ic_ac; 507 struct mtx ic_mtx; 508 #endif 514 struct net_device ic_dev; /* NB: this must be first */ 515 int ic_timer; /* equivalent of if_timer */ 516 void (*ic_watchdog)(struct net_device *); 517 void (*ic_start)(struct net_device *); 509 518 void (*ic_recv_mgmt[16])(struct ieee80211com *, 510 os_buf_t *, int, u_int32_t); 519 struct sk_buff *, int, u_int32_t); 520 spinlock_t ic_lock; 521 struct net_device_stats ic_stats; /* interface statistics */ 522 u_int32_t msg_enable; /* interface message flags */ 511 523 int (*ic_send_mgmt[16])(struct ieee80211com *, 512 524 struct ieee80211_node *, int, int); … … 517 529 u_char ic_chan_avail[roundup(IEEE80211_CHAN_MAX,NBBY)]; 518 530 u_char ic_chan_active[roundup(IEEE80211_CHAN_MAX, NBBY)]; 519 #ifdef notdef 520 struct ifqueue ic_mgtq; 521 #endif 531 struct sk_buff_head ic_mgtq; 522 532 int ic_flags; 523 533 enum ieee80211_phytype ic_phytype; … … 546 556 u_int32_t ic_iv; /* initial vector for wep */ 547 557 }; 548 #ifdef __NetBSD__ 549 #define ic_if ic_ec.ec_if 550 #define IEEE80211_LOCK(_ic) do { s = splnet(); } while (0) 551 #define IEEE80211_UNLOCK(_ic) splx(s) 552 #endif 553 #ifdef __FreeBSD__ 554 #define ic_if ic_ac.ac_if 555 #define IEEE80211_LOCK(_ic) mtx_lock(&(_ic)->ic_mtx) 556 #define IEEE80211_UNLOCK(_ic) mtx_unlock(&(_ic)->ic_mtx) 557 #endif 558 #define ic_softc ic_if.if_softc 558 #define IEEE80211_LOCK(_ic) spin_lock(&(_ic)->ic_lock) 559 #define IEEE80211_UNLOCK(_ic) spin_unlock(&(_ic)->ic_lock) 559 560 560 561 #define IEEE80211_SEND_MGMT(ic,ni,type,arg) do { \ … … 589 590 #define IEEE80211_F_DODEL 0x00000008 /* delete ignore rate */ 590 591 591 void ieee80211_ifattach(os_ifnet_t *); 592 void ieee80211_ifdetach(os_ifnet_t *); 593 void ieee80211_input(os_ifnet_t *, os_buf_t *, int, u_int32_t); 594 int ieee80211_mgmt_output(os_ifnet_t *, struct ieee80211_node *, 595 os_buf_t *, int); 596 os_buf_t *ieee80211_encap(os_ifnet_t *, os_buf_t *); 597 os_buf_t *ieee80211_decap(os_ifnet_t *, os_buf_t *); 598 int ieee80211_ioctl(os_ifnet_t *, u_long, caddr_t); 592 /* private extensions to netdevice.h's netif_msg* mechanism */ 593 #define NETIF_MSG_DEBUG 0x80000000 /* enable debugging msgs */ 594 #define netif_msg_debug(p) ((p)->msg_enable & NETIF_MSG_DEBUG) 595 596 int ieee80211_ifattach(struct net_device *); 597 void ieee80211_ifdetach(struct net_device *); 598 void ieee80211_input(struct net_device *, struct sk_buff *, int, u_int32_t); 599 int ieee80211_mgmt_output(struct net_device *, struct ieee80211_node *, 600 struct sk_buff *, int); 601 struct sk_buff *ieee80211_encap(struct net_device *, struct sk_buff *); 602 struct sk_buff *ieee80211_decap(struct net_device *, struct sk_buff *); 603 int ieee80211_ioctl(struct net_device *, u_long, caddr_t); 599 604 void ieee80211_print_essid(u_int8_t *, int); 600 605 void ieee80211_dump_pkt(u_int8_t *, int, int, int); 601 void ieee80211_watchdog( os_ifnet_t*);602 void ieee80211_next_scan( os_ifnet_t*);603 void ieee80211_end_scan( os_ifnet_t*);606 void ieee80211_watchdog(struct net_device *); 607 void ieee80211_next_scan(struct net_device *); 608 void ieee80211_end_scan(struct net_device *); 604 609 struct ieee80211_node *ieee80211_alloc_node(struct ieee80211com *, u_int8_t *, 605 610 int); … … 608 613 void ieee80211_free_allnodes(struct ieee80211com *); 609 614 int ieee80211_fix_rate(struct ieee80211com *, struct ieee80211_node *, int); 610 int ieee80211_new_state( os_ifnet_t*, enum ieee80211_state, int);611 os_buf_t *ieee80211_wep_crypt(os_ifnet_t *, os_buf_t*, int);615 int ieee80211_new_state(struct net_device *, enum ieee80211_state, int); 616 struct sk_buff *ieee80211_wep_crypt(struct net_device *, struct sk_buff *, int); 612 617 int ieee80211_rate2media(int, enum ieee80211_phytype); 613 618 int ieee80211_media2rate(int, enum ieee80211_phytype); 614 619 615 int ieee80211_cfgget( os_ifnet_t*, u_long, caddr_t);616 int ieee80211_cfgset( os_ifnet_t*, u_long, caddr_t);617 618 #endif /* _ KERNEL*/620 int ieee80211_cfgget(struct net_device *, u_long, caddr_t); 621 int ieee80211_cfgset(struct net_device *, u_long, caddr_t); 622 623 #endif /* __KERNEL__ */ 619 624 620 625 #endif /* _NET_IF_IEEE80211_H_ */ cvs-import/trunk/wlan/if_ieee80211subr.c
r3 r4 42 42 */ 43 43 44 #include <sys/cdefs.h> 45 46 #include "opt_inet.h" 47 #define NBPFILTER 1 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/mbuf.h> 52 #include <sys/malloc.h> 53 #include <sys/kernel.h> 54 #include <sys/socket.h> 55 #include <sys/sockio.h> 56 #include <sys/endian.h> 57 #include <sys/errno.h> 58 #include <sys/bus.h> 59 #include <sys/proc.h> 60 #include <sys/sysctl.h> 61 62 #include <crypto/rc4/rc4.h> 44 #ifndef EXPORT_SYMTAB 45 #define EXPORT_SYMTAB 46 #endif 47 48 #include <linux/config.h> 49 #include <linux/version.h> 50 #include <linux/module.h> 51 #include <linux/init.h> 52 #include <linux/skbuff.h> 53 #include <linux/netdevice.h> 54 #include <linux/utsname.h> 55 #include <linux/random.h> 56 57 #include <asm/uaccess.h> 58 59 #include "rc4.h" 63 60 #define arc4_ctxlen() sizeof (struct rc4_state) 64 61 #define arc4_setkey(_c,_k,_l) rc4_init(_c,_k,_l) 65 62 #define arc4_encrypt(_c,_d,_s,_l) rc4_crypt(_c,_s,_d,_l) 66 67 #include <net/if.h> 68 #include <net/if_dl.h> 69 #include <net/if_media.h> 70 #include <net/ethernet.h> 71 #include <net/if_llc.h> 72 #include <net/if_ieee80211.h> 73 74 #if NBPFILTER > 0 75 #include <net/bpf.h> 76 #endif 77 78 #ifdef INET 79 #include <netinet/in.h> 80 #include <netinet/if_ether.h> 81 #endif 82 83 #include <dev/wi/if_wavelan_ieee.h> 63 64 #include "if_ieee80211.h" 65 #include "if_wavelan_ieee.h" 66 #include "if_media.h" 67 #define __packed __attribute__((__packed__)) 68 #include "if_llc.h" 69 #include "if_ethersubr.h" 70 71 /* Bit map related macros. */ 72 #define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) 73 #define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) 74 #define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) 75 #define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) 84 76 85 77 #define IEEE80211_DEBUG 86 78 #ifdef IEEE80211_DEBUG 87 int ieee80211_debug = 0; 88 #define DPRINTF(X) if (ieee80211_debug) printf X 89 #define DPRINTF2(X) if (ieee80211_debug>1) printf X 90 91 SYSCTL_INT(_debug, OID_AUTO, ieee80211, CTLFLAG_RW, &ieee80211_debug, 92 0, "IEEE 802.11 media debugging printfs"); 79 static int ieee80211_debug = 0; 80 #define DPRINTF(X) if (ieee80211_debug) printk X 81 #define DPRINTF2(X) if (ieee80211_debug>1) printk X 93 82 #else 94 83 #define DPRINTF(X) … … 124 113 125 114 static void ieee80211_recv_beacon(struct ieee80211com *, 126 struct mbuf *, int, u_int32_t);115 struct sk_buff *, int, u_int32_t); 127 116 static void ieee80211_recv_prreq(struct ieee80211com *, 128 struct mbuf *, int, u_int32_t);117 struct sk_buff *, int, u_int32_t); 129 118 static void ieee80211_recv_auth(struct ieee80211com *, 130 struct mbuf *, int, u_int32_t);119 struct sk_buff *, int, u_int32_t); 131 120 static void ieee80211_recv_asreq(struct ieee80211com *, 132 struct mbuf *, int, u_int32_t);121 struct sk_buff *, int, u_int32_t); 133 122 static void ieee80211_recv_asresp(struct ieee80211com *, 134 struct mbuf *, int, u_int32_t);123 struct sk_buff *, int, u_int32_t); 135 124 static void ieee80211_recv_disassoc(struct ieee80211com *, 136 struct mbuf *, int, u_int32_t);125 struct sk_buff *, int, u_int32_t); 137 126 static void ieee80211_recv_deauth(struct ieee80211com *, 138 struct mbuf *, int, u_int32_t);127 struct sk_buff *, int, u_int32_t); 139 128 140 129 static void ieee80211_crc_init(void); … … 148 137 }; 149 138 150 void 151 ieee80211_ifattach(struct ifnet *ifp) 152 { 153 struct ieee80211com *ic = (void *)ifp; 139 /* 140 * Format an Ethernet MAC for printing. 141 */ 142 static const char* 143 ether_sprintf(const u_int8_t *mac) 144 { 145 static char etherbuf[18]; 146 snprintf(etherbuf, sizeof(etherbuf), "%02x:%02x:%02x:%02x:%02x:%02x", 147 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 148 return etherbuf; 149 } 150 151 int 152 ieee80211_ifattach(struct net_device *dev) 153 { 154 struct ieee80211com *ic = (void *)dev; 154 155 int i, rate; 155 156 156 /* XXX need unit */157 mtx_init(&ic->ic_mtx, ifp->if_name, "802.11 link layer", MTX_DEF);158 159 ether_ifattach(ifp, ic->ic_myaddr);160 #if NBPFILTER > 0 161 bpfattach2(ifp, DLT_IEEE802_11, 162 sizeof(struct ieee80211_frame_addr4), &ic->ic_rawbpf);163 #endif 157 if (register_netdev(&ic->ic_dev)) { 158 printk(KERN_WARNING "%s: unable to register device\n", 159 ic->ic_dev.name); 160 return (EIO); 161 } 162 163 spin_lock_init(&ic->ic_lock); 164 164 165 ieee80211_crc_init(); 165 ic->ic_iv = arc4random();166 get_random_bytes(&ic->ic_iv, sizeof(ic->ic_iv)); 166 167 memcpy(ic->ic_chan_active, ic->ic_chan_avail, 167 168 sizeof(ic->ic_chan_active)); … … 179 180 ic->ic_lintval = 100; /* default sleep */ 180 181 TAILQ_INIT(&ic->ic_node); 181 mtx_init(&ic->ic_mgtq.ifq_mtx, ifp->if_name, "mgmt send q", MTX_DEF); 182 182 skb_queue_head_init(&ic->ic_mgtq); 183 184 #ifdef notdef 183 185 rate = 0; 184 186 for (i = 0; i < IEEE80211_RATE_SIZE; i++) { … … 189 191 ifp->if_baudrate = IF_Mbps(rate); 190 192 ifp->if_hdrlen = sizeof(struct ieee80211_frame); 193 #endif 191 194 192 195 /* initialize management frame handler */ … … 230 233 ic->ic_send_mgmt[IEEE80211_FC0_SUBTYPE_DISASSOC 231 234 >> IEEE80211_FC0_SUBTYPE_SHIFT] = ieee80211_send_disassoc; 235 236 return (0); 232 237 } 233 238 234 239 void 235 ieee80211_ifdetach(struct ifnet *ifp)236 { 237 struct ieee80211com *ic = (void *) ifp;240 ieee80211_ifdetach(struct net_device *dev) 241 { 242 struct ieee80211com *ic = (void *)dev; 238 243 239 244 IEEE80211_LOCK(ic); 240 IF_DRAIN(&ic->ic_mgtq); 241 mtx_destroy(&ic->ic_mgtq.ifq_mtx); 245 skb_queue_purge(&ic->ic_mgtq); 242 246 if (ic->ic_wep_ctx != NULL) { 243 free(ic->ic_wep_ctx, M_DEVBUF);247 kfree(ic->ic_wep_ctx); 244 248 ic->ic_wep_ctx = NULL; 245 249 } 246 250 ieee80211_free_allnodes(ic); 247 #if NBPFILTER > 0 248 bpfdetach(ifp); 249 #endif 250 ether_ifdetach(ifp); 251 unregister_netdev(&ic->ic_dev); 251 252 IEEE80211_UNLOCK(ic); 252 mtx_destroy(&ic->ic_mtx);253 253 } 254 254 255 255 void 256 ieee80211_input(struct ifnet *ifp, struct mbuf *m, int rssi, u_int32_t rstamp) 257 { 258 struct ieee80211com *ic = (void *)ifp; 256 ieee80211_input(struct net_device *dev, struct sk_buff *skb, 257 int rssi, u_int32_t rstamp) 258 { 259 struct ieee80211com *ic = (void *)dev; 259 260 struct ieee80211_node *ni = NULL; 260 261 struct ieee80211_frame *wh; 261 262 struct ether_header *eh; 262 void (*rh)(struct ieee80211com *, struct mbuf *, int, u_int);263 struct mbuf *m1;263 void (*rh)(struct ieee80211com *, struct sk_buff *, int, u_int); 264 struct sk_buff *skb1; 264 265 int len; 265 266 u_int8_t dir, subtype; … … 267 268 u_int16_t rxseq; 268 269 269 /* trim CRC here for WEP can find its own CRC at the end of packet. */ 270 if (m->m_flags & M_HASFCS) { 271 m_adj(m, -IEEE80211_CRC_LEN); 272 m->m_flags &= ~M_HASFCS; 273 } 274 275 wh = mtod(m, struct ieee80211_frame *); 270 wh = (struct ieee80211_frame *) skb->data; 276 271 if ((wh->i_fc[0] & IEEE80211_FC0_VERSION_MASK) != 277 272 IEEE80211_FC0_VERSION_0) { 278 if ( ifp->if_flags & IFF_DEBUG)279 if_printf(ifp, "receive packet with wrong version: %x\n",280 wh->i_fc[0]);273 if (netif_msg_debug(ic)) 274 printk("%s: receive packet with wrong version: %x\n", 275 dev->name, wh->i_fc[0]); 281 276 goto err; 282 277 } … … 303 298 bssid = wh->i_addr1; 304 299 if (!IEEE80211_ADDR_EQ(bssid, ic->ic_bss.ni_bssid) && 305 !IEEE80211_ADDR_EQ(bssid, ifp->if_broadcastaddr)) {300 !IEEE80211_ADDR_EQ(bssid, dev->broadcast)) { 306 301 /* not interested in */ 307 302 DPRINTF2(("ieee80211_input: other bss %s\n", … … 321 316 rxseq = ni->ni_rxseq; 322 317 ni->ni_rxseq = 323 le16 toh(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT;318 le16_to_cpu(*(u_int16_t *)wh->i_seq) >> IEEE80211_SEQ_SEQ_SHIFT; 324 319 /* TODO: fragment */ 325 320 if ((wh->i_fc[1] & IEEE80211_FC1_RETRY) && … … 337 332 if (dir != IEEE80211_FC1_DIR_FROMDS) 338 333 goto out; 334 #ifdef IFF_SIMPLEX 339 335 if ((ifp->if_flags & IFF_SIMPLEX) && 340 336 IEEE80211_IS_MULTICAST(wh->i_addr1) && … … 348 344 goto out; 349 345 } 346 #endif 350 347 break; 351 348 case IEEE80211_M_IBSS: … … 385 382 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 386 383 if (ic->ic_flags & IEEE80211_F_WEPON) { 387 m = ieee80211_wep_crypt(ifp, m, 0);388 if ( m== NULL)384 skb = ieee80211_wep_crypt(dev, skb, 0); 385 if (skb == NULL) 389 386 goto err; 390 wh = mtod(m, struct ieee80211_frame *);387 wh = (struct ieee80211_frame *) skb->data; 391 388 } else 392 389 goto out; 393 390 } 394 391 /* copy to listener after decrypt */ 395 #if NBPFILTER > 0 396 if (ic->ic_rawbpf) 397 bpf_mtap(ic->ic_rawbpf, m); 398 #endif 399 m = ieee80211_decap(ifp, m); 400 if (m == NULL) 392 skb = ieee80211_decap(dev, skb); 393 if (skb == NULL) 401 394 goto err; 402 i fp->if_ipackets++;395 ic->ic_stats.rx_packets++; 403 396 404 397 /* perform as a bridge within the AP */ 405 m1 = NULL;398 skb1 = NULL; 406 399 if (ic->ic_opmode == IEEE80211_M_HOSTAP) { 407 eh = mtod(m, struct ether_header *);400 eh = (struct ether_header *) skb->data; 408 401 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 409 m1 = m_copym(m, 0, M_COPYALL, M_NOWAIT); 410 if (m1 == NULL) 411 ifp->if_oerrors++; 412 else 413 m1->m_flags |= M_MCAST; 402 skb1 = skb_copy(skb, 0); 403 if (skb1 == NULL) 404 ic->ic_stats.tx_errors++; 414 405 } else { 415 406 ni = ieee80211_find_node(ic, eh->ether_dhost); 416 407 if (ni != NULL && ni->ni_associd != 0) { 417 m1 = m;418 m= NULL;408 skb1 = skb; 409 skb = NULL; 419 410 } 420 411 } 421 if (m1 != NULL) { 422 #ifdef ALTQ 423 if (ALTQ_IS_ENABLED(&ifp->if_snd)) 424 altq_etherclassify(&ifp->if_snd, m1, 425 &pktattr); 426 #endif 427 len = m1->m_pkthdr.len; 428 IF_ENQUEUE(&ifp->if_snd, m1); 429 if (m != NULL) 430 ifp->if_omcasts++; 431 ifp->if_obytes += len; 432 } 433 } 434 if (m != NULL) 435 (*ifp->if_input)(ifp, m); 412 if (skb1 != NULL) { 413 len = skb1->len; 414 skb1->dev = dev; 415 skb1->protocol = __constant_htons(ETH_P_802_2); 416 dev_queue_xmit(skb1); 417 ic->ic_stats.tx_bytes += len; 418 } 419 } 420 if (skb != NULL) { 421 skb->dev = dev; 422 skb->mac.raw = skb->data; 423 skb_pull(skb, sizeof(struct ether_header)); 424 skb->pkt_type = PACKET_OTHERHOST; 425 skb->protocol = __constant_htons(ETH_P_802_2); 426 netif_rx(skb); 427 } 436 428 return; 437 429 … … 454 446 } 455 447 456 if ( ifp->if_flags & IFF_DEBUG) {448 if (netif_msg_debug(ic)) { 457 449 /* avoid to print too many frames */ 458 450 int doprint = 0; … … 475 467 #endif 476 468 if (doprint) 477 if_printf(ifp, "received %s from %s rssi %d\n", 469 printk("%s: received %s from %s rssi %d\n", 470 dev->name, 478 471 ieee80211_mgt_subtype_name[subtype 479 472 >> IEEE80211_FC0_SUBTYPE_SHIFT], 480 473 ether_sprintf(wh->i_addr2), rssi); 481 474 } 482 #if NBPFILTER > 0483 if (ic->ic_rawbpf)484 bpf_mtap(ic->ic_rawbpf, m);485 #endif486 475 rh = ic->ic_recv_mgmt[subtype >> IEEE80211_FC0_SUBTYPE_SHIFT]; 487 476 if (rh != NULL) 488 (*rh)(ic, m, rssi, rstamp);489 m_freem(m);477 (*rh)(ic, skb, rssi, rstamp); 478 dev_kfree_skb(skb); 490 479 return; 491 480 … … 497 486 } 498 487 err: 499 i fp->if_ierrors++;488 ic->ic_stats.rx_errors++; 500 489 out: 501 if (m != NULL) { 502 #if NBPFILTER > 0 503 if (ic->ic_rawbpf) 504 bpf_mtap(ic->ic_rawbpf, m); 505 #endif 506 m_freem(m); 507 } 490 if (skb != NULL) 491 dev_kfree_skb(skb); 508 492 } 509 493 510 494 int 511 ieee80211_mgmt_output(struct ifnet *ifp, struct ieee80211_node *ni,512 struct mbuf *m, int type)513 { 514 struct ieee80211com *ic = (void *) ifp;495 ieee80211_mgmt_output(struct net_device *dev, struct ieee80211_node *ni, 496 struct sk_buff *skb, int type) 497 { 498 struct ieee80211com *ic = (void *)dev; 515 499 struct ieee80211_frame *wh; 516 500 … … 518 502 ni = &ic->ic_bss; 519 503 ni->ni_inact = 0; 520 M_PREPEND(m, sizeof(struct ieee80211_frame), M_NOWAIT); 521 if (m == NULL) 522 return ENOMEM; 523 wh = mtod(m, struct ieee80211_frame *); 504 505 wh = (struct ieee80211_frame *) 506 skb_push(skb, sizeof(struct ieee80211_frame)); 524 507 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT | type; 525 508 wh->i_fc[1] = IEEE80211_FC1_DIR_NODS; 526 509 *(u_int16_t *)wh->i_dur = 0; 527 510 *(u_int16_t *)wh->i_seq = 528 htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);511 cpu_to_le16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT); 529 512 ni->ni_txseq++; 530 513 IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr); … … 532 515 IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid); 533 516 534 if ( ifp->if_flags & IFF_DEBUG) {517 if (netif_msg_debug(ic)) { 535 518 /* avoid to print too many frames */ 536 519 if (ic->ic_opmode == IEEE80211_M_IBSS || … … 540 523 (type & IEEE80211_FC0_SUBTYPE_MASK) != 541 524 IEEE80211_FC0_SUBTYPE_PROBE_RESP) 542 if_printf(ifp, "sending %s to %s\n", 525 printk("%s: sending %s to %s\n", 526 dev->name, 543 527 ieee80211_mgt_subtype_name[ 544 528 (type & IEEE80211_FC0_SUBTYPE_MASK) … … 546 530 ether_sprintf(ni->ni_macaddr)); 547 531 } 548 IF_ENQUEUE(&ic->ic_mgtq, m);549 i fp->if_timer = 1;550 (*i fp->if_start)(ifp);532 skb_queue_tail(&ic->ic_mgtq, skb); 533 ic->ic_timer = 1; 534 (*ic->ic_start)(dev); 551 535 return 0; 552 536 } 553 537 554 struct mbuf *555 ieee80211_encap(struct ifnet *ifp, struct mbuf *m)556 { 557 struct ieee80211com *ic = (void *) ifp;538 struct sk_buff * 539 ieee80211_encap(struct net_device *dev, struct sk_buff *skb) 540 { 541 struct ieee80211com *ic = (void *)dev; 558 542 struct ether_header eh; 559 543 struct ieee80211_frame *wh; … … 561 545 struct ieee80211_node *ni; 562 546 563 if (m->m_len < sizeof(struct ether_header)) { 564 m = m_pullup(m, sizeof(struct ether_header)); 565 if (m == NULL) 566 return NULL; 567 } 568 memcpy(&eh, mtod(m, caddr_t), sizeof(struct ether_header)); 547 memcpy(&eh, skb->data, sizeof(struct ether_header)); 569 548 570 549 if (!IEEE80211_IS_MULTICAST(eh.ether_dhost) && … … 578 557 ni->ni_inact = 0; 579 558 580 m_adj(m, sizeof(struct ether_header) - sizeof(struct llc));581 llc = mtod(m, struct llc *);559 llc = (struct llc *) skb_push(skb, 560 sizeof(struct ether_header) - sizeof(struct llc)); 582 561 llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP; 583 562 llc->llc_control = LLC_UI; … … 586 565 llc->llc_snap.org_code[2] = 0; 587 566 llc->llc_snap.ether_type = eh.ether_type; 588 M_PREPEND(m, sizeof(struct ieee80211_frame), M_NOWAIT); 589 if (m == NULL) 590 return NULL; 591 wh = mtod(m, struct ieee80211_frame *); 567 wh = (struct ieee80211_frame *) skb_push(skb, sizeof(*wh)); 592 568 wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_DATA; 593 569 *(u_int16_t *)wh->i_dur = 0; 594 570 *(u_int16_t *)wh->i_seq = 595 htole16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT);571 cpu_to_le16(ni->ni_txseq << IEEE80211_SEQ_SEQ_SHIFT); 596 572 ni->ni_txseq++; 597 573 switch (ic->ic_opmode) { … … 616 592 break; 617 593 } 618 return m;619 } 620 621 struct mbuf *622 ieee80211_decap(struct ifnet *ifp, struct mbuf *m)594 return skb; 595 } 596 597 struct sk_buff * 598 ieee80211_decap(struct net_device *dev, struct sk_buff *skb) 623 599 { 624 600 struct ether_header *eh; … … 626 602 struct llc *llc; 627 603 628 if (m->m_len < sizeof(wh) + sizeof(*llc)) { 629 m = m_pullup(m, sizeof(wh) + sizeof(*llc)); 630 if (m == NULL) 631 return NULL; 632 } 633 memcpy(&wh, mtod(m, caddr_t), sizeof(wh)); 634 llc = (struct llc *)(mtod(m, caddr_t) + sizeof(wh)); 604 memcpy(&wh, skb->data, sizeof(wh)); 605 llc = (struct llc *)(skb->data + sizeof(wh)); 635 606 if (llc->llc_dsap == LLC_SNAP_LSAP && llc->llc_ssap == LLC_SNAP_LSAP && 636 607 llc->llc_control == LLC_UI && llc->llc_snap.org_code[0] == 0 && 637 608 llc->llc_snap.org_code[1] == 0 && llc->llc_snap.org_code[2] == 0) { 638 m_adj(m, sizeof(wh) + sizeof(struct llc) - sizeof(*eh));609 skb_pull(skb, sizeof(wh) + sizeof(struct llc) - sizeof(*eh)); 639 610 llc = NULL; 640 611 } else { 641 m_adj(m, sizeof(wh) - sizeof(*eh));642 } 643 eh = mtod(m, struct ether_header *);612 skb_pull(skb, sizeof(wh) - sizeof(*eh)); 613 } 614 eh = (struct ether_header *) skb->data; 644 615 switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { 645 616 case IEEE80211_FC1_DIR_NODS: … … 658 629 /* not yet supported */ 659 630 DPRINTF(("ieee80211_decap: DS to DS\n")); 660 m_freem(m);631 dev_kfree_skb(skb); 661 632 return NULL; 662 633 } 663 if (!ALIGNED_POINTER(mtod(m, caddr_t) + sizeof(*eh), u_int32_t)) { 664 struct mbuf *n, *n0, **np; 665 caddr_t newdata; 666 int off, pktlen; 667 668 n0 = NULL; 669 np = &n0; 670 off = 0; 671 pktlen = m->m_pkthdr.len; 672 while (pktlen > off) { 673 if (n0 == NULL) { 674 MGETHDR(n, M_NOWAIT, MT_DATA); 675 if (n == NULL) { 676 m_freem(m); 677 return NULL; 678 } 679 M_MOVE_PKTHDR(n, m); 680 n->m_len = MHLEN; 681 } else { 682 MGET(n, M_NOWAIT, MT_DATA); 683 if (n == NULL) { 684 m_freem(m); 685 m_freem(n0); 686 return NULL; 687 } 688 n->m_len = MLEN; 689 } 690 if (pktlen - off >= MINCLSIZE) { 691 MCLGET(n, M_NOWAIT); 692 if (n->m_flags & M_EXT) 693 n->m_len = n->m_ext.ext_size; 694 } 695 if (n0 == NULL) { 696 newdata = 697 (caddr_t)ALIGN(n->m_data + sizeof(*eh)) - 698 sizeof(*eh); 699 n->m_len -= newdata - n->m_data; 700 n->m_data = newdata; 701 } 702 if (n->m_len > pktlen - off) 703 n->m_len = pktlen - off; 704 m_copydata(m, off, n->m_len, mtod(n, caddr_t)); 705 off += n->m_len; 706 *np = n; 707 np = &n->m_next; 708 } 709 m_freem(m); 710 m = n0; 634 if (!ALIGNED_POINTER(skb->data + sizeof(*eh), u_int32_t)) { 635 struct sk_buff *n; 636 637 /* XXX does this always work? */ 638 n = skb_copy(skb, 0); 639 if (n == NULL) { 640 dev_kfree_skb(skb); 641 return NULL; 642 } 643 dev_kfree_skb(skb); 644 skb = n; 711 645 } 712 646 if (llc != NULL) { 713 eh = mtod(m, struct ether_header *);714 eh->ether_type = htons( m->m_pkthdr.len - sizeof(*eh));715 } 716 return m;647 eh = (struct ether_header *) skb->data; 648 eh->ether_type = htons(skb->len - sizeof(*eh)); 649 } 650 return skb; 717 651 } 718 652 719 653 int 720 ieee80211_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)721 { 722 struct ieee80211com *ic = (void *) ifp;654 ieee80211_ioctl(struct net_device *dev, u_long cmd, caddr_t data) 655 { 656 struct ieee80211com *ic = (void *)dev; 723 657 int error = 0; 724 658 u_int kid, len; … … 744 678 break; 745 679 } 746 error = copy out(tmpssid, ireq->i_data, ireq->i_len);680 error = copy_to_user(ireq->i_data, tmpssid, ireq->i_len); 747 681 break; 748 682 case IEEE80211_IOC_NUMSSIDS: … … 774 708 len = (u_int) ic->ic_nw_keys[kid].wk_len; 775 709 /* NB: only root can read WEP keys */ 776 if ( suser(curthread)) {777 bcopy(ic->ic_nw_keys[kid].wk_key, tmpkey, len);710 if (capable(CAP_SYS_ADMIN)) { 711 memcpy(tmpkey, ic->ic_nw_keys[kid].wk_key, len); 778 712 } else { 779 bzero(tmpkey, len);713 memset(tmpkey, 0, len); 780 714 } 781 715 ireq->i_len = len; 782 error = copy out(tmpkey, ireq->i_data, len);716 error = copy_to_user(ireq->i_data, tmpkey, len); 783 717 break; 784 718 case IEEE80211_IOC_NUMWEPKEYS: … … 825 759 break; 826 760 case SIOCS80211: 827 error = suser(curthread); 828 if (error) 829 break; 761 if (!capable(CAP_SYS_ADMIN)) { 762 error = EPERM; 763 break; 764 } 830 765 ireq = (struct ieee80211req *) data; 831 766 switch (ireq->i_type) { … … 836 771 break; 837 772 } 838 error = copy in(ireq->i_data, tmpssid, ireq->i_len);773 error = copy_from_user(tmpssid, ireq->i_data, ireq->i_len); 839 774 if (error) 840 775 break; … … 872 807 } 873 808 memset(tmpkey, 0, sizeof(tmpkey)); 874 error = copy in(ireq->i_data, tmpkey, ireq->i_len);809 error = copy_from_user(tmpkey, ireq->i_data, ireq->i_len); 875 810 if (error) 876 811 break; … … 956 891 break; 957 892 case SIOCGIFGENERIC: 958 error = ieee80211_cfgget( ifp, cmd, data);893 error = ieee80211_cfgget(dev, cmd, data); 959 894 break; 960 895 case SIOCSIFGENERIC: 961 error = suser(curthread);962 if (error)963 break;964 error = ieee80211_cfgset(ifp, cmd, data);896 if (capable(CAP_SYS_ADMIN)) 897
