ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Unix/Linux/NetDriver/sheep_net.c
Revision: 1.6
Committed: 2001-07-14T15:02:48Z (23 years ago) by cebix
Content type: text/plain
Branch: MAIN
Changes since 1.5: +8 -5 lines
Log Message:
- 1-bit mode under X11 always uses default visual
- fixed possible crash in driver_window dtor (image data would be freed twice,
  once by XDestroyImage() and once in driver_base dtor)
- fixed compilation problems with banked memory
- fixed typos

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