ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c
Revision: 1.5
Committed: 2001-03-28T14:18:58Z (23 years, 8 months ago) by cebix
Content type: text/plain
Branch: MAIN
CVS Tags: snapshot-29052001, release-0_9-1
Changes since 1.4: +15 -6 lines
Log Message:
cleaned up a little

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