This source file includes following definitions.
- tunnel_open
- tunnel_close
- tunnel_init
- print_ip
- tunnel_xmit
- tunnel_get_stats
- tunnel_probe
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <linux/module.h>
22
23 #include <linux/kernel.h>
24 #include <linux/sched.h>
25 #include <linux/types.h>
26 #include <netinet/in.h>
27 #include <linux/ip.h>
28 #include <linux/string.h>
29 #include <asm/system.h>
30 #include <linux/errno.h>
31
32 #include <linux/netdevice.h>
33 #include <linux/etherdevice.h>
34 #include <linux/if_arp.h>
35 #include <linux/skbuff.h>
36 #include <net/ip.h>
37
38 #include <net/checksum.h>
39
40 #define ip_header_len sizeof(struct iphdr)
41
42 static int tunnel_xmit(struct sk_buff *skb, struct device *dev);
43 static struct enet_statistics *tunnel_get_stats(struct device *dev);
44
45 #ifdef MODULE
46 static int tunnel_open(struct device *dev)
47 {
48 MOD_INC_USE_COUNT;
49 return 0;
50 }
51
52 static int tunnel_close(struct device *dev)
53 {
54 MOD_DEC_USE_COUNT;
55 return 0;
56 }
57
58 #endif
59
60
61 int tunnel_init(struct device *dev)
62 {
63 static int tun_msg=0;
64 if(!tun_msg)
65 {
66 printk ( KERN_INFO "tunnel: version v0.1a\n" );
67 tun_msg=1;
68 }
69
70
71 ether_setup(dev);
72
73
74 dev->hard_start_xmit = tunnel_xmit;
75 dev->get_stats = tunnel_get_stats;
76 dev->priv = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
77 if (dev->priv == NULL)
78 return -ENOMEM;
79 memset(dev->priv, 0, sizeof(struct enet_statistics));
80 #ifdef MODULE
81 dev->open = &tunnel_open;
82 dev->stop = &tunnel_close;
83 #endif
84
85 dev->type = ARPHRD_TUNNEL;
86 dev->flags |= IFF_NOARP;
87 dev->flags |= IFF_LOOPBACK;
88 dev->addr_len=0;
89 dev->hard_header_len=0;
90 dev->hard_header=NULL;
91 dev->header_cache_bind=NULL;
92 dev->rebuild_header=NULL;
93
94 return 0;
95 }
96
97 #ifdef TUNNEL_DEBUG
98 void print_ip(struct iphdr *ip)
99 {
100 unsigned char *ipaddr;
101
102 printk("IP packet:\n");
103 printk("--- header len = %d\n", ip->ihl*4);
104 printk("--- ip version: %d\n", ip->version);
105 printk("--- ip protocol: %d\n", ip->protocol);
106 ipaddr=(unsigned char *)&ip->saddr;
107 printk("--- source address: %u.%u.%u.%u\n",
108 *ipaddr, *(ipaddr+1), *(ipaddr+2), *(ipaddr+3));
109 ipaddr=(unsigned char *)&ip->daddr;
110 printk("--- destination address: %u.%u.%u.%u\n",
111 *ipaddr, *(ipaddr+1), *(ipaddr+2), *(ipaddr+3));
112 printk("--- total packet len: %d\n", ntohs(ip->tot_len));
113 }
114 #endif
115
116
117
118
119
120
121
122 static int tunnel_xmit(struct sk_buff *skb, struct device *dev)
123 {
124 struct enet_statistics *stats;
125 struct sk_buff *skb2;
126 int newlen;
127 struct iphdr *iph;
128
129
130
131
132
133 if (skb == NULL || dev == NULL)
134 return 0;
135
136
137
138
139
140 stats = (struct enet_statistics *)dev->priv;
141 cli();
142 if (dev->tbusy != 0)
143 {
144 sti();
145 stats->tx_errors++;
146 return(1);
147 }
148 dev->tbusy = 1;
149 sti();
150
151
152
153
154
155 if ( ! dev->pa_dstaddr )
156 {
157 printk("%s: packet sent through tunnel to never-never land!\n", dev->name);
158 dev_kfree_skb(skb, FREE_WRITE);
159 dev->tbusy = 0;
160 return(1);
161 }
162
163 iph=(struct iphdr *)skb->data;
164 if ( iph->version != 4 )
165 {
166
167
168
169 printk("%s: Bad IP packet: ip version %d\n", dev->name, iph->version);
170 dev_kfree_skb(skb, FREE_WRITE);
171 dev->tbusy = 0;
172 return(0);
173 }
174
175
176
177
178
179
180 if ( iph->protocol == IPPROTO_IPIP && iph->saddr == dev->pa_addr )
181 {
182
183
184
185 printk("%s: Warning: IP routing loop!\n", dev->name);
186 dev->tbusy = 0;
187 dev_kfree_skb(skb, FREE_WRITE);
188 return(0);
189 }
190
191 if ( iph->daddr == dev->pa_addr )
192 {
193 printk("%s: Received inbound packet -- not handled.\n",dev->name);
194 dev_kfree_skb(skb, FREE_WRITE);
195 dev->tbusy = 0;
196 return(0);
197 }
198
199 #ifdef TUNNEL_DEBUG
200 printk("Old IP Header....\n");
201 print_ip(iph);
202 #endif
203
204
205
206
207
208 newlen = (skb->len + ip_header_len);
209 if ( !(skb2 = dev_alloc_skb(newlen)) )
210 {
211 printk("%s: No free memory.\n",dev->name);
212 dev_kfree_skb(skb, FREE_WRITE);
213 dev->tbusy = 0;
214 stats->tx_dropped++;
215 return(1);
216 }
217
218
219 skb2->free=1;
220 skb_put(skb2,newlen);
221 iph=skb2->h.iph=(struct iphdr *)skb2->data;
222 skb2->ip_hdr=iph;
223 memcpy(skb2->h.iph, skb->data, ip_header_len );
224 memcpy(skb2->data + ip_header_len, skb->data, skb->len);
225
226 dev_kfree_skb(skb, FREE_WRITE);
227
228
229 ++iph->ttl;
230 iph->saddr = dev->pa_addr;
231 iph->daddr = dev->pa_dstaddr;
232 iph->protocol = IPPROTO_IPIP;
233 iph->ihl = 5;
234 iph->tot_len = htons(skb2->len);
235 iph->frag_off = 0;
236
237
238
239 iph->check = 0;
240 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
241
242 #ifdef TUNNEL_DEBUG
243 printk("New IP Header....\n");
244 print_ip(iph);
245 #endif
246
247 #ifdef TUNNEL_DEBUG
248 printk("tunnel: calling ip_forward()\n");
249 #endif
250 if(ip_forward(skb2, dev, 0, iph->daddr))
251 kfree_skb(skb2, FREE_WRITE);
252
253
254 #ifdef TUNNEL_DEBUG
255 printk("Packet sent through tunnel interface!\n");
256 #endif
257
258 stats->tx_packets++;
259
260 #ifdef TUNNEL_DEBUG
261 printk("tunnel: Updated usage statistics.\n");
262 #endif
263 dev->tbusy=0;
264 return 0;
265 }
266
267 static struct enet_statistics *
268 tunnel_get_stats(struct device *dev)
269 {
270 return((struct enet_statistics*) dev->priv);
271 }
272
273 #ifdef MODULE
274
275 static int tunnel_probe(struct device *dev)
276 {
277 tunnel_init(dev);
278 return 0;
279 }
280
281 static struct device dev_tunnel = {
282 "tunl0\0 ",
283 0, 0, 0, 0,
284 0x0, 0,
285 0, 0, 0, NULL, tunnel_probe };
286
287 int init_module(void)
288 {
289
290 int ct= 1;
291
292 while(dev_get(dev_tunnel.name)!=NULL && ct<100)
293 {
294 sprintf(dev_tunnel.name,"tunl%d",ct);
295 ct++;
296 }
297
298 #ifdef TUNNEL_DEBUG
299 printk("tunnel: registering device %s\n", dev_tunnel.name);
300 #endif
301 if (register_netdev(&dev_tunnel) != 0)
302 return -EIO;
303 return 0;
304 }
305
306 void cleanup_module(void)
307 {
308 unregister_netdev(&dev_tunnel);
309 kfree_s(dev_tunnel.priv,sizeof(struct enet_statistics));
310 dev_tunnel.priv=NULL;
311 }
312 #endif