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