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