ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c
Revision: 1.7
Committed: 2002-01-06T14:05:35Z (22 years, 10 months ago) by cebix
Content type: text/plain
Branch: MAIN
Changes since 1.6: +18 -24 lines
Log Message:
updated for kernel 2.4.9

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