]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/orinoco/orinoco-modules-0.13e/shmoo-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 / shmoo-monitor-0.13e.patch
1 diff -aur orinoco-0.13e/hermes.c orinoco-0.13e-patched/hermes.c
2 --- orinoco-0.13e/hermes.c      2003-05-11 23:22:27.000000000 -0700
3 +++ orinoco-0.13e-patched/hermes.c      2003-08-07 04:16:04.000000000 -0700
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 -aur orinoco-0.13e/hermes.h orinoco-0.13e-patched/hermes.h
16 --- orinoco-0.13e/hermes.h      2003-05-11 23:22:27.000000000 -0700
17 +++ orinoco-0.13e-patched/hermes.h      2003-08-07 04:16:04.000000000 -0700
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 @@ -149,6 +153,38 @@
30  #define                HERMES_MONITOR_DISABLE          (0x000f)
31  
32  /*
33 + * Configuration RIDs
34 + */
35 +
36 +#define                HERMES_RID_CNF_PORTTYPE         (0xfc00)
37 +#define                HERMES_RID_CNF_CHANNEL          (0xfc03)
38 +#define                HERMES_RID_CNF_PRISM2_WEP_ON    (0xfc28)
39 +
40 +/*-- Status Fields --*/
41 +#define                HERMES_RXSTATUS_MSGTYPE         (0xE000)
42 +#define                HERMES_RXSTATUS_MACPORT         (0x0700)
43 +#define                HERMES_RXSTATUS_UNDECR          (0x0002)
44 +#define                HERMES_RXSTATUS_FCSERR          (0x0001)
45 +
46 +/*--------------------------------------------------------------------
47 +Communication Frames: Test/Get/Set Field Values for Receive Frames
48 +--------------------------------------------------------------------*/
49 +#define                HERMES_RXSTATUS_MSGTYPE_GET(value)      (((value) & HERMES_RXSTATUS_MSGTYPE) >> 13)
50 +#define                HERMES_RXSTATUS_MSGTYPE_SET(value)      ((value) << 13)
51 +#define                HERMES_RXSTATUS_MACPORT_GET(value)      (((value) & HERMES_RXSTATUS_MACPORT) >> 8)
52 +#define                HERMES_RXSTATUS_MACPORT_SET(value)      ((value) << 8)
53 +#define                HERMES_RXSTATUS_ISUNDECR(value) ((value) & HERMES_RXSTATUS_UNDECR)
54 +#define                HERMES_RXSTATUS_ISFCSERR(value) ((value) & HERMES_RXSTATUS_FCSERR)
55 +
56 +/*--------------------------------------------------------------------
57 +Communication Frames: Field Masks for Receive Frames
58 +--------------------------------------------------------------------*/
59 +/*-- Offsets --------*/
60 +#define                HERMES_RX_DATA_LEN_OFF          (44)
61 +#define                HERMES_RX_80211HDR_OFF          (14)
62 +#define                HERMES_RX_DATA_OFF                      (60)
63 +
64 +/*
65   * Frame structures and constants
66   */
67  
68 @@ -286,6 +322,7 @@
69  #define HERMES_32BIT_REGSPACING        1
70  
71         u16 inten; /* Which interrupts should be enabled? */
72 +       uint8_t         port_enabled[HERMES_NUMPORTS_MAX];
73  
74  #ifdef HERMES_DEBUG_BUFFER
75         struct hermes_debug_entry dbuf[HERMES_DEBUG_BUFSIZE];
76 @@ -339,12 +376,14 @@
77  
78  static inline int hermes_enable_port(hermes_t *hw, int port)
79  {
80 +        hw->port_enabled[port] = 1;
81         return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
82                                  0, NULL);
83  }
84  
85  static inline int hermes_disable_port(hermes_t *hw, int port)
86  {
87 +        hw->port_enabled[port] = 0;
88         return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 
89                                  0, NULL);
90  }
91 diff -aur orinoco-0.13e/orinoco.c orinoco-0.13e-patched/orinoco.c
92 --- orinoco-0.13e/orinoco.c     2003-05-11 23:22:27.000000000 -0700
93 +++ orinoco-0.13e-patched/orinoco.c     2003-08-07 04:16:04.000000000 -0700
94 @@ -1673,6 +1673,7 @@
95         struct header_struct hdr;
96         struct ethhdr *eh;
97         int err;
98 +        struct ieee802_11_hdr hdr80211;
99  
100         rxfid = hermes_read_regn(hw, RXFID);
101  
102 @@ -1689,6 +1690,7 @@
103         
104         if (status & HERMES_RXSTAT_ERR) {
105                 if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
106 +                    if (dev->type != ARPHRD_ETHER) goto sniffing;
107                         wstats->discard.code++;
108                         DEBUG(1, "%s: Undecryptable frame on Rx. Frame dropped.\n",
109                                dev->name);
110 @@ -1699,7 +1701,7 @@
111                 stats->rx_errors++;
112                 goto drop;
113         }
114 -
115 +sniffing:
116         /* For now we ignore the 802.11 header completely, assuming
117             that the card's firmware has handled anything vital */
118  
119 @@ -1730,6 +1732,11 @@
120                 goto drop;
121         }
122  
123 +       /* Now handle frame based on port# */
124 +       switch( HERMES_RXSTATUS_MACPORT_GET(status) )
125 +       {
126 +       case 0:
127 +
128         /* We need space for the packet data itself, plus an ethernet
129            header, plus 2 bytes so we can align the IP header on a
130            32bit boundary, plus 1 byte so we can read in odd length
131 @@ -1804,6 +1811,26 @@
132  
133         return;
134  
135 +       case 7:
136 +               if ( ! HERMES_RXSTATUS_ISFCSERR(status) ) {
137 +                   if (hermes_bap_pread(hw, IRQ_BAP, &hdr80211, sizeof(hdr80211), 
138 +                                       rxfid, HERMES_RX_80211HDR_OFF)) {
139 +                      stats->rx_errors++;
140 +                   }
141 +                   else {
142 +                        /* Copy to wlansnif skb */
143 +                        orinoco_int_rxmonitor( priv, rxfid, length, &desc, &hdr80211);
144 +                   }
145 +                } else {
146 +                        printk("Received monitor frame: FCSerr set\n");
147 +                }
148 +                break;
149 +       default:
150 +               printk("Received frame on unsupported port=%d\n",
151 +                       HERMES_RXSTATUS_MACPORT_GET(status) );
152 +               break;
153 +       }
154 +
155   drop: 
156         stats->rx_dropped++;
157  
158 @@ -2446,6 +2473,24 @@
159         return err;
160  }
161  
162 +//#define SET_MAC_ADDRESS
163 +#ifdef SET_MAC_ADDRESS
164 +static int
165 +orinoco_set_mac_address(struct net_device *dev, void *addr)
166 +{
167 +  struct orinoco_private *priv = dev->priv;
168 +  struct sockaddr *mac = addr;
169 +
170 +  /* Copy the address */
171 +  memcpy(dev->dev_addr, mac->sa_data, WLAN_ADDR_LEN);
172 +
173 +  /* Reconfig the beast */
174 +  orinoco_reset(priv);
175 +
176 +  return 0;
177 +}
178 +#endif /* SET_MAC_ADDRESS */
179 +
180  static void
181  orinoco_tx_timeout(struct net_device *dev)
182  {
183 @@ -3598,6 +3643,173 @@
184         return 0;
185  }
186  
187 +/*----------------------------------------------------------------
188 +* orinoco_wlansniff
189 +*
190 +* Start or stop sniffing.
191 +*
192 +* Arguments:
193 +*      wlandev         wlan device structure
194 +*      msgp            ptr to msg buffer
195 +*
196 +* Returns: 
197 +*      0       success and done
198 +*      <0      success, but we're waiting for something to finish.
199 +*      >0      an error occurred while handling the message.
200 +* Side effects:
201 +*
202 +* Call context:
203 +*      process thread  (usually)
204 +*      interrupt
205 +----------------------------------------------------------------*/
206 +static int orinoco_wlansniff(struct net_device *dev, struct iwreq *wrq)
207 +{
208 +       struct orinoco_private *priv = dev->priv;
209 +
210 +       hermes_t                *hw = &(priv->hw);
211 +        hermes_response_t  resp;
212 +       int                     result = 0;
213 +       uint16_t                        word;
214 +
215 +       int *parms = (int *) wrq->u.name;
216 +       int enable = parms[0] > 0;
217 +       unsigned long flags;
218 +
219 +       orinoco_lock(priv, &flags);
220 +
221 +       switch (enable)
222 +       {
223 +       case P80211ENUM_truth_false:
224 +               /* Confirm that we're in monitor mode */
225 +               if ( dev->type == ARPHRD_ETHER ) {
226 +                       result = -EFAULT;
227 +               }
228 +               /* Disable monitor mode */
229 +               word =  HERMES_CMD_MONITOR | (HERMES_MONITOR_DISABLE << 8);
230 +               result = hermes_docmd_wait(hw, word, 0, &resp);
231 +
232 +               if ( result ) break;
233 +
234 +               /* Disable port 0 */
235 +               result = hermes_disable_port(hw, 0);
236 +               if ( result ) break;
237 +
238 +               /* Clear the driver state */
239 +               dev->type = ARPHRD_ETHER;
240 +
241 +               /* Restore the wepflags */   //Orinoco doesn't like this
242 +/*
243 +               result = hermes_write_wordrec(hw, USER_BAP,
244 +                               HERMES_RID_CNF_PRISM2_WEP_ON, 
245 +                               priv->presniff_wepflags);
246 +               if ( result ) break;
247 +
248 +*/
249 +               /* Set the port to its prior type and enable (if necessary) */
250 +               if (priv->presniff_port_type != 0 ) {
251 +                       word = priv->presniff_port_type;
252 +                       result = hermes_write_wordrec(hw, USER_BAP, 
253 +                               HERMES_RID_CNF_PORTTYPE, word);
254 +                   if ( result ) break;
255 +
256 +                       /* Enable the port */
257 +                       result = hermes_enable_port(hw, 0);
258 +                   if ( result ) break;
259 +
260 +               }
261 +
262 +               break;
263 +       case P80211ENUM_truth_true:
264 +             /* Re-initialize the card before changing channel as advised at
265 +              * http://lists.samba.org/pipermail/wireless/2002-June/004491.html
266 +              * by Ian Goldberg.  Implementation by Pat Swieskowski.
267 +              */
268 +//             __orinoco_down(dev);
269 +                hermes_set_irqmask(hw, 0);
270 +               hermes_init(hw);
271 +//             _orinoco_up(dev);
272 +                hermes_set_irqmask(hw, ORINOCO_INTEN);
273 +/*
274 +               __orinoco_stop_irqs(priv);
275 +               hermes_reset(hw);
276 +               __orinoco_start_irqs(priv, HERMES_EV_RX | HERMES_EV_ALLOC |
277 +                                  HERMES_EV_TX | HERMES_EV_TXEXC |
278 +                                  HERMES_EV_WTERR | HERMES_EV_INFO |
279 +                                  HERMES_EV_INFDROP);
280 +*/
281 +               /* Disable the port (if enabled), only check Port 0 */
282 +               if ( hw->port_enabled[0] ) {
283 +                       /* Save macport 0 state */
284 +                       result = hermes_read_wordrec(hw, USER_BAP,
285 +                                       HERMES_RID_CNF_PORTTYPE,
286 +                                       &(priv->presniff_port_type));
287 +                   if ( result ) break;
288 +
289 +                       /* Save the wepflags state */
290 +                       result = hermes_read_wordrec(hw, USER_BAP,
291 +                                       HERMES_RID_CNF_PRISM2_WEP_ON,
292 +                                       &(priv->presniff_wepflags));
293 +                   if ( result ) break;
294 +                       result = hermes_disable_port(hw, 0);
295 +                   if ( result ) break;
296 +               }
297 +               else {
298 +                       priv->presniff_port_type = 0;
299 +               }
300 +
301 +               /* Set the channel we wish to sniff  */
302 +               if (parms[1] > 0 && parms[1] < 15) {
303 +                 word = parms[1];
304 +                 result = hermes_write_wordrec(hw, USER_BAP, 
305 +                                 HERMES_RID_CNF_CHANNEL, word);
306 +               } else {
307 +                 result = -EFAULT;
308 +               }
309 +
310 +               if ( result ) break;
311 +
312 +               /* Set the port type to pIbss */
313 +               word = HFA384x_PORTTYPE_IBSS;
314 +               result = hermes_write_wordrec(hw, USER_BAP, 
315 +                               HERMES_RID_CNF_PORTTYPE, word);
316 +               if ( result ) break;
317 +
318 +/*
319 +               if ( (msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && 
320 +                     (msg->keepwepflags.data != P80211ENUM_truth_true)) {
321 +                 // Set the wepflags for no decryption   //Orinoco doesn't like this
322 +                 word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | 
323 +                            HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
324 +                 result = hermes_write_wordrec(hw, USER_BAP, 
325 +                                HERMES_RID_CNF_PRISM2_WEP_ON, word); //won't work with the bits above
326 +                }
327 +               if ( result ) break;
328 +
329 +*/
330 +               /* Enable the port */
331 +               result = hermes_enable_port(hw, 0);
332 +               if ( result ) break;
333 +
334 +               /* Enable monitor mode */
335 +               word =  HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8);
336 +               result = hermes_docmd_wait(hw, word, 0, &resp);
337 +               if ( result ) break;
338 +
339 +               /* Set the driver state */
340 +               /* Do we want the prism2 header? */
341 +               if (parms[0] == 1)
342 +                 dev->type = ARPHRD_IEEE80211_PRISM;
343 +               else 
344 +                 dev->type = ARPHRD_IEEE80211;
345 +               break;
346 +       default:
347 +               result = -EFAULT;
348 +               break;
349 +       }
350 +       orinoco_unlock(priv, &flags);
351 +       return result;
352 +}
353 +
354  static int
355  orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
356  {
357 @@ -3830,6 +4042,9 @@
358                                 { SIOCIWFIRSTPRIV + 0x7, 0,
359                                   IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
360                                   "get_ibssport" },
361 +                               { SIOCIWFIRSTPRIV + 0x8,
362 +                                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
363 +                                 0, "monitor" },
364                                 { SIOCIWLASTPRIV, 0, 0, "dump_recs" },
365                         };
366  
367 @@ -3924,6 +4139,16 @@
368                 err = orinoco_ioctl_getibssport(dev, wrq);
369                 break;
370  
371 +        case SIOCIWFIRSTPRIV + 0x8: /* set sniff (monitor) mode */ 
372 +               DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x8 (monitor)\n",
373 +                     dev->name);
374 +               if (! capable(CAP_NET_ADMIN)) {
375 +                       err = -EPERM;
376 +                       break;
377 +               }
378 +                err = orinoco_wlansniff(dev, wrq);
379 +               break;
380 +
381         case SIOCIWLASTPRIV:
382                 err = orinoco_debug_dump_recs(dev);
383                 if (err)
384 @@ -4146,6 +4371,9 @@
385         dev->tx_timeout = orinoco_tx_timeout;
386         dev->watchdog_timeo = HZ; /* 1 second timeout */
387         dev->get_stats = orinoco_get_stats;
388 +#ifdef SET_MAC_ADDRESS
389 +        dev->set_mac_address = orinoco_set_mac_address;
390 +#endif /* SET_MAC_ADDRESS */
391         dev->get_wireless_stats = orinoco_get_wireless_stats;
392         dev->do_ioctl = orinoco_ioctl;
393         dev->change_mtu = orinoco_change_mtu;
394 @@ -4171,6 +4399,197 @@
395  
396  }
397  
398 +/*----------------------------------------------------------------
399 +* orinoco_int_rxmonitor
400 +*
401 +* Helper function for int_rx.  Handles monitor frames.
402 +* Note that this function allocates space for the FCS and sets it
403 +* to 0xffffffff.  The hfa384x doesn't give us the FCS value but the
404 +* higher layers expect it.  0xffffffff is used as a flag to indicate
405 +* the FCS is bogus.
406 +*
407 +* Arguments:
408 +*      dev             wlan device structure
409 +*      rxfid           received FID
410 +*      rxdesc          rx descriptor read from card in int_rx
411 +*
412 +* Returns: 
413 +*      nothing
414 +*
415 +* Side effects:
416 +*      Allocates an skb and passes it up via the PF_PACKET interface.
417 +* Call context:
418 +*      interrupt
419 +----------------------------------------------------------------*/
420 +void orinoco_int_rxmonitor( struct orinoco_private *dev, uint16_t rxfid, int len,
421 +                            struct hermes_rx_descriptor *rxdesc, struct ieee802_11_hdr *hdr)
422 +{
423 +       hermes_t                        *hw = &(dev->hw);
424 +       uint32_t                                hdrlen = 0;
425 +       uint32_t                                datalen = 0;
426 +       uint32_t                                skblen = 0;
427 +       p80211msg_lnxind_wlansniffrm_t  *msg;
428 +       struct net_device_stats *stats = &dev->stats;
429 +
430 +
431 +       uint8_t                         *datap;
432 +       uint16_t                                fc;
433 +       struct sk_buff                  *skb;
434 +
435 +       /* Don't forget the status, time, and data_len fields are in host order */
436 +       /* Figure out how big the frame is */
437 +       fc = le16_to_cpu(hdr->frame_ctl);
438 +       switch ( WLAN_GET_FC_FTYPE(fc) )
439 +       {
440 +       case WLAN_FTYPE_DATA:
441 +               if ( WLAN_GET_FC_TODS(fc) && WLAN_GET_FC_FROMDS(fc) ) {
442 +                       hdrlen = WLAN_HDR_A4_LEN;
443 +               } else {
444 +                       hdrlen = WLAN_HDR_A3_LEN;
445 +               }
446 +               datalen = len;
447 +               break;
448 +       case WLAN_FTYPE_MGMT:
449 +               hdrlen = WLAN_HDR_A3_LEN;
450 +               datalen = len;
451 +               break;
452 +       case WLAN_FTYPE_CTL:
453 +               switch ( WLAN_GET_FC_FSTYPE(fc) )
454 +               {
455 +               case WLAN_FSTYPE_PSPOLL:
456 +               case WLAN_FSTYPE_RTS:
457 +               case WLAN_FSTYPE_CFEND:
458 +               case WLAN_FSTYPE_CFENDCFACK:
459 +                       hdrlen = 16;
460 +                       break;
461 +               case WLAN_FSTYPE_CTS:
462 +               case WLAN_FSTYPE_ACK:
463 +                       hdrlen = 10;
464 +                       break;
465 +               }
466 +               datalen = 0;
467 +               break;
468 +       default:
469 +               printk("unknown frm: fc=0x%04x\n", fc);
470 +               return;
471 +       }
472 +
473 +       /* Allocate an ind message+framesize skb */
474 +       skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) + 
475 +         hdrlen + datalen;
476 +       
477 +       /* sanity check the length */
478 +       if ( skblen > 
479 +               (sizeof(p80211msg_lnxind_wlansniffrm_t) + 
480 +               WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
481 +               printk("overlen frm: len=%d\n", 
482 +                       skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
483 +       }
484 +                       
485 +       if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
486 +               printk("alloc_skb failed trying to allocate %d bytes\n", skblen);
487 +               return;
488 +       }
489 +
490 +       /* only prepend the prism header if in the right mode */
491 +       if (dev->ndev->type != ARPHRD_IEEE80211_PRISM) {
492 +         skb_put(skb, skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
493 +         datap = skb->data;
494 +       } else {
495 +         skb_put(skb, skblen);
496 +         datap = skb->data + sizeof(p80211msg_lnxind_wlansniffrm_t);
497 +         msg = (p80211msg_lnxind_wlansniffrm_t*)skb->data;
498 +         
499 +         /* Initialize the message members */
500 +         msg->msgcode = DIDmsg_lnxind_wlansniffrm;
501 +         msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
502 +         strcpy(msg->devname, dev->ndev->name);
503 +         
504 +         msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
505 +         msg->hosttime.status = 0;
506 +         msg->hosttime.len = 4;
507 +         msg->hosttime.data = jiffies;
508 +         
509 +         msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
510 +         msg->mactime.status = 0;
511 +         msg->mactime.len = 4;
512 +         msg->mactime.data = rxdesc->time;
513 +         
514 +         msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
515 +         msg->channel.status = P80211ENUM_msgitem_status_no_value;
516 +         msg->channel.len = 4;
517 +         msg->channel.data = 0;
518 +
519 +         msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
520 +         msg->rssi.status = P80211ENUM_msgitem_status_no_value;
521 +         msg->rssi.len = 4;
522 +         msg->rssi.data = 0;
523 +         
524 +         msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
525 +         msg->sq.status = P80211ENUM_msgitem_status_no_value;
526 +         msg->sq.len = 4;
527 +         msg->sq.data = 0;
528 +         
529 +         msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
530 +         msg->signal.status = 0;
531 +         msg->signal.len = 4;
532 +         msg->signal.data = rxdesc->signal;
533 +         
534 +         msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
535 +         msg->noise.status = 0;
536 +         msg->noise.len = 4;
537 +         msg->noise.data = rxdesc->silence;
538 +
539 +         msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
540 +         msg->rate.status = 0;
541 +         msg->rate.len = 4;
542 +         msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
543 +  
544 +         msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
545 +         msg->istx.status = 0;
546 +         msg->istx.len = 4;
547 +         msg->istx.data = P80211ENUM_truth_false;
548 +         
549 +         msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
550 +         msg->frmlen.status = 0;
551 +         msg->frmlen.len = 4;
552 +         msg->frmlen.data = hdrlen + datalen;
553 +       }         
554 +
555 +       /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
556 +       memcpy( datap, &(hdr->frame_ctl), hdrlen);
557 +
558 +       /* If any, copy the data from the card to the skb */
559 +       if ( datalen > 0 )
560 +       {
561 +               hermes_bap_pread(hw, IRQ_BAP, datap + hdrlen, (datalen+1)&~1,
562 +                                      rxfid, HERMES_RX_DATA_OFF);
563 +
564 +               /* check for unencrypted stuff if WEP bit set. */
565 +               if (*(datap+1) & 0x40) // wep set
566 +                 if ((*(datap+hdrlen) == 0xaa) && (*(datap+hdrlen+1) == 0xaa))
567 +                   *(datap+1) &= 0xbf; // clear wep; it's the 802.2 header!
568 +       }
569 +
570 +       /* pass it up via the PF_PACKET interface */
571 +       {
572 +          skb->dev = dev->ndev;
573 +          skb->dev->last_rx = jiffies;
574 +
575 +          skb->mac.raw = skb->data ;
576 +          skb->ip_summed = CHECKSUM_NONE;
577 +          skb->pkt_type = PACKET_OTHERHOST;
578 +          skb->protocol = htons(ETH_P_80211_RAW);  /* XXX ETH_P_802_2? */
579 +
580 +          stats->rx_packets++;
581 +          stats->rx_bytes += skb->len;
582 +
583 +          netif_rx(skb);
584 +       }
585 +
586 +       return;
587 +}
588 +
589  /********************************************************************/
590  /* Module initialization                                            */
591  /********************************************************************/
592 diff -aur orinoco-0.13e/orinoco.h orinoco-0.13e-patched/orinoco.h
593 --- orinoco-0.13e/orinoco.h     2003-05-11 23:22:27.000000000 -0700
594 +++ orinoco-0.13e-patched/orinoco.h     2003-08-07 04:16:04.000000000 -0700
595 @@ -37,6 +37,20 @@
596  /* To enable debug messages */
597  //#define ORINOCO_DEBUG                3
598  
599 +#ifndef ETH_P_ECONET
600 +#define ETH_P_ECONET   0x0018    /* needed for 2.2.x kernels */
601 +#endif
602 +
603 +#define ETH_P_80211_RAW        (ETH_P_ECONET + 1)
604 +
605 +#ifndef ARPHRD_IEEE80211
606 +#define ARPHRD_IEEE80211 801     /* kernel 2.4.6 */
607 +#endif
608 +
609 +#ifndef ARPHRD_IEEE80211_PRISM  /* kernel 2.4.18 */
610 +#define ARPHRD_IEEE80211_PRISM 802
611 +#endif
612 +
613  #if (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10)
614  #error "orinoco driver requires Wireless extensions v10 or later."
615  #endif /* (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10) */
616 @@ -54,6 +68,158 @@
617                                 HERMES_EV_TXEXC | HERMES_EV_WTERR | HERMES_EV_INFO | \
618                                 HERMES_EV_INFDROP )
619  
620 +#define WLAN_DEVNAMELEN_MAX 16
621 +
622 +/* message data item for INT, BOUNDEDINT, ENUMINT */
623 +typedef struct p80211item_uint32
624 +{
625 +       uint32_t                did             __attribute__ ((packed));
626 +       uint16_t                status  __attribute__ ((packed));
627 +       uint16_t                len             __attribute__ ((packed));
628 +       uint32_t                data    __attribute__ ((packed));
629 +} __attribute__ ((packed)) p80211item_uint32_t;
630 +
631 +typedef struct p80211msg
632 +{
633 +       uint32_t        msgcode         __attribute__ ((packed));
634 +       uint32_t        msglen          __attribute__ ((packed));
635 +       uint8_t devname[WLAN_DEVNAMELEN_MAX]    __attribute__ ((packed));
636 +} __attribute__ ((packed)) p80211msg_t;
637 +
638 +#define DIDmsg_lnxind_wlansniffrm 0x0041
639 +#define DIDmsg_lnxind_wlansniffrm_hosttime 0x1041
640 +#define DIDmsg_lnxind_wlansniffrm_mactime 0x2041
641 +#define DIDmsg_lnxind_wlansniffrm_channel 0x3041
642 +#define DIDmsg_lnxind_wlansniffrm_rssi 0x4041
643 +#define DIDmsg_lnxind_wlansniffrm_sq 0x5041
644 +#define DIDmsg_lnxind_wlansniffrm_signal 0x6041
645 +#define DIDmsg_lnxind_wlansniffrm_noise 0x7041
646 +#define DIDmsg_lnxind_wlansniffrm_rate 0x8041
647 +#define DIDmsg_lnxind_wlansniffrm_istx 0x9041
648 +#define DIDmsg_lnxind_wlansniffrm_frmlen 0xA041
649 +
650 +typedef struct p80211msg_lnxind_wlansniffrm
651 +{
652 +       uint32_t                msgcode;
653 +       uint32_t                msglen;
654 +       uint8_t             devname[WLAN_DEVNAMELEN_MAX];
655 +       p80211item_uint32_t     hosttime;
656 +       p80211item_uint32_t     mactime;
657 +       p80211item_uint32_t     channel;
658 +       p80211item_uint32_t     rssi;
659 +       p80211item_uint32_t     sq;
660 +       p80211item_uint32_t     signal;
661 +       p80211item_uint32_t     noise;
662 +       p80211item_uint32_t     rate;
663 +       p80211item_uint32_t     istx;
664 +       p80211item_uint32_t     frmlen;
665 +} __attribute__ ((packed)) p80211msg_lnxind_wlansniffrm_t;
666 +
667 +#define P80211ENUM_truth_false                 0
668 +#define P80211ENUM_truth_true                  1
669 +#define P80211ENUM_resultcode_success          1
670 +#define P80211ENUM_resultcode_invalid_parameters       2
671 +#define P80211ENUM_resultcode_not_supported    3
672 +#define P80211ENUM_resultcode_timeout          4
673 +#define P80211ENUM_resultcode_too_many_req     5
674 +#define P80211ENUM_resultcode_refused          6
675 +#define P80211ENUM_resultcode_bss_already      7
676 +#define P80211ENUM_resultcode_invalid_access   8
677 +#define P80211ENUM_resultcode_invalid_mibattribute     9
678 +#define P80211ENUM_resultcode_cant_set_readonly_mib    10
679 +#define P80211ENUM_resultcode_implementation_failure   11
680 +#define P80211ENUM_resultcode_cant_get_writeonly_mib   12
681 +#define P80211ENUM_msgitem_status_data_ok              0
682 +#define P80211ENUM_msgitem_status_no_value             1
683 +#define P80211ENUM_msgitem_status_invalid_itemname     2
684 +#define P80211ENUM_msgitem_status_invalid_itemdata     3
685 +#define P80211ENUM_msgitem_status_missing_itemdata     4
686 +#define P80211ENUM_msgitem_status_incomplete_itemdata  5
687 +#define P80211ENUM_msgitem_status_invalid_msg_did      6
688 +#define P80211ENUM_msgitem_status_invalid_mib_did      7
689 +#define P80211ENUM_msgitem_status_missing_conv_func    8
690 +#define P80211ENUM_msgitem_status_string_too_long      9
691 +#define P80211ENUM_msgitem_status_data_out_of_range    10
692 +#define P80211ENUM_msgitem_status_string_too_short     11
693 +#define P80211ENUM_msgitem_status_missing_valid_func   12
694 +#define P80211ENUM_msgitem_status_unknown              13
695 +#define P80211ENUM_msgitem_status_invalid_did          14
696 +#define P80211ENUM_msgitem_status_missing_print_func   15
697 +
698 +#define WLAN_GET_FC_FTYPE(n)   (((n) & 0x0C) >> 2)
699 +#define WLAN_GET_FC_FSTYPE(n)  (((n) & 0xF0) >> 4)
700 +#define WLAN_GET_FC_TODS(n)    (((n) & 0x0100) >> 8)
701 +#define WLAN_GET_FC_FROMDS(n)  (((n) & 0x0200) >> 9)
702 +
703 +/*--- Sizes -----------------------------------------------*/
704 +#define WLAN_ADDR_LEN                  6
705 +#define WLAN_CRC_LEN                   4
706 +#define WLAN_BSSID_LEN                 6
707 +#define WLAN_BSS_TS_LEN                        8
708 +#define WLAN_HDR_A3_LEN                        24
709 +#define WLAN_HDR_A4_LEN                        30
710 +#define WLAN_SSID_MAXLEN               32
711 +#define WLAN_DATA_MAXLEN               2312
712 +
713 +/*--- Frame Control Field -------------------------------------*/
714 +/* Frame Types */
715 +#define WLAN_FTYPE_MGMT                        0x00
716 +#define WLAN_FTYPE_CTL                 0x01
717 +#define WLAN_FTYPE_DATA                        0x02
718 +
719 +/* Frame subtypes */
720 +/* Management */
721 +#define WLAN_FSTYPE_ASSOCREQ           0x00
722 +#define WLAN_FSTYPE_ASSOCRESP          0x01
723 +#define WLAN_FSTYPE_REASSOCREQ         0x02
724 +#define WLAN_FSTYPE_REASSOCRESP                0x03
725 +#define WLAN_FSTYPE_PROBEREQ           0x04 
726 +#define WLAN_FSTYPE_PROBERESP          0x05
727 +#define WLAN_FSTYPE_BEACON             0x08
728 +#define WLAN_FSTYPE_ATIM               0x09
729 +#define WLAN_FSTYPE_DISASSOC           0x0a
730 +#define WLAN_FSTYPE_AUTHEN             0x0b
731 +#define WLAN_FSTYPE_DEAUTHEN           0x0c
732 +
733 +/* Control */
734 +#define WLAN_FSTYPE_PSPOLL             0x0a
735 +#define WLAN_FSTYPE_RTS                        0x0b
736 +#define WLAN_FSTYPE_CTS                        0x0c
737 +#define WLAN_FSTYPE_ACK                        0x0d
738 +#define WLAN_FSTYPE_CFEND              0x0e
739 +#define WLAN_FSTYPE_CFENDCFACK         0x0f
740 +
741 +/* Data */
742 +#define WLAN_FSTYPE_DATAONLY           0x00
743 +#define WLAN_FSTYPE_DATA_CFACK         0x01
744 +#define WLAN_FSTYPE_DATA_CFPOLL                0x02
745 +#define WLAN_FSTYPE_DATA_CFACK_CFPOLL  0x03
746 +#define WLAN_FSTYPE_NULL               0x04
747 +#define WLAN_FSTYPE_CFACK              0x05
748 +#define WLAN_FSTYPE_CFPOLL             0x06
749 +#define WLAN_FSTYPE_CFACK_CFPOLL       0x07
750 +
751 +/*----------------------------------------------------------------*/
752 +/* Magic number, a quick test to see we're getting the desired struct */
753 +
754 +#define P80211_IOCTL_MAGIC     (0x4a2d464dUL)
755 +
756 +/*================================================================*/
757 +/* Types */
758 +
759 +/*----------------------------------------------------------------*/
760 +/* A ptr to the following structure type is passed as the third */
761 +/*  argument to the ioctl system call when issuing a request to */
762 +/*  the p80211 module. */
763 +
764 +typedef struct p80211ioctl_req
765 +{
766 +       char    name[WLAN_DEVNAMELEN_MAX] __attribute__ ((packed));
767 +       void    *data           __attribute__ ((packed));
768 +       uint32_t        magic   __attribute__ ((packed));
769 +       uint16_t        len     __attribute__ ((packed));
770 +       uint32_t        result  __attribute__ ((packed));
771 +} __attribute__ ((packed)) p80211ioctl_req_t;
772  
773  struct orinoco_private {
774         void *card;     /* Pointer to card dependent structure */
775 @@ -116,6 +282,9 @@
776         /* Configuration dependent variables */
777         int port_type, createibss;
778         int promiscuous, mc_count;
779 +
780 +       uint16_t                presniff_port_type;
781 +       uint16_t                presniff_wepflags;
782  };
783  
784  #ifdef ORINOCO_DEBUG
785 @@ -163,4 +332,12 @@
786         spin_unlock_irqrestore(&priv->lock, *flags);
787  }
788  
789 +/*================================================================*/
790 +/* Function Declarations */
791 +
792 +struct ieee802_11_hdr;
793 +
794 +void orinoco_int_rxmonitor( struct orinoco_private *dev, uint16_t rxfid, int len,
795 +                            struct hermes_rx_descriptor *rxdesc, struct ieee802_11_hdr *hdr);
796 +
797  #endif /* _ORINOCO_H */