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 memset(dev->priv, 0, sizeof(struct enet_statistics));
83 #ifdef MODULE
84 dev->open = &tunnel_open;
85 dev->stop = &tunnel_close;
86 #endif
87 dev->type = ARPHRD_TUNNEL;
88 dev->flags |= IFF_NOARP;
89 dev->flags |= IFF_LOOPBACK;
90 dev->addr_len=0;
91 dev->hard_header_len=0;
92 dev->hard_header=NULL;
93 return 0;
94 }
95
96 #ifdef TUNNEL_DEBUG
97 void print_ip(struct iphdr *ip)
98 {
99 unsigned char *ipaddr;
100
101 printk("IP packet:\n");
102 printk("--- header len = %d\n", ip->ihl*4);
103 printk("--- ip version: %d\n", ip->version);
104 printk("--- ip protocol: %d\n", ip->protocol);
105 ipaddr=(unsigned char *)&ip->saddr;
106 printk("--- source address: %u.%u.%u.%u\n",
107 *ipaddr, *(ipaddr+1), *(ipaddr+2), *(ipaddr+3));
108 ipaddr=(unsigned char *)&ip->daddr;
109 printk("--- destination address: %u.%u.%u.%u\n",
110 *ipaddr, *(ipaddr+1), *(ipaddr+2), *(ipaddr+3));
111 printk("--- total packet len: %d\n", ntohs(ip->tot_len));
112 }
113 #endif
114
115
116
117
118
119
120
121 static int tunnel_xmit(struct sk_buff *skb, struct device *dev)
122 {
123 struct enet_statistics *stats;
124 struct sk_buff *skb2;
125 int newlen;
126 struct iphdr *iph;
127
128
129
130
131
132 if (skb == NULL || dev == NULL)
133 return 0;
134
135
136
137
138
139 stats = (struct enet_statistics *)dev->priv;
140 cli();
141 if (dev->tbusy != 0)
142 {
143 sti();
144 stats->tx_errors++;
145 return(1);
146 }
147 dev->tbusy = 1;
148 sti();
149
150
151
152
153
154 if ( ! dev->pa_dstaddr )
155 {
156 printk("%s: packet sent through tunnel to never-never land!\n", dev->name);
157 dev_kfree_skb(skb, FREE_WRITE);
158 dev->tbusy = 0;
159 return(1);
160 }
161
162 iph=(struct iphdr *)skb->data;
163 if ( iph->version != 4 )
164 {
165
166
167
168 printk("%s: Bad IP packet: ip version %d\n", dev->name, iph->version);
169 dev_kfree_skb(skb, FREE_WRITE);
170 dev->tbusy = 0;
171 return(0);
172 }
173
174
175
176
177
178
179 if ( iph->protocol == IPPROTO_IPIP && iph->saddr == dev->pa_addr )
180 {
181
182
183
184 printk("%s: Warning: IP routing loop!\n", dev->name);
185 dev->tbusy = 0;
186 dev_kfree_skb(skb, FREE_WRITE);
187 return(0);
188 }
189
190 if ( iph->daddr == dev->pa_addr )
191 {
192 printk("%s: Received inbound packet -- not handled.\n",dev->name);
193 dev_kfree_skb(skb, FREE_WRITE);
194 dev->tbusy = 0;
195 return(0);
196 }
197
198 #ifdef TUNNEL_DEBUG
199 printk("Old IP Header....\n");
200 print_ip(iph);
201 #endif
202
203
204
205
206
207 newlen = (skb->len + ip_header_len);
208 if ( !(skb2 = dev_alloc_skb(newlen)) )
209 {
210 printk("%s: No free memory.\n",dev->name);
211 dev_kfree_skb(skb, FREE_WRITE);
212 dev->tbusy = 0;
213 stats->tx_dropped++;
214 return(1);
215 }
216
217
218 skb2->free=1;
219 skb_put(skb2,newlen);
220 iph=skb2->h.iph=(struct iphdr *)skb2->data;
221 memcpy(skb2->h.iph, skb->data, ip_header_len );
222 memcpy(skb2->data + ip_header_len, skb->data, skb->len);
223
224 dev_kfree_skb(skb, FREE_WRITE);
225
226
227 ++iph->ttl;
228 iph->saddr = dev->pa_addr;
229 iph->daddr = dev->pa_dstaddr;
230 iph->protocol = IPPROTO_IPIP;
231 iph->ihl = 5;
232 iph->tot_len = htons(skb2->len);
233 iph->frag_off = 0;
234
235
236
237 iph->check = 0;
238 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
239
240 #ifdef TUNNEL_DEBUG
241 printk("New IP Header....\n");
242 print_ip(iph);
243 #endif
244
245 #ifdef TUNNEL_DEBUG
246 printk("tunnel: calling ip_forward()\n");
247 #endif
248 if(ip_forward(skb2, dev, 0, iph->daddr, 0))
249 kfree_skb(skb2, FREE_WRITE);
250
251
252 #ifdef TUNNEL_DEBUG
253 printk("Packet sent through tunnel interface!\n");
254 #endif
255
256 stats->tx_packets++;
257
258 #ifdef TUNNEL_DEBUG
259 printk("tunnel: Updated usage statistics.\n");
260 #endif
261 dev->tbusy=0;
262 return 0;
263 }
264
265 static struct enet_statistics *
266 tunnel_get_stats(struct device *dev)
267 {
268 return((struct enet_statistics*) dev->priv);
269 }
270
271 #ifdef MODULE
272 char kernel_version[] = UTS_RELEASE;
273
274 static int tunnel_probe(struct device *dev)
275 {
276 tunnel_init(dev);
277 return 0;
278 }
279
280 static struct device dev_tunnel = {
281 "tunl0\0 ",
282 0, 0, 0, 0,
283 0x0, 0,
284 0, 0, 0, NULL, tunnel_probe };
285
286 int init_module(void)
287 {
288
289 int ct= 1;
290
291 while(dev_get(dev_tunnel.name)!=NULL && ct<100)
292 {
293 sprintf(dev_tunnel.name,"tunl%d",ct);
294 ct++;
295 }
296
297 #ifdef TUNNEL_DEBUG
298 printk("tunnel: registering device %s\n", dev_tunnel.name);
299 #endif
300 if (register_netdev(&dev_tunnel) != 0)
301 return -EIO;
302 return 0;
303 }
304
305 void cleanup_module(void)
306 {
307 unregister_netdev(&dev_tunnel);
308 kfree_s(dev_tunnel.priv,sizeof(struct enet_statistics));
309 dev_tunnel.priv=NULL;
310 }
311 #endif
312 #endif