ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c
Revision: 1.13
Committed: 2005-03-22T13:31:13Z (19 years, 4 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
Changes since 1.12: +8 -5 lines
Log Message:
fix build with kernels >= 2.6.9

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