ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c
Revision: 1.8
Committed: 2002-01-15T14:58:39Z (22 years, 10 months ago) by cebix
Content type: text/plain
Branch: MAIN
CVS Tags: snapshot-15012002
Changes since 1.7: +1 -1 lines
Log Message:
- documentation updates
- 2001 -> 2002
- version 0.9 -> 1.0

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-2002 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 #include <linux/kernel.h>
22 #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 #include <linux/fs.h>
30 #include <linux/poll.h>
31 #include <linux/init.h>
32 #include <net/sock.h>
33 #include <asm/uaccess.h>
34 #include <net/arp.h>
35 #include <net/ip.h>
36 #include <linux/in.h>
37 #include <linux/wait.h>
38
39 MODULE_AUTHOR("Christian Bauer");
40 MODULE_DESCRIPTION("Pseudo ethernet device for emulators");
41
42 /* 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 #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 /* 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
66 #define ETH_ADDR_MULTICAST 0x1
67 #define ETH_ADDR_LOCALLY_DEFINED 0x02
68
69 #define SIOC_MOL_GET_IPFILTER SIOCDEVPRIVATE
70 #define SIOC_MOL_SET_IPFILTER (SIOCDEVPRIVATE + 1)
71
72 /* Prototypes */
73 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 static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt);
80
81
82 /*
83 * Driver private variables
84 */
85
86 struct SheepVars {
87 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 };
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 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 };
111
112
113 /*
114 * miscdevice structure for driver initialization
115 */
116
117 static struct miscdevice sheep_net_device = {
118 SHEEP_NET_MINOR, /* minor number */
119 "sheep_net", /* name */
120 &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 /* Register driver */
135 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 int cleanup_module(void)
146 {
147 int ret;
148
149 /* Unregister driver */
150 ret = misc_deregister(&sheep_net_device);
151 D(bug("Sheep net driver removed\n"));
152 return ret;
153 }
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 /* Must be opened with read permissions */
166 if ((f->f_flags & O_ACCMODE) == O_WRONLY)
167 return -EPERM;
168
169 /* Allocate private variables */
170 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 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
183 /* Yes, we're open */
184 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 /* Detach from Ethernet card */
200 if (v->ether) {
201 dev_remove_pack(&v->pt);
202 sk_free(v->skt);
203 v->skt = NULL;
204 #ifdef LINUX_24
205 dev_put( v->ether );
206 #endif
207 v->ether = NULL;
208 }
209
210 /* Empty packet queue */
211 while ((skb = skb_dequeue(&v->queue)) != NULL)
212 dev_kfree_skb(skb);
213
214 /* Free private variables */
215 kfree(v);
216
217 /* Sorry, we're closed */
218 MOD_DEC_USE_COUNT;
219 return 0;
220 }
221
222
223 /*
224 * 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 * 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
298 D(bug("sheep_net: read\n"));
299
300 for (;;) {
301
302 /* Get next packet from queue */
303 skb = skb_dequeue(&v->queue);
304 if (skb != NULL || (f->f_flags & O_NONBLOCK))
305 break;
306
307 /* No packet in queue and in blocking mode, so block */
308 interruptible_sleep_on(&v->wait);
309
310 /* Signal received? Then bail out */
311 if (signal_pending(current))
312 return -EINTR;
313 }
314 if (skb == NULL)
315 return -EAGAIN;
316
317 /* Pass packet to caller */
318 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 /* Check packet size */
339 if (count < sizeof(struct ethhdr))
340 return -EINVAL;
341 if (count > 1514) {
342 printk("sheep_net_write: packet size > 1514\n");
343 count = 1514;
344 }
345
346 /* Interface active? */
347 if (v->ether == NULL)
348 return count;
349
350 /* Allocate buffer for packet */
351 skb = dev_alloc_skb(count);
352 if (skb == NULL)
353 return -ENOBUFS;
354
355 /* Stuff packet in buffer */
356 p = skb_put(skb, count);
357 if (copy_from_user(p, buf, count)) {
358 kfree_skb(skb);
359 return -EFAULT;
360 }
361
362 /* Transmit packet */
363 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 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 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 /* Packets in queue? Then return */
414 if (!skb_queue_empty(&v->queue))
415 return POLLIN | POLLRDNORM;
416
417 /* Otherwise wait for packet */
418 poll_wait(f, &v->wait, wait);
419 if (!skb_queue_empty(&v->queue))
420 return POLLIN | POLLRDNORM;
421 else
422 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 /* Attach to Ethernet card
438 arg: pointer to name of Ethernet device (char[20]) */
439 case SIOCSIFLINK: {
440 char name[20];
441 int err;
442
443 /* Already attached? */
444 if (v->ether)
445 return -EBUSY;
446
447 /* Get Ethernet card name */
448 if (copy_from_user(name, (void *)arg, 20))
449 return -EFAULT;
450 name[19] = 0;
451
452 /* Find card */
453 #ifdef LINUX_24
454 v->ether = dev_get_by_name(name);
455 #else
456 dev_lock_list();
457 v->ether = dev_get(name);
458 #endif
459 if (v->ether == NULL) {
460 err = -ENODEV;
461 goto error;
462 }
463
464 /* Is it Ethernet? */
465 if (v->ether->type != ARPHRD_ETHER) {
466 err = -EINVAL;
467 goto error;
468 }
469
470 /* Remember the card's hardware address */
471 memcpy(v->eth_addr, v->ether->dev_addr, 6);
472
473 /* Allocate socket */
474 v->skt = sk_alloc(0, GFP_USER, 1);
475 if (v->skt == NULL) {
476 err = -ENOMEM;
477 goto error;
478 }
479 v->skt->dead = 1;
480
481 /* Attach packet handler */
482 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 #ifndef LINUX_24
488 dev_unlock_list();
489 #endif
490 return 0;
491
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 }
502
503 /* Get hardware address of the sheep_net module
504 arg: pointer to buffer (6 bytes) to store address */
505 case SIOCGIFADDR:
506 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 return -EFAULT;
515 return 0;
516
517 /* Add multicast address
518 arg: pointer to address (6 bytes) */
519 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 /* Remove multicast address
529 arg: pointer to address (6 bytes) */
530 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 /* Return size of first packet in queue */
540 case FIONREAD: {
541 int count = 0;
542 struct sk_buff *skb;
543 #ifdef LINUX_24
544 long flags;
545 spin_lock_irqsave(&v->queue.lock, flags);
546 #else
547 cli();
548 #endif
549 skb = skb_peek(&v->queue);
550 if (skb)
551 count = skb->len;
552 #ifdef LINUX_24
553 spin_unlock_irqrestore(&v->queue.lock, flags);
554 #else
555 sti();
556 #endif
557 return put_user(count, (int *)arg);
558 }
559
560 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 default:
568 return -ENOIOCTLCMD;
569 }
570 }
571
572
573 /*
574 * Packet receiver function
575 */
576
577 static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
578 {
579 struct SheepVars *v = (struct SheepVars *)pt->data;
580 struct sk_buff *skb2;
581 int fake;
582 int multicast;
583 D(bug("sheep_net: packet received\n"));
584
585 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 }
606
607 /* 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
615 /* We also want the Ethernet header */
616 skb_push(skb, skb->data - skb->mac.raw);
617
618 /* Enqueue packet */
619 skb_queue_tail(&v->queue, skb);
620
621 /* Unblock blocked read */
622 wake_up(&v->wait);
623 return 0;
624
625 drop:
626 kfree_skb(skb);
627 return 0;
628 }