]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/orinoco/orinoco-modules-0.13e/monitor-0.13e.patch
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / orinoco / orinoco-modules-0.13e / monitor-0.13e.patch
1 diff -urN dist/orinoco-0.13e/hermes.c orinoco-monitor/hermes.c
2 --- dist/orinoco-0.13e/hermes.c 2003-05-12 16:22:27.000000000 +1000
3 +++ orinoco-monitor/hermes.c    2003-05-13 13:26:02.000000000 +1000
4 @@ -183,6 +183,10 @@
5         if (err)
6                 return err;
7  
8 +       for (k = 0; k < HERMES_NUMPORTS_MAX; k++) {
9 +               hw->port_enabled[k] = 0;
10 +       }
11 +
12         reg = hermes_read_regn(hw, EVSTAT);
13         k = CMD_INIT_TIMEOUT;
14         while ( (! (reg & HERMES_EV_CMD)) && k) {
15 diff -urN dist/orinoco-0.13e/hermes.h orinoco-monitor/hermes.h
16 --- dist/orinoco-0.13e/hermes.h 2003-05-12 16:22:27.000000000 +1000
17 +++ orinoco-monitor/hermes.h    2003-05-07 16:54:45.000000000 +1000
18 @@ -33,6 +33,10 @@
19  #include <linux/if_ether.h>
20  #include <asm/byteorder.h>
21  
22 +#define                HFA384x_PORTTYPE_IBSS                   ((uint16_t)3)
23 +#define                HFA384x_WEPFLAGS_DISABLE_TXCRYPT        (0x10)
24 +#define                HFA384x_WEPFLAGS_DISABLE_RXCRYPT        (0x80)
25 +
26  /*
27   * Limits and constants
28   */
29 @@ -148,6 +152,14 @@
30  #define                HERMES_MONITOR_ENABLE           (0x000b)
31  #define                HERMES_MONITOR_DISABLE          (0x000f)
32  
33 +/*--------------------------------------------------------------------
34 +Communication Frames: Field Masks for Receive Frames
35 +--------------------------------------------------------------------*/
36 +/*-- Offsets --------*/
37 +#define                HERMES_RX_DATA_LEN_OFF          (44)
38 +#define                HERMES_RX_80211HDR_OFF          (14)
39 +#define                HERMES_RX_DATA_OFF                      (60)
40 +
41  /*
42   * Frame structures and constants
43   */
44 @@ -171,6 +183,7 @@
45  #define        HERMES_RXSTAT_BADCRC            (0x0001)
46  #define        HERMES_RXSTAT_UNDECRYPTABLE     (0x0002)
47  #define        HERMES_RXSTAT_MACPORT           (0x0700)
48 +#define HERMES_RXSTAT_GET_MACPORT(s)   (((s) & HERMES_RXSTAT_MACPORT) >> 8)
49  #define HERMES_RXSTAT_PCF              (0x1000)        /* Frame was received in CF period */
50  #define        HERMES_RXSTAT_MSGTYPE           (0xE000)
51  #define        HERMES_RXSTAT_1042              (0x2000)        /* RFC-1042 frame */
52 @@ -286,6 +299,7 @@
53  #define HERMES_32BIT_REGSPACING        1
54  
55         u16 inten; /* Which interrupts should be enabled? */
56 +       u8 port_enabled[HERMES_NUMPORTS_MAX];
57  
58  #ifdef HERMES_DEBUG_BUFFER
59         struct hermes_debug_entry dbuf[HERMES_DEBUG_BUFSIZE];
60 @@ -339,12 +353,14 @@
61  
62  static inline int hermes_enable_port(hermes_t *hw, int port)
63  {
64 +       hw->port_enabled[port] = 1;
65         return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
66                                  0, NULL);
67  }
68  
69  static inline int hermes_disable_port(hermes_t *hw, int port)
70  {
71 +       hw->port_enabled[port] = 0;
72         return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 
73                                  0, NULL);
74  }
75 diff -urN dist/orinoco-0.13e/orinoco.c orinoco-monitor/orinoco.c
76 --- dist/orinoco-0.13e/orinoco.c        2003-05-12 16:22:27.000000000 +1000
77 +++ orinoco-monitor/orinoco.c   2003-05-13 13:27:31.000000000 +1000
78 @@ -1673,6 +1673,7 @@
79         struct header_struct hdr;
80         struct ethhdr *eh;
81         int err;
82 +       struct ieee802_11_hdr hdr80211;
83  
84         rxfid = hermes_read_regn(hw, RXFID);
85  
86 @@ -1689,6 +1690,8 @@
87         
88         if (status & HERMES_RXSTAT_ERR) {
89                 if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
90 +                       if (dev->type != ARPHRD_ETHER)
91 +                               goto sniffing;
92                         wstats->discard.code++;
93                         DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
94                                dev->name);
95 @@ -1699,7 +1702,7 @@
96                 stats->rx_errors++;
97                 goto drop;
98         }
99 -
100 +sniffing:
101         /* For now we ignore the 802.11 header completely, assuming
102             that the card's firmware has handled anything vital */
103  
104 @@ -1729,81 +1732,111 @@
105                 stats->rx_errors++;
106                 goto drop;
107         }
108 +       /* Now handle frame based on port# */
109 +       switch (HERMES_RXSTAT_GET_MACPORT(status)) {
110 +       case 0:
111 +               /* We need space for the packet data itself, plus an
112 +                * ethernet header, plus 2 bytes so we can align the
113 +                * IP header on a 32bit boundary, plus 1 byte so we
114 +                * can read in odd length packets from the card, which
115 +                * has an IO granularity of 16 bits */
116 +               skb = dev_alloc_skb(length+ETH_HLEN+2+1);
117 +               if (!skb) {
118 +                       printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
119 +                              dev->name);
120 +                       goto drop;
121 +               }
122  
123 -       /* We need space for the packet data itself, plus an ethernet
124 -          header, plus 2 bytes so we can align the IP header on a
125 -          32bit boundary, plus 1 byte so we can read in odd length
126 -          packets from the card, which has an IO granularity of 16
127 -          bits */  
128 -       skb = dev_alloc_skb(length+ETH_HLEN+2+1);
129 -       if (!skb) {
130 -               printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
131 -                      dev->name);
132 -               goto drop;
133 -       }
134 -
135 -       skb_reserve(skb, 2); /* This way the IP header is aligned */
136 -
137 -       /* Handle decapsulation
138 -        * In most cases, the firmware tell us about SNAP frames.
139 -        * For some reason, the SNAP frames sent by LinkSys APs
140 -        * are not properly recognised by most firmwares.
141 -        * So, check ourselves */
142 -       if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
143 -          ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
144 -          is_ethersnap(&hdr)) {
145 -               /* These indicate a SNAP within 802.2 LLC within
146 -                  802.11 frame which we'll need to de-encapsulate to
147 -                  the original EthernetII frame. */
148 +               skb_reserve(skb, 2); /* This way the IP header is aligned */
149  
150 -               if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
151 -                       stats->rx_length_errors++;
152 +               /* Handle decapsulation In most cases, the firmware
153 +                * tell us about SNAP frames.  For some reason, the
154 +                * SNAP frames sent by LinkSys APs are not properly
155 +                * recognised by most firmwares.  So, check ourselves
156 +                * */
157 +               if (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
158 +                   ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
159 +                   is_ethersnap(&hdr)) {
160 +                       /* These indicate a SNAP within 802.2 LLC
161 +                        * within 802.11 frame which we'll need to
162 +                        * de-encapsulate to the original EthernetII
163 +                        * frame. */
164 +
165 +                       if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
166 +                               stats->rx_length_errors++;
167 +                               goto drop;
168 +                       }
169 +                       
170 +                       /* Remove SNAP header, reconstruct EthernetII frame */
171 +                       data_len = length - ENCAPS_OVERHEAD;
172 +                       data_off = HERMES_802_3_OFFSET + sizeof(hdr);
173 +                       
174 +                       eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
175 +                       
176 +                       memcpy(eh, &hdr, 2 * ETH_ALEN);
177 +                       eh->h_proto = hdr.ethertype;
178 +               } else {
179 +                       /* All other cases indicate a genuine 802.3 frame.  No
180 +                          decapsulation needed.  We just throw the whole
181 +                          thing in, and hope the protocol layer can deal with
182 +                          it as 802.3 */
183 +                       data_len = length;
184 +                       data_off = HERMES_802_3_OFFSET;
185 +                       /* FIXME: we re-read from the card data we already read here */
186 +               }
187 +               
188 +               p = skb_put(skb, data_len);
189 +               err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
190 +                                      rxfid, data_off);
191 +               if (err) {
192 +                       printk(KERN_ERR "%s: error %d reading frame. "
193 +                              "Frame dropped.\n", dev->name, err);
194 +                       stats->rx_errors++;
195 +                       goto drop;
196 +               }
197 +               
198 +               dev->last_rx = jiffies;
199 +               skb->dev = dev;
200 +               skb->protocol = eth_type_trans(skb, dev);
201 +               skb->ip_summed = CHECKSUM_NONE;
202 +               
203 +               /* Process the wireless stats if needed */
204 +               orinoco_stat_gather(dev, skb, &desc);
205 +               
206 +               /* Pass the packet to the networking stack */
207 +               netif_rx(skb);
208 +               stats->rx_packets++;
209 +               stats->rx_bytes += length;
210 +               
211 +               return;
212 +               
213 +       case 7:
214 +               if (status & HERMES_RXSTAT_BADCRC) {
215 +                        printk(KERN_DEBUG "%s: Received monitor frame: "
216 +                              "BADCRC set\n", dev->name);
217                         goto drop;
218                 }
219  
220 -               /* Remove SNAP header, reconstruct EthernetII frame */
221 -               data_len = length - ENCAPS_OVERHEAD;
222 -               data_off = HERMES_802_3_OFFSET + sizeof(hdr);
223 +               err = hermes_bap_pread(hw, IRQ_BAP, &hdr80211,
224 +                                      sizeof(hdr80211), 
225 +                                      rxfid, HERMES_RX_80211HDR_OFF);
226  
227 -               eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
228 +               if (err) {
229 +                       printk(KERN_ERR "%s: error %d reading monitor frame. "
230 +                              "Frame dropped.\n", dev->name, err);
231 +                       stats->rx_errors++;
232 +                       goto drop;
233 +               }
234  
235 -               memcpy(eh, &hdr, 2 * ETH_ALEN);
236 -               eh->h_proto = hdr.ethertype;
237 -       } else {
238 -               /* All other cases indicate a genuine 802.3 frame.  No
239 -                  decapsulation needed.  We just throw the whole
240 -                  thing in, and hope the protocol layer can deal with
241 -                  it as 802.3 */
242 -               data_len = length;
243 -               data_off = HERMES_802_3_OFFSET;
244 -               /* FIXME: we re-read from the card data we already read here */
245 -       }
246 +               orinoco_int_rxmonitor(dev, rxfid, length,
247 +                                     &desc, &hdr80211);
248 +                break;
249  
250 -       p = skb_put(skb, data_len);
251 -       err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
252 -                              rxfid, data_off);
253 -       if (err) {
254 -               printk(KERN_ERR "%s: error %d reading frame. "
255 -                      "Frame dropped.\n", dev->name, err);
256 -               stats->rx_errors++;
257 -               goto drop;
258 +       default:
259 +               printk("Received frame on unsupported port=%d\n",
260 +                      HERMES_RXSTAT_GET_MACPORT(status));
261 +               break;
262         }
263 -
264 -       dev->last_rx = jiffies;
265 -       skb->dev = dev;
266 -       skb->protocol = eth_type_trans(skb, dev);
267 -       skb->ip_summed = CHECKSUM_NONE;
268 -       
269 -       /* Process the wireless stats if needed */
270 -       orinoco_stat_gather(dev, skb, &desc);
271 -
272 -       /* Pass the packet to the networking stack */
273 -       netif_rx(skb);
274 -       stats->rx_packets++;
275 -       stats->rx_bytes += length;
276 -
277 -       return;
278 -
279   drop: 
280         stats->rx_dropped++;
281  
282 @@ -3598,6 +3631,159 @@
283         return 0;
284  }
285  
286 +static int orinoco_wlansniff(struct net_device *dev, struct iwreq *wrq)
287 +{
288 +       struct orinoco_private *priv = dev->priv;
289 +       hermes_t *hw = &priv->hw;
290 +       int err = 0;
291 +       u16 word;
292 +       int *parms = (int *) wrq->u.name;
293 +       int enable = parms[0] > 0;
294 +       unsigned long flags;
295 +
296 +       err = orinoco_lock(priv, &flags);
297 +       if (err)
298 +               return err;
299 +
300 +       switch (enable) {
301 +       case 0:
302 +               /* Confirm that we're in monitor mode */
303 +               if (dev->type == ARPHRD_ETHER)
304 +                       err = -EFAULT;
305 +
306 +               /* Disable monitor mode */
307 +               word =  HERMES_CMD_MONITOR | (HERMES_MONITOR_DISABLE << 8);
308 +               err = hermes_docmd_wait(hw, word, 0, NULL);
309 +               if (err)
310 +                       break;
311 +
312 +               /* Disable port 0 */
313 +               err = hermes_disable_port(hw, 0);
314 +               if (err)
315 +                       break;
316 +
317 +               /* Clear the driver state */
318 +               dev->type = ARPHRD_ETHER;
319 +
320 +               /* Restore the wepflags */   /*Orinoco doesn't like this*/
321 +#if 0
322 +               err = hermes_write_wordrec(hw, USER_BAP,
323 +                                          HERMES_RID_CNFWEPFLAGS_INTERSIL, 
324 +                                          priv->presniff_wepflags);
325 +               if (err)
326 +                       break;
327 +#endif /* 0 */
328 +
329 +               /* Set the port to its prior type and enable (if necessary) */
330 +               if (priv->presniff_port_type != 0) {
331 +                       word = priv->presniff_port_type;
332 +                       err = hermes_write_wordrec(hw, USER_BAP, 
333 +                                                  HERMES_RID_CNFPORTTYPE,
334 +                                                  word);
335 +                       if (err)
336 +                               break;
337 +                       
338 +                       /* Enable the port */
339 +                       err = hermes_enable_port(hw, 0);
340 +                       if (err)
341 +                               break;
342 +               }
343 +
344 +               break;
345 +
346 +       case 1:
347 +               /* Re-initialize the card before changing channel as advised at
348 +                * http://lists.samba.org/pipermail/wireless/2002-June/004491.html
349 +                * by Ian Goldberg.  Implementation by Pat Swieskowski.
350 +                */
351 +/*             __orinoco_down(dev); */
352 +               hermes_set_irqmask(hw, 0);
353 +               hermes_init(hw);
354 +/*             __orinoco_up(dev); */
355 +               hermes_set_irqmask(hw, ORINOCO_INTEN);
356 +               /* Disable the port (if enabled), only check Port 0 */
357 +               if (hw->port_enabled[0]) {
358 +                       /* Save macport 0 state */
359 +                       err = hermes_read_wordrec(hw, USER_BAP,
360 +                                                 HERMES_RID_CNFPORTTYPE,
361 +                                                 &(priv->presniff_port_type));
362 +                       if (err)
363 +                               break;
364 +                   
365 +                       /* Save the wepflags state */
366 +                       err = hermes_read_wordrec(hw, USER_BAP,
367 +                                                 HERMES_RID_CNFWEPFLAGS_INTERSIL,
368 +                                                 &(priv->presniff_wepflags));
369 +                       if (err)
370 +                               break;
371 +                       err = hermes_disable_port(hw, 0);
372 +                       if (err)
373 +                               break;
374 +               } else {
375 +                       priv->presniff_port_type = 0;
376 +               }
377 +
378 +               /* Set the channel we wish to sniff  */
379 +               if ((parms[1] > 0) && (parms[1] < 15)) {
380 +                       word = parms[1];
381 +                       err = hermes_write_wordrec(hw, USER_BAP, 
382 +                                                  HERMES_RID_CNFOWNCHANNEL,
383 +                                                  word);
384 +               } else {
385 +                       err = -EFAULT;
386 +               }
387 +
388 +               if (err)
389 +                       break;
390 +
391 +               /* Set the port type to pIbss */
392 +               word = HFA384x_PORTTYPE_IBSS;
393 +               err = hermes_write_wordrec(hw, USER_BAP, 
394 +                                          HERMES_RID_CNFPORTTYPE, word);
395 +               if (err)
396 +                       break;
397 +
398 +#if 0
399 +               if ( (msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && 
400 +                    (msg->keepwepflags.data != 1)) {
401 +                       /* Set the wepflags for no decryption */
402 +                       /* Orinoco doesn't like this */
403 +                       word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | 
404 +                               HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
405 +                       err = hermes_write_wordrec(hw, USER_BAP, 
406 +                                                  HERMES_RID_CNFWEPFLAGS_INTERSIL,
407 +                                                  word); /*won't work with the bits above */
408 +               }
409 +               if (err)
410 +                       break;
411 +#endif /* 0 */
412 +               /* Enable the port */
413 +               err = hermes_enable_port(hw, 0);
414 +               if (err)
415 +                       break;
416 +
417 +               /* Enable monitor mode */
418 +               word =  HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8);
419 +               err = hermes_docmd_wait(hw, word, 0, NULL);
420 +               if (err)
421 +                       break;
422 +
423 +               /* Set the driver state */
424 +               /* Do we want the prism2 header? */
425 +               if (parms[0] == 1)
426 +                       dev->type = ARPHRD_IEEE80211_PRISM;
427 +               else 
428 +                       dev->type = ARPHRD_IEEE80211;
429 +               break;
430 +       default:
431 +               BUG();
432 +               break;
433 +       }
434 +
435 +       orinoco_unlock(priv, &flags);
436 +       return err;
437 +}
438 +
439  static int
440  orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
441  {
442 @@ -3830,6 +4016,9 @@
443                                 { SIOCIWFIRSTPRIV + 0x7, 0,
444                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
445                                   "get_ibssport" },
446 +                               { SIOCIWFIRSTPRIV + 0x8,
447 +                                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
448 +                                 0, "monitor" },
449                                 { SIOCIWLASTPRIV, 0, 0, "dump_recs" },
450                         };
451  
452 @@ -3924,6 +4113,16 @@
453                 err = orinoco_ioctl_getibssport(dev, wrq);
454                 break;
455  
456 +       case SIOCIWFIRSTPRIV + 0x8: /* set sniff (monitor) mode */ 
457 +               DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x8 (monitor)\n",
458 +                     dev->name);
459 +               if (! capable(CAP_NET_ADMIN)) {
460 +                       err = -EPERM;
461 +                       break;
462 +               }
463 +               err = orinoco_wlansniff(dev, wrq);
464 +               break;
465 +
466         case SIOCIWLASTPRIV:
467                 err = orinoco_debug_dump_recs(dev);
468                 if (err)
469 @@ -4171,6 +4370,191 @@
470  
471  }
472  
473 +/*----------------------------------------------------------------
474 +* orinoco_int_rxmonitor
475 +*
476 +* Handles monitor frames.  Note that this function allocates space for
477 +* the FCS and sets it to 0xffffffff.  The hfa384x doesn't give us the
478 +* FCS value but the higher layers expect it.  0xffffffff is used as a
479 +* flag to indicate the FCS is bogus.
480 +*
481 +* Arguments:
482 +*      dev             wlan device structure
483 +*      rxfid           received FID
484 +*      rxdesc          rx descriptor read from card in int_rx
485 +*
486 +* Side effects:
487 +*      Allocates an skb and passes it up via the PF_PACKET interface.
488 +* Call context:
489 +*      interrupt
490 +----------------------------------------------------------------*/
491 +void orinoco_int_rxmonitor(struct net_device *dev, u16 rxfid,
492 +                          int len, struct hermes_rx_descriptor *rxdesc,
493 +                          struct ieee802_11_hdr *hdr)
494 +{
495 +       struct orinoco_private *priv = dev->priv;
496 +       hermes_t *hw = &priv->hw;
497 +       u32 hdrlen = 0;
498 +       u32 datalen = 0;
499 +       u32 skblen = 0;
500 +       p80211msg_lnxind_wlansniffrm_t *msg;
501 +       struct net_device_stats *stats = &priv->stats;
502 +       u8 *datap;
503 +       u16 fc;
504 +       struct sk_buff *skb;
505 +
506 +       /* Don't forget the status, time, and data_len fields are in
507 +        * little-endian order */
508 +       /* Figure out how big the frame is */
509 +       fc = le16_to_cpu(hdr->frame_ctl);
510 +       switch (fc & IEEE802_11_FCTL_FTYPE) {
511 +       case IEEE802_11_FTYPE_DATA:
512 +               if ((fc & IEEE802_11_FCTL_TODS)
513 +                   && (fc & IEEE802_11_FCTL_FROMDS))
514 +                       hdrlen = WLAN_HDR_A4_LEN;
515 +               else
516 +                       hdrlen = WLAN_HDR_A3_LEN;
517 +               datalen = len;
518 +               break;
519 +       case IEEE802_11_FTYPE_MGMT:
520 +               hdrlen = WLAN_HDR_A3_LEN;
521 +               datalen = len;
522 +               break;
523 +       case IEEE802_11_FTYPE_CTL:
524 +               switch (fc & IEEE802_11_FCTL_STYPE) {
525 +               case IEEE802_11_STYPE_PSPOLL:
526 +               case IEEE802_11_STYPE_RTS:
527 +               case IEEE802_11_STYPE_CFEND:
528 +               case IEEE802_11_STYPE_CFENDACK:
529 +                       hdrlen = 16;
530 +                       break;
531 +               case IEEE802_11_STYPE_CTS:
532 +               case IEEE802_11_STYPE_ACK:
533 +                       hdrlen = 10;
534 +                       break;
535 +               }
536 +               datalen = 0;
537 +               break;
538 +       default:
539 +               printk("unknown frm: fc=0x%04x\n", fc);
540 +               return;
541 +       }
542 +
543 +       /* Allocate an ind message+framesize skb */
544 +       skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) + 
545 +               hdrlen + datalen;
546 +       
547 +       /* sanity check the length */
548 +       if ( skblen > 
549 +               ( (sizeof(p80211msg_lnxind_wlansniffrm_t) + 
550 +                  WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) ) {
551 +               printk("overlen frm: len=%d\n", 
552 +                      skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
553 +       }
554 +
555 +       if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
556 +               printk("alloc_skb failed trying to allocate %d bytes\n", skblen);
557 +               return;
558 +       }
559 +
560 +       /* only prepend the prism header if in the right mode */
561 +       if (dev->type != ARPHRD_IEEE80211_PRISM) {
562 +               skb_put(skb, skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
563 +               datap = skb->data;
564 +       } else {
565 +               skb_put(skb, skblen);
566 +               datap = skb->data + sizeof(p80211msg_lnxind_wlansniffrm_t);
567 +               msg = (p80211msg_lnxind_wlansniffrm_t*)skb->data;
568 +
569 +               /* Initialize the message members */
570 +               msg->msgcode = DIDmsg_lnxind_wlansniffrm;
571 +               msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
572 +               strcpy(msg->devname, dev->name);
573 +         
574 +               msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
575 +               msg->hosttime.status = 0;
576 +               msg->hosttime.len = 4;
577 +               msg->hosttime.data = jiffies;
578 +         
579 +               msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
580 +               msg->mactime.status = 0;
581 +               msg->mactime.len = 4;
582 +               msg->mactime.data = rxdesc->time;
583 +         
584 +               msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
585 +               msg->channel.status = P80211ENUM_msgitem_status_no_value;
586 +               msg->channel.len = 4;
587 +               msg->channel.data = 0;
588 +
589 +               msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
590 +               msg->rssi.status = P80211ENUM_msgitem_status_no_value;
591 +               msg->rssi.len = 4;
592 +               msg->rssi.data = 0;
593 +         
594 +               msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
595 +               msg->sq.status = P80211ENUM_msgitem_status_no_value;
596 +               msg->sq.len = 4;
597 +               msg->sq.data = 0;
598 +         
599 +               msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
600 +               msg->signal.status = 0;
601 +               msg->signal.len = 4;
602 +               msg->signal.data = rxdesc->signal;
603 +         
604 +               msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
605 +               msg->noise.status = 0;
606 +               msg->noise.len = 4;
607 +               msg->noise.data = rxdesc->silence;
608 +
609 +               msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
610 +               msg->rate.status = 0;
611 +               msg->rate.len = 4;
612 +               msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
613 +  
614 +               msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
615 +               msg->istx.status = 0;
616 +               msg->istx.len = 4;
617 +               msg->istx.data = 0;
618 +         
619 +               msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
620 +               msg->frmlen.status = 0;
621 +               msg->frmlen.len = 4;
622 +               msg->frmlen.data = hdrlen + datalen;
623 +       }
624 +
625 +       /* Copy the 802.11 header to the skb (ctl frames may be less
626 +        * than a full header) */
627 +       memcpy(datap, &(hdr->frame_ctl), hdrlen);
628 +
629 +       /* If any, copy the data from the card to the skb */
630 +       if (datalen > 0) {
631 +               hermes_bap_pread(hw, IRQ_BAP, datap + hdrlen, (datalen+1)&~1,
632 +                                rxfid, HERMES_RX_DATA_OFF);
633 +
634 +               /* check for unencrypted stuff if WEP bit set. */
635 +               if (datap[1] & 0x40) /* wep set */
636 +                       if ((datap[hdrlen] == 0xaa)
637 +                           && (datap[hdrlen+1] == 0xaa))
638 +                               datap[1] &= 0xbf; /* clear wep; it's the 802.2 header! */
639 +       }
640 +
641 +       /* pass it up via the PF_PACKET interface */
642 +       skb->dev = dev;
643 +       skb->dev->last_rx = jiffies;
644 +
645 +       skb->mac.raw = skb->data ;
646 +       skb->ip_summed = CHECKSUM_NONE;
647 +       skb->pkt_type = PACKET_OTHERHOST;
648 +       skb->protocol = htons(ETH_P_80211_RAW);  /* XXX ETH_P_802_2? */
649 +       
650 +       stats->rx_packets++;
651 +       stats->rx_bytes += skb->len;
652 +
653 +       netif_rx(skb);
654 +
655 +       return;
656 +}
657 +
658  /********************************************************************/
659  /* Module initialization                                            */
660  /********************************************************************/
661 diff -urN dist/orinoco-0.13e/orinoco.h orinoco-monitor/orinoco.h
662 --- dist/orinoco-0.13e/orinoco.h        2003-05-12 16:22:27.000000000 +1000
663 +++ orinoco-monitor/orinoco.h   2003-05-13 13:27:02.000000000 +1000
664 @@ -37,6 +37,16 @@
665  /* To enable debug messages */
666  //#define ORINOCO_DEBUG                3
667  
668 +#define ETH_P_80211_RAW        (ETH_P_ECONET + 1)
669 +
670 +#ifndef ARPHRD_IEEE80211
671 +#define ARPHRD_IEEE80211 801     /* kernel 2.4.6 */
672 +#endif
673 +
674 +#ifndef ARPHRD_IEEE80211_PRISM  /* kernel 2.4.18 */
675 +#define ARPHRD_IEEE80211_PRISM 802
676 +#endif
677 +
678  #if (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10)
679  #error "orinoco driver requires Wireless extensions v10 or later."
680  #endif /* (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10) */
681 @@ -55,6 +65,67 @@
682                                 HERMES_EV_INFDROP )
683  
684  
685 +#define WLAN_DEVNAMELEN_MAX 16
686 +
687 +/* message data item for INT, BOUNDEDINT, ENUMINT */
688 +typedef struct p80211item_uint32 {
689 +       u32 did;
690 +       u16 status;
691 +       u16 len;
692 +       u32 data;
693 +} __attribute__ ((packed)) p80211item_uint32_t;
694 +
695 +#define DIDmsg_lnxind_wlansniffrm              0x0041
696 +#define DIDmsg_lnxind_wlansniffrm_hosttime     0x1041
697 +#define DIDmsg_lnxind_wlansniffrm_mactime      0x2041
698 +#define DIDmsg_lnxind_wlansniffrm_channel      0x3041
699 +#define DIDmsg_lnxind_wlansniffrm_rssi         0x4041
700 +#define DIDmsg_lnxind_wlansniffrm_sq           0x5041
701 +#define DIDmsg_lnxind_wlansniffrm_signal       0x6041
702 +#define DIDmsg_lnxind_wlansniffrm_noise                0x7041
703 +#define DIDmsg_lnxind_wlansniffrm_rate         0x8041
704 +#define DIDmsg_lnxind_wlansniffrm_istx         0x9041
705 +#define DIDmsg_lnxind_wlansniffrm_frmlen       0xA041
706 +
707 +typedef struct p80211msg_lnxind_wlansniffrm {
708 +       u32 msgcode;
709 +       u32 msglen;
710 +       u8 devname[WLAN_DEVNAMELEN_MAX];
711 +       p80211item_uint32_t hosttime;
712 +       p80211item_uint32_t mactime;
713 +       p80211item_uint32_t channel;
714 +       p80211item_uint32_t rssi;
715 +       p80211item_uint32_t sq;
716 +       p80211item_uint32_t signal;
717 +       p80211item_uint32_t noise;
718 +       p80211item_uint32_t rate;
719 +       p80211item_uint32_t istx;
720 +       p80211item_uint32_t frmlen;
721 +} __attribute__ ((packed)) p80211msg_lnxind_wlansniffrm_t;
722 +
723 +#define P80211ENUM_msgitem_status_data_ok              0
724 +#define P80211ENUM_msgitem_status_no_value             1
725 +#define P80211ENUM_msgitem_status_invalid_itemname     2
726 +#define P80211ENUM_msgitem_status_invalid_itemdata     3
727 +#define P80211ENUM_msgitem_status_missing_itemdata     4
728 +#define P80211ENUM_msgitem_status_incomplete_itemdata  5
729 +#define P80211ENUM_msgitem_status_invalid_msg_did      6
730 +#define P80211ENUM_msgitem_status_invalid_mib_did      7
731 +#define P80211ENUM_msgitem_status_missing_conv_func    8
732 +#define P80211ENUM_msgitem_status_string_too_long      9
733 +#define P80211ENUM_msgitem_status_data_out_of_range    10
734 +#define P80211ENUM_msgitem_status_string_too_short     11
735 +#define P80211ENUM_msgitem_status_missing_valid_func   12
736 +#define P80211ENUM_msgitem_status_unknown              13
737 +#define P80211ENUM_msgitem_status_invalid_did          14
738 +#define P80211ENUM_msgitem_status_missing_print_func   15
739 +
740 +/*--- Sizes -----------------------------------------------*/
741 +#define WLAN_CRC_LEN                   4
742 +#define WLAN_HDR_A3_LEN                        24
743 +#define WLAN_HDR_A4_LEN                        30
744 +#define WLAN_DATA_MAXLEN               2312
745 +
746  struct orinoco_private {
747         void *card;     /* Pointer to card dependent structure */
748         int (*hard_reset)(struct orinoco_private *);
749 @@ -116,6 +187,9 @@
750         /* Configuration dependent variables */
751         int port_type, createibss;
752         int promiscuous, mc_count;
753 +
754 +       u16 presniff_port_type;
755 +       u16 presniff_wepflags;
756  };
757  
758  #ifdef ORINOCO_DEBUG