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> |
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 |
66 |
|
#define init_waitqueue_head(x) *(x)=NULL |
67 |
|
#endif |
68 |
|
|
69 |
+ |
#ifdef LINUX_26 |
70 |
+ |
#define compat_sk_alloc(a,b,c) sk_alloc( (a), (b), (c), NULL ) |
71 |
+ |
#define skt_set_dead(skt) do {} while(0) |
72 |
+ |
#define wmem_alloc sk_wmem_alloc |
73 |
+ |
#else |
74 |
+ |
#define compat_sk_alloc sk_alloc |
75 |
+ |
#define skt_set_dead(skt) (skt)->dead = 1 |
76 |
+ |
#endif |
77 |
+ |
|
78 |
|
#define DEBUG 0 |
79 |
|
|
80 |
|
#define bug printk |
111 |
|
*/ |
112 |
|
|
113 |
|
struct SheepVars { |
114 |
+ |
/* IMPORTANT: the packet_type struct must go first. It no longer |
115 |
+ |
(2.6) contains * a data field so we typecast to get the SheepVars |
116 |
+ |
struct */ |
117 |
+ |
struct packet_type pt; /* Receiver packet type */ |
118 |
|
struct net_device *ether; /* The Ethernet device we're attached to */ |
119 |
|
struct sock *skt; /* Socket for communication with Ethernet card */ |
120 |
|
struct sk_buff_head queue; /* Receiver packet queue */ |
104 |
– |
struct packet_type pt; /* Receiver packet type */ |
121 |
|
wait_queue_head_t wait; /* Wait queue for blocking read operations */ |
122 |
|
u32 ipfilter; /* Only receive IP packets destined for this address (host byte order) */ |
123 |
|
char eth_addr[6]; /* Hardware address of the Ethernet card */ |
131 |
|
*/ |
132 |
|
|
133 |
|
static struct file_operations sheep_net_fops = { |
134 |
< |
read: sheep_net_read, |
135 |
< |
write: sheep_net_write, |
136 |
< |
poll: sheep_net_poll, |
137 |
< |
ioctl: sheep_net_ioctl, |
138 |
< |
open: sheep_net_open, |
139 |
< |
release: sheep_net_release, |
134 |
> |
.owner = THIS_MODULE, |
135 |
> |
.read = sheep_net_read, |
136 |
> |
.write = sheep_net_write, |
137 |
> |
.poll = sheep_net_poll, |
138 |
> |
.ioctl = sheep_net_ioctl, |
139 |
> |
.open = sheep_net_open, |
140 |
> |
.release = sheep_net_release, |
141 |
|
}; |
142 |
|
|
143 |
|
|
146 |
|
*/ |
147 |
|
|
148 |
|
static struct miscdevice sheep_net_device = { |
149 |
< |
SHEEP_NET_MINOR, /* minor number */ |
150 |
< |
"sheep_net", /* name */ |
151 |
< |
&sheep_net_fops, |
135 |
< |
NULL, |
136 |
< |
NULL |
149 |
> |
.minor = SHEEP_NET_MINOR, /* minor number */ |
150 |
> |
.name = "sheep_net", /* name */ |
151 |
> |
.fops = &sheep_net_fops |
152 |
|
}; |
153 |
|
|
154 |
|
|
171 |
|
* Deinitialize module |
172 |
|
*/ |
173 |
|
|
174 |
< |
int cleanup_module(void) |
174 |
> |
void cleanup_module(void) |
175 |
|
{ |
161 |
– |
int ret; |
162 |
– |
|
176 |
|
/* Unregister driver */ |
177 |
< |
ret = misc_deregister(&sheep_net_device); |
177 |
> |
misc_deregister(&sheep_net_device); |
178 |
|
D(bug("Sheep net driver removed\n")); |
166 |
– |
return ret; |
179 |
|
} |
180 |
|
|
181 |
|
|
193 |
|
return -EPERM; |
194 |
|
|
195 |
|
/* Allocate private variables */ |
196 |
< |
v = (struct SheepVars *)f->private_data = kmalloc(sizeof(struct SheepVars), GFP_USER); |
196 |
> |
v = (struct SheepVars *)(f->private_data = kmalloc(sizeof(struct SheepVars), GFP_USER)); |
197 |
|
if (v == NULL) |
198 |
|
return -ENOMEM; |
199 |
|
memset(v, 0, sizeof(struct SheepVars)); |
207 |
|
v->fake_addr[5] = 0xef; |
208 |
|
|
209 |
|
/* Yes, we're open */ |
210 |
+ |
#ifndef LINUX_26 |
211 |
|
MOD_INC_USE_COUNT; |
212 |
+ |
#endif |
213 |
|
return 0; |
214 |
|
} |
215 |
|
|
243 |
|
kfree(v); |
244 |
|
|
245 |
|
/* Sorry, we're closed */ |
246 |
+ |
#ifndef LINUX_26 |
247 |
|
MOD_DEC_USE_COUNT; |
248 |
+ |
#endif |
249 |
|
return 0; |
250 |
|
} |
251 |
|
|
501 |
|
memcpy(v->eth_addr, v->ether->dev_addr, 6); |
502 |
|
|
503 |
|
/* Allocate socket */ |
504 |
< |
v->skt = sk_alloc(0, GFP_USER, 1); |
504 |
> |
v->skt = compat_sk_alloc(0, GFP_USER, 1); |
505 |
|
if (v->skt == NULL) { |
506 |
|
err = -ENOMEM; |
507 |
|
goto error; |
508 |
|
} |
509 |
< |
v->skt->dead = 1; |
509 |
> |
skt_set_dead(v->skt->dead); |
510 |
|
|
511 |
|
/* Attach packet handler */ |
512 |
|
v->pt.type = htons(ETH_P_ALL); |
513 |
|
v->pt.dev = v->ether; |
514 |
|
v->pt.func = sheep_net_receiver; |
499 |
– |
v->pt.data = v; |
515 |
|
dev_add_pack(&v->pt); |
516 |
|
#ifndef LINUX_24 |
517 |
|
dev_unlock_list(); |
570 |
|
int count = 0; |
571 |
|
struct sk_buff *skb; |
572 |
|
#ifdef LINUX_24 |
573 |
< |
long flags; |
573 |
> |
unsigned long flags; |
574 |
|
spin_lock_irqsave(&v->queue.lock, flags); |
575 |
|
#else |
576 |
|
cli(); |
605 |
|
|
606 |
|
static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) |
607 |
|
{ |
608 |
< |
struct SheepVars *v = (struct SheepVars *)pt->data; |
608 |
> |
struct SheepVars *v = (struct SheepVars *)pt; |
609 |
|
struct sk_buff *skb2; |
610 |
|
int fake; |
611 |
|
int multicast; |