ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c
Revision: 1.15
Committed: 2009-10-20T01:55:03Z (14 years, 9 months ago) by asvitkine
Content type: text/plain
Branch: MAIN
Changes since 1.14: +51 -11 lines
Log Message:
[Joel Mauras]
Patch for network suppor on 2.6 Linux Kernel.

File Contents

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