ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c
Revision: 1.11
Committed: 2004-01-12T15:54:46Z (20 years, 6 months ago) by cebix
Content type: text/plain
Branch: MAIN
CVS Tags: nigel-build-16, nigel-build-15
Changes since 1.10: +1 -1 lines
Log Message:
Happy New Year!

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