ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c
Revision: 1.9
Committed: 2002-07-23T18:02:47Z (21 years, 11 months ago) by cebix
Content type: text/plain
Branch: MAIN
Changes since 1.8: +22 -0 lines
Log Message:
fixes by Steven N. Hirsch (versioned symbols, module license)

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * sheep_net.c - Linux driver for SheepShaver/Basilisk II networking (access to raw Ethernet packets)
3     *
4 cebix 1.8 * sheep_net (C) 1999-2002 Mar"c" Hellwig and Christian Bauer
5 cebix 1.1 *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21 cebix 1.9 #ifndef __KERNEL__
22     #define __KERNEL__
23     #endif
24    
25     #ifndef MODULE
26     #define MODULE
27     #endif
28    
29     /* determine whether to use checksummed versions of kernel symbols */
30     #include <linux/config.h>
31     #ifdef CONFIG_MODVERSIONS
32     #define MODVERSIONS
33     #include <linux/modversions.h>
34     #endif
35    
36     /* modversions.h redefines kernel symbols. Now include other headers */
37     #include <linux/kernel.h>
38     #include <linux/module.h>
39     #include <linux/init.h>
40    
41 cebix 1.7 #include <linux/kernel.h>
42 cebix 1.1 #include <linux/module.h>
43     #include <linux/version.h>
44     #include <linux/miscdevice.h>
45     #include <linux/netdevice.h>
46     #include <linux/etherdevice.h>
47     #include <linux/if_ether.h>
48     #include <linux/if_arp.h>
49 cebix 1.7 #include <linux/fs.h>
50 cebix 1.1 #include <linux/poll.h>
51     #include <linux/init.h>
52     #include <net/sock.h>
53 cebix 1.7 #include <asm/uaccess.h>
54 cebix 1.4 #include <net/arp.h>
55     #include <net/ip.h>
56 cebix 1.7 #include <linux/in.h>
57     #include <linux/wait.h>
58 cebix 1.1
59 cebix 1.5 MODULE_AUTHOR("Christian Bauer");
60     MODULE_DESCRIPTION("Pseudo ethernet device for emulators");
61    
62 cebix 1.4 /* Compatibility glue */
63     #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
64     #define LINUX_24
65     #else
66     #define net_device device
67     typedef struct wait_queue *wait_queue_head_t;
68     #define init_waitqueue_head(x) *(x)=NULL
69     #endif
70    
71 cebix 1.1 #define DEBUG 0
72    
73     #define bug printk
74     #if DEBUG
75     #define D(x) (x);
76     #else
77     #define D(x) ;
78     #endif
79    
80    
81 cebix 1.4 /* Constants */
82     #define SHEEP_NET_MINOR 198 /* Driver minor number */
83     #define MAX_QUEUE 32 /* Maximum number of packets in queue */
84     #define PROT_MAGIC 1520 /* Our "magic" protocol type */
85 cebix 1.1
86 cebix 1.4 #define ETH_ADDR_MULTICAST 0x1
87 cebix 1.7 #define ETH_ADDR_LOCALLY_DEFINED 0x02
88 cebix 1.4
89     #define SIOC_MOL_GET_IPFILTER SIOCDEVPRIVATE
90     #define SIOC_MOL_SET_IPFILTER (SIOCDEVPRIVATE + 1)
91    
92     /* Prototypes */
93 cebix 1.1 static int sheep_net_open(struct inode *inode, struct file *f);
94     static int sheep_net_release(struct inode *inode, struct file *f);
95     static ssize_t sheep_net_read(struct file *f, char *buf, size_t count, loff_t *off);
96     static ssize_t sheep_net_write(struct file *f, const char *buf, size_t count, loff_t *off);
97     static unsigned int sheep_net_poll(struct file *f, struct poll_table_struct *wait);
98     static int sheep_net_ioctl(struct inode *inode, struct file *f, unsigned int code, unsigned long arg);
99 cebix 1.4 static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt);
100 cebix 1.1
101    
102     /*
103     * Driver private variables
104     */
105    
106     struct SheepVars {
107 cebix 1.4 struct net_device *ether; /* The Ethernet device we're attached to */
108     struct sock *skt; /* Socket for communication with Ethernet card */
109     struct sk_buff_head queue; /* Receiver packet queue */
110     struct packet_type pt; /* Receiver packet type */
111     wait_queue_head_t wait; /* Wait queue for blocking read operations */
112     u32 ipfilter; /* Only receive IP packets destined for this address (host byte order) */
113     char eth_addr[6]; /* Hardware address of the Ethernet card */
114     char fake_addr[6]; /* Local faked hardware address (what SheepShaver sees) */
115 cebix 1.1 };
116    
117    
118     /*
119     * file_operations structure - has function pointers to the
120     * various entry points for device operations
121     */
122    
123     static struct file_operations sheep_net_fops = {
124 cebix 1.4 read: sheep_net_read,
125     write: sheep_net_write,
126     poll: sheep_net_poll,
127     ioctl: sheep_net_ioctl,
128     open: sheep_net_open,
129     release: sheep_net_release,
130 cebix 1.1 };
131    
132    
133     /*
134     * miscdevice structure for driver initialization
135     */
136    
137     static struct miscdevice sheep_net_device = {
138 cebix 1.4 SHEEP_NET_MINOR, /* minor number */
139     "sheep_net", /* name */
140 cebix 1.1 &sheep_net_fops,
141     NULL,
142     NULL
143     };
144    
145    
146     /*
147     * Initialize module
148     */
149    
150     int init_module(void)
151     {
152     int ret;
153    
154 cebix 1.4 /* Register driver */
155 cebix 1.1 ret = misc_register(&sheep_net_device);
156     D(bug("Sheep net driver installed\n"));
157     return ret;
158     }
159    
160    
161     /*
162     * Deinitialize module
163     */
164    
165 cebix 1.7 int cleanup_module(void)
166 cebix 1.1 {
167 cebix 1.7 int ret;
168    
169 cebix 1.4 /* Unregister driver */
170 cebix 1.7 ret = misc_deregister(&sheep_net_device);
171 cebix 1.1 D(bug("Sheep net driver removed\n"));
172 cebix 1.7 return ret;
173 cebix 1.1 }
174    
175    
176     /*
177     * Driver open() function
178     */
179    
180     static int sheep_net_open(struct inode *inode, struct file *f)
181     {
182     struct SheepVars *v;
183     D(bug("sheep_net: open\n"));
184    
185 cebix 1.4 /* Must be opened with read permissions */
186 cebix 1.1 if ((f->f_flags & O_ACCMODE) == O_WRONLY)
187     return -EPERM;
188    
189 cebix 1.4 /* Allocate private variables */
190 cebix 1.1 v = (struct SheepVars *)f->private_data = kmalloc(sizeof(struct SheepVars), GFP_USER);
191     if (v == NULL)
192     return -ENOMEM;
193     memset(v, 0, sizeof(struct SheepVars));
194     skb_queue_head_init(&v->queue);
195 cebix 1.4 init_waitqueue_head(&v->wait);
196     v->fake_addr[0] = 0xfe;
197     v->fake_addr[1] = 0xfd;
198     v->fake_addr[2] = 0xde;
199     v->fake_addr[3] = 0xad;
200     v->fake_addr[4] = 0xbe;
201     v->fake_addr[5] = 0xef;
202 cebix 1.1
203 cebix 1.4 /* Yes, we're open */
204 cebix 1.1 MOD_INC_USE_COUNT;
205     return 0;
206     }
207    
208    
209     /*
210     * Driver release() function
211     */
212    
213     static int sheep_net_release(struct inode *inode, struct file *f)
214     {
215     struct SheepVars *v = (struct SheepVars *)f->private_data;
216     struct sk_buff *skb;
217     D(bug("sheep_net: close\n"));
218    
219 cebix 1.4 /* Detach from Ethernet card */
220 cebix 1.1 if (v->ether) {
221     dev_remove_pack(&v->pt);
222     sk_free(v->skt);
223     v->skt = NULL;
224 cebix 1.4 #ifdef LINUX_24
225     dev_put( v->ether );
226     #endif
227 cebix 1.1 v->ether = NULL;
228     }
229    
230 cebix 1.4 /* Empty packet queue */
231 cebix 1.1 while ((skb = skb_dequeue(&v->queue)) != NULL)
232     dev_kfree_skb(skb);
233    
234 cebix 1.4 /* Free private variables */
235 cebix 1.1 kfree(v);
236    
237 cebix 1.4 /* Sorry, we're closed */
238 cebix 1.1 MOD_DEC_USE_COUNT;
239     return 0;
240     }
241    
242    
243     /*
244 cebix 1.4 * Check whether an Ethernet address is the local (attached) one or
245     * the fake one
246     */
247    
248     static inline int is_local_addr(struct SheepVars *v, void *a)
249     {
250     return memcmp(a, v->eth_addr, 6) == 0;
251     }
252    
253     static inline int is_fake_addr(struct SheepVars *v, void *a)
254     {
255     return memcmp(a, v->fake_addr, 6) == 0;
256     }
257    
258    
259     /*
260     * Outgoing packet. Replace the fake enet addr with the real local one.
261     */
262    
263     static inline void do_demasq(struct SheepVars *v, u8 *p)
264     {
265     memcpy(p, v->eth_addr, 6);
266     }
267    
268     static void demasquerade(struct SheepVars *v, struct sk_buff *skb)
269     {
270     u8 *p = skb->mac.raw;
271     int proto = (p[12] << 8) | p[13];
272    
273     do_demasq(v, p + 6); /* source address */
274    
275     /* Need to fix ARP packets */
276     if (proto == ETH_P_ARP) {
277     if (is_fake_addr(v, p + 14 + 8)) /* sender HW-addr */
278     do_demasq(v, p + 14 + 8);
279     }
280    
281     /* ...and AARPs (snap code: 0x00,0x00,0x00,0x80,0xF3) */
282     if (p[17] == 0 && p[18] == 0 && p[19] == 0 && p[20] == 0x80 && p[21] == 0xf3) {
283     /* XXX: we should perhaps look for the 802 frame too */
284     if (is_fake_addr(v, p + 30))
285     do_demasq(v, p + 30); /* sender HW-addr */
286     }
287     }
288    
289    
290     /*
291     * Incoming packet. Replace the local enet addr with the fake one.
292     */
293    
294     static inline void do_masq(struct SheepVars *v, u8 *p)
295     {
296     memcpy(p, v->fake_addr, 6);
297     }
298    
299     static void masquerade(struct SheepVars *v, struct sk_buff *skb)
300     {
301     u8 *p = skb->mac.raw;
302     if (!(p[0] & ETH_ADDR_MULTICAST))
303     do_masq(v, p); /* destination address */
304    
305     /* XXX: reverse ARP might need to be fixed */
306     }
307    
308    
309     /*
310 cebix 1.1 * Driver read() function
311     */
312    
313     static ssize_t sheep_net_read(struct file *f, char *buf, size_t count, loff_t *off)
314     {
315     struct SheepVars *v = (struct SheepVars *)f->private_data;
316     struct sk_buff *skb;
317 cebix 1.4
318 cebix 1.1 D(bug("sheep_net: read\n"));
319    
320     for (;;) {
321    
322 cebix 1.4 /* Get next packet from queue */
323 cebix 1.1 skb = skb_dequeue(&v->queue);
324     if (skb != NULL || (f->f_flags & O_NONBLOCK))
325     break;
326    
327 cebix 1.4 /* No packet in queue and in blocking mode, so block */
328 cebix 1.1 interruptible_sleep_on(&v->wait);
329    
330 cebix 1.4 /* Signal received? Then bail out */
331     if (signal_pending(current))
332     return -EINTR;
333 cebix 1.1 }
334     if (skb == NULL)
335     return -EAGAIN;
336    
337 cebix 1.4 /* Pass packet to caller */
338 cebix 1.1 if (count > skb->len)
339     count = skb->len;
340     if (copy_to_user(buf, skb->data, count))
341     count = -EFAULT;
342     dev_kfree_skb(skb);
343     return count;
344     }
345    
346    
347     /*
348     * Driver write() function
349     */
350    
351     static ssize_t sheep_net_write(struct file *f, const char *buf, size_t count, loff_t *off)
352     {
353     struct SheepVars *v = (struct SheepVars *)f->private_data;
354     struct sk_buff *skb;
355     char *p;
356     D(bug("sheep_net: write\n"));
357    
358 cebix 1.4 /* Check packet size */
359 cebix 1.1 if (count < sizeof(struct ethhdr))
360     return -EINVAL;
361 cebix 1.7 if (count > 1514) {
362     printk("sheep_net_write: packet size > 1514\n");
363 cebix 1.1 count = 1514;
364 cebix 1.7 }
365 cebix 1.1
366 cebix 1.4 /* Interface active? */
367 cebix 1.1 if (v->ether == NULL)
368     return count;
369    
370 cebix 1.4 /* Allocate buffer for packet */
371 cebix 1.1 skb = dev_alloc_skb(count);
372     if (skb == NULL)
373     return -ENOBUFS;
374    
375 cebix 1.4 /* Stuff packet in buffer */
376 cebix 1.1 p = skb_put(skb, count);
377     if (copy_from_user(p, buf, count)) {
378     kfree_skb(skb);
379     return -EFAULT;
380     }
381    
382 cebix 1.4 /* Transmit packet */
383 cebix 1.1 atomic_add(skb->truesize, &v->skt->wmem_alloc);
384     skb->sk = v->skt;
385     skb->dev = v->ether;
386     skb->priority = 0;
387     skb->nh.raw = skb->h.raw = skb->data + v->ether->hard_header_len;
388 cebix 1.4 skb->mac.raw = skb->data;
389    
390     /* Base the IP-filtering on the IP address in any outgoing ARP packets */
391     if (skb->mac.ethernet->h_proto == htons(ETH_P_ARP)) {
392     u8 *p = &skb->data[14+14]; /* source IP address */
393     u32 ip = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
394     if (ip != v->ipfilter) {
395     v->ipfilter = ip;
396     printk("sheep_net: ipfilter set to %d.%d.%d.%d\n", (ip >> 24) & 0xff, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff);
397     }
398     }
399    
400     /* Is this packet addressed solely to the local host? */
401     if (is_local_addr(v, skb->data) && !(skb->data[0] & ETH_ADDR_MULTICAST)) {
402     skb->protocol = eth_type_trans(skb, v->ether);
403     netif_rx(skb);
404     return count;
405     }
406     if (skb->data[0] & ETH_ADDR_MULTICAST) {
407     /* We can't clone the skb since we will manipulate the data below */
408     struct sk_buff *lskb = skb_copy(skb, GFP_ATOMIC);
409     if (lskb) {
410     lskb->protocol = eth_type_trans(lskb, v->ether);
411     netif_rx(lskb);
412     }
413     }
414    
415     /* Outgoing packet (will be on the net) */
416     demasquerade(v, skb);
417    
418     skb->protocol = PROT_MAGIC; /* Magic value (we can recognize the packet in sheep_net_receiver) */
419 cebix 1.1 dev_queue_xmit(skb);
420     return count;
421     }
422    
423    
424     /*
425     * Driver poll() function
426     */
427    
428     static unsigned int sheep_net_poll(struct file *f, struct poll_table_struct *wait)
429     {
430     struct SheepVars *v = (struct SheepVars *)f->private_data;
431     D(bug("sheep_net: poll\n"));
432    
433 cebix 1.4 /* Packets in queue? Then return */
434     if (!skb_queue_empty(&v->queue))
435 cebix 1.1 return POLLIN | POLLRDNORM;
436    
437 cebix 1.4 /* Otherwise wait for packet */
438 cebix 1.1 poll_wait(f, &v->wait, wait);
439 cebix 1.4 if (!skb_queue_empty(&v->queue))
440 cebix 1.1 return POLLIN | POLLRDNORM;
441 cebix 1.4 else
442 cebix 1.1 return 0;
443     }
444    
445    
446     /*
447     * Driver ioctl() function
448     */
449    
450     static int sheep_net_ioctl(struct inode *inode, struct file *f, unsigned int code, unsigned long arg)
451     {
452     struct SheepVars *v = (struct SheepVars *)f->private_data;
453     D(bug("sheep_net: ioctl %04x\n", code));
454    
455     switch (code) {
456    
457 cebix 1.4 /* Attach to Ethernet card
458 cebix 1.7 arg: pointer to name of Ethernet device (char[20]) */
459 cebix 1.1 case SIOCSIFLINK: {
460 cebix 1.7 char name[20];
461 cebix 1.4 int err;
462 cebix 1.1
463 cebix 1.4 /* Already attached? */
464 cebix 1.1 if (v->ether)
465     return -EBUSY;
466    
467 cebix 1.4 /* Get Ethernet card name */
468 cebix 1.7 if (copy_from_user(name, (void *)arg, 20))
469 cebix 1.1 return -EFAULT;
470 cebix 1.7 name[19] = 0;
471 cebix 1.1
472 cebix 1.4 /* Find card */
473     #ifdef LINUX_24
474     v->ether = dev_get_by_name(name);
475     #else
476 cebix 1.1 dev_lock_list();
477     v->ether = dev_get(name);
478 cebix 1.4 #endif
479 cebix 1.1 if (v->ether == NULL) {
480 cebix 1.4 err = -ENODEV;
481     goto error;
482 cebix 1.1 }
483    
484 cebix 1.4 /* Is it Ethernet? */
485 cebix 1.1 if (v->ether->type != ARPHRD_ETHER) {
486 cebix 1.4 err = -EINVAL;
487     goto error;
488 cebix 1.1 }
489    
490 cebix 1.4 /* Remember the card's hardware address */
491     memcpy(v->eth_addr, v->ether->dev_addr, 6);
492    
493     /* Allocate socket */
494 cebix 1.1 v->skt = sk_alloc(0, GFP_USER, 1);
495     if (v->skt == NULL) {
496 cebix 1.4 err = -ENOMEM;
497     goto error;
498 cebix 1.1 }
499     v->skt->dead = 1;
500    
501 cebix 1.4 /* Attach packet handler */
502 cebix 1.1 v->pt.type = htons(ETH_P_ALL);
503     v->pt.dev = v->ether;
504     v->pt.func = sheep_net_receiver;
505     v->pt.data = v;
506     dev_add_pack(&v->pt);
507 cebix 1.4 #ifndef LINUX_24
508 cebix 1.1 dev_unlock_list();
509 cebix 1.4 #endif
510 cebix 1.1 return 0;
511 cebix 1.4
512     error:
513     #ifdef LINUX_24
514     if (v->ether)
515     dev_put(v->ether);
516     #else
517     dev_unlock_list();
518     #endif
519     v->ether = NULL;
520     return err;
521 cebix 1.1 }
522    
523 cebix 1.4 /* Get hardware address of the sheep_net module
524     arg: pointer to buffer (6 bytes) to store address */
525 cebix 1.1 case SIOCGIFADDR:
526 cebix 1.4 if (copy_to_user((void *)arg, v->fake_addr, 6))
527     return -EFAULT;
528     return 0;
529    
530     /* Set the hardware address of the sheep_net module
531     arg: pointer to new address (6 bytes) */
532     case SIOCSIFADDR:
533     if (copy_from_user(v->fake_addr, (void*)arg, 6))
534 cebix 1.1 return -EFAULT;
535     return 0;
536    
537 cebix 1.4 /* Add multicast address
538     arg: pointer to address (6 bytes) */
539 cebix 1.1 case SIOCADDMULTI: {
540     char addr[6];
541     if (v->ether == NULL)
542     return -ENODEV;
543     if (copy_from_user(addr, (void *)arg, 6))
544     return -EFAULT;
545     return dev_mc_add(v->ether, addr, 6, 0);
546     }
547    
548 cebix 1.4 /* Remove multicast address
549     arg: pointer to address (6 bytes) */
550 cebix 1.1 case SIOCDELMULTI: {
551     char addr[6];
552     if (v->ether == NULL)
553     return -ENODEV;
554     if (copy_from_user(addr, (void *)arg, 6))
555     return -EFAULT;
556     return dev_mc_delete(v->ether, addr, 6, 0);
557     }
558    
559 cebix 1.4 /* Return size of first packet in queue */
560 cebix 1.1 case FIONREAD: {
561     int count = 0;
562     struct sk_buff *skb;
563 cebix 1.4 #ifdef LINUX_24
564     long flags;
565     spin_lock_irqsave(&v->queue.lock, flags);
566     #else
567     cli();
568     #endif
569 cebix 1.1 skb = skb_peek(&v->queue);
570     if (skb)
571     count = skb->len;
572 cebix 1.4 #ifdef LINUX_24
573     spin_unlock_irqrestore(&v->queue.lock, flags);
574     #else
575     sti();
576     #endif
577 cebix 1.1 return put_user(count, (int *)arg);
578     }
579    
580 cebix 1.4 case SIOC_MOL_GET_IPFILTER:
581     return put_user(v->ipfilter, (int *)arg);
582    
583     case SIOC_MOL_SET_IPFILTER:
584     v->ipfilter = arg;
585     return 0;
586    
587 cebix 1.1 default:
588     return -ENOIOCTLCMD;
589     }
590     }
591    
592    
593     /*
594     * Packet receiver function
595     */
596    
597 cebix 1.4 static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
598 cebix 1.1 {
599     struct SheepVars *v = (struct SheepVars *)pt->data;
600 cebix 1.4 struct sk_buff *skb2;
601     int fake;
602     int multicast;
603 cebix 1.1 D(bug("sheep_net: packet received\n"));
604    
605 cebix 1.4 multicast = (skb->mac.ethernet->h_dest[0] & ETH_ADDR_MULTICAST);
606     fake = is_fake_addr(v, &skb->mac.ethernet->h_dest);
607    
608     /* Packet sent by us? Then discard */
609     if (is_fake_addr(v, &skb->mac.ethernet->h_source) || skb->protocol == PROT_MAGIC)
610     goto drop;
611    
612     /* If the packet is not meant for this host, discard it */
613     if (!is_local_addr(v, &skb->mac.ethernet->h_dest) && !multicast && !fake)
614     goto drop;
615    
616     /* Discard packets if queue gets too full */
617     if (skb_queue_len(&v->queue) > MAX_QUEUE)
618     goto drop;
619    
620     /* Apply any filters here (if fake is true, then we *know* we want this packet) */
621     if (!fake) {
622     if ((skb->protocol == htons(ETH_P_IP))
623     && (!v->ipfilter || (ntohl(skb->h.ipiph->daddr) != v->ipfilter && !multicast)))
624     goto drop;
625 cebix 1.1 }
626    
627 cebix 1.4 /* Masquerade (we are typically a clone - best to make a real copy) */
628     skb2 = skb_copy(skb, GFP_ATOMIC);
629     if (!skb2)
630     goto drop;
631     kfree_skb(skb);
632     skb = skb2;
633     masquerade(v, skb);
634 cebix 1.1
635 cebix 1.4 /* We also want the Ethernet header */
636 cebix 1.1 skb_push(skb, skb->data - skb->mac.raw);
637    
638 cebix 1.4 /* Enqueue packet */
639 cebix 1.1 skb_queue_tail(&v->queue, skb);
640    
641 cebix 1.4 /* Unblock blocked read */
642 cebix 1.1 wake_up(&v->wait);
643 cebix 1.4 return 0;
644    
645     drop:
646     kfree_skb(skb);
647 cebix 1.1 return 0;
648     }
649 cebix 1.9
650     MODULE_LICENSE("GPL");