This source file includes following definitions.
- ip_encap
- ip_forward
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include <linux/config.h>
16 #include <linux/types.h>
17 #include <linux/mm.h>
18 #include <linux/sched.h>
19 #include <linux/skbuff.h>
20 #include <linux/ip.h>
21 #include <linux/icmp.h>
22 #include <linux/netdevice.h>
23 #include <net/sock.h>
24 #include <net/ip.h>
25 #include <net/icmp.h>
26 #include <linux/tcp.h>
27 #include <linux/udp.h>
28 #include <linux/firewall.h>
29 #include <linux/ip_fw.h>
30 #include <net/checksum.h>
31 #include <linux/route.h>
32 #include <net/route.h>
33
34 #ifdef CONFIG_IP_FORWARD
35 #ifdef CONFIG_IP_MROUTE
36
37
38
39
40
41
42
43 static void ip_encap(struct sk_buff *skb, int len, struct device *out, __u32 daddr)
44 {
45
46
47
48
49
50 struct iphdr *iph=(struct iphdr *)skb_push(skb,sizeof(struct iphdr));
51 if(len>65515)
52 len=65515;
53 iph->version = 4;
54 iph->tos = skb->ip_hdr->tos;
55 iph->ttl = skb->ip_hdr->ttl;
56 iph->frag_off = 0;
57 iph->daddr = daddr;
58 iph->saddr = out->pa_addr;
59 iph->protocol = IPPROTO_IPIP;
60 iph->ihl = 5;
61 iph->tot_len = htons(skb->len);
62 iph->id = htons(ip_id_count++);
63 ip_send_check(iph);
64
65 skb->dev = out;
66 skb->arp = 1;
67 skb->raddr=daddr;
68
69
70
71 if (out->hard_header && out->hard_header(skb, out, ETH_P_IP, NULL, NULL, len)<0)
72 skb->arp=0;
73
74
75
76 }
77
78 #endif
79
80
81
82
83
84 int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag,
85 __u32 target_addr)
86 {
87 struct device *dev2;
88 struct iphdr *iph;
89 struct sk_buff *skb2;
90 struct rtable *rt;
91 unsigned char *ptr;
92 unsigned long raddr;
93 struct options * opt = (struct options*)skb->proto_priv;
94 struct hh_cache *hh = NULL;
95 int encap = 0;
96 #ifdef CONFIG_FIREWALL
97 int fw_res = 0;
98 #ifdef CONFIG_IP_MASQUERADE
99 struct sk_buff *skb_in = skb;
100 #endif
101
102
103
104
105
106
107
108 if(!(is_frag&IPFWD_MASQUERADED))
109 {
110 fw_res=call_fw_firewall(PF_INET, skb, skb->h.iph);
111 switch (fw_res) {
112 case FW_ACCEPT:
113 case FW_MASQUERADE:
114 break;
115 case FW_REJECT:
116 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev);
117
118 default:
119 return -1;
120 }
121 }
122 #endif
123
124
125
126
127
128
129
130
131
132
133
134 iph = skb->h.iph;
135 iph->ttl--;
136
137
138
139
140
141
142
143 iph->check = ntohs(iph->check) + 0x0100;
144 if ((iph->check & 0xFF00) == 0)
145 iph->check++;
146 iph->check = htons(iph->check);
147
148 if (iph->ttl <= 0)
149 {
150
151 icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, dev);
152 return -1;
153 }
154
155 #ifdef CONFIG_IP_MROUTE
156 if(!(is_frag&IPFWD_MULTICASTING))
157 {
158 #endif
159
160
161
162
163
164 rt = ip_rt_route(target_addr, 0);
165
166 if (rt == NULL)
167 {
168
169
170
171
172 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);
173 return -1;
174 }
175
176
177
178
179
180
181
182
183
184
185 raddr = rt->rt_gateway;
186
187 if (opt->is_strictroute && (rt->rt_flags & RTF_GATEWAY)) {
188
189
190
191
192 ip_rt_put(rt);
193 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0, dev);
194 return -1;
195 }
196
197
198
199
200
201 dev2 = rt->rt_dev;
202 hh = rt->rt_hh;
203
204
205
206
207
208 #ifndef CONFIG_IP_NO_ICMP_REDIRECT
209 if (dev == dev2 && !((iph->saddr^iph->daddr)&dev->pa_mask) &&
210 (rt->rt_flags&RTF_MODIFIED) && !opt->srr)
211 icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
212 #endif
213 #ifdef CONFIG_IP_MROUTE
214 }
215 else
216 {
217
218
219
220 dev2=skb->dev;
221 raddr=skb->raddr;
222 if(is_frag&IPFWD_MULTITUNNEL)
223 encap=20;
224 rt=NULL;
225 }
226 #endif
227
228
229
230
231
232
233
234 if (dev2->flags & IFF_UP)
235 {
236 #ifdef CONFIG_IP_MASQUERADE
237
238
239
240
241 if (!(is_frag&IPFWD_MASQUERADED) && fw_res==FW_MASQUERADE)
242 ip_fw_masquerade(&skb, dev2);
243 #endif
244 IS_SKB(skb);
245
246 if (skb->len+encap > dev2->mtu && (ntohs(iph->frag_off) & IP_DF))
247 {
248 ip_statistics.IpFragFails++;
249 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(dev2->mtu), dev);
250 if(rt)
251 ip_rt_put(rt);
252 return -1;
253 }
254
255 #ifdef CONFIG_IP_MROUTE
256 if(skb_headroom(skb)-encap<dev2->hard_header_len)
257 {
258 skb2 = alloc_skb(dev2->hard_header_len + skb->len + encap + 15, GFP_ATOMIC);
259 #else
260 if(skb_headroom(skb)<dev2->hard_header_len)
261 {
262 skb2 = alloc_skb(dev2->hard_header_len + skb->len + 15, GFP_ATOMIC);
263 #endif
264
265
266
267
268
269 if (skb2 == NULL)
270 {
271 NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
272 if(rt)
273 ip_rt_put(rt);
274 return -1;
275 }
276
277 IS_SKB(skb2);
278
279
280
281 skb2->protocol=htons(ETH_P_IP);
282 #ifdef CONFIG_IP_MROUTE
283 if(is_frag&IPFWD_MULTITUNNEL)
284 {
285 skb_reserve(skb,(encap+dev->hard_header_len+15)&~15);
286 ip_encap(skb2,skb->len, dev2, raddr);
287 }
288 else
289 #endif
290 ip_send(rt,skb2,raddr,skb->len,dev2,dev2->pa_addr);
291
292
293
294
295
296
297 ptr = skb_put(skb2,skb->len);
298 skb2->free = 1;
299 skb2->h.raw = ptr;
300
301
302
303
304 memcpy(ptr, skb->h.raw, skb->len);
305 memcpy(skb2->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
306 iph = skb2->ip_hdr = skb2->h.iph;
307 }
308 else
309 {
310
311
312
313
314 skb2 = skb;
315 skb2->dev=dev2;
316 #ifdef CONFIG_IP_MROUTE
317 if(is_frag&IPFWD_MULTITUNNEL)
318 ip_encap(skb,skb->len, dev2, raddr);
319 else
320 {
321 #endif
322 skb->arp=1;
323 skb->raddr=raddr;
324 if (hh)
325 {
326 memcpy(skb_push(skb, dev2->hard_header_len), hh->hh_data, dev2->hard_header_len);
327 if (!hh->hh_uptodate)
328 {
329 #if RT_CACHE_DEBUG >= 2
330 printk("ip_forward: hh miss %08x via %08x\n", target_addr, rt->rt_gateway);
331 #endif
332 skb->arp = 0;
333 }
334 }
335 else if (dev2->hard_header)
336 {
337 if(dev2->hard_header(skb, dev2, ETH_P_IP, NULL, NULL, skb->len)<0)
338 skb->arp=0;
339 }
340 #ifdef CONFIG_IP_MROUTE
341 }
342 #endif
343 ip_statistics.IpForwDatagrams++;
344 }
345
346 if (opt->optlen)
347 {
348 unsigned char * optptr;
349 if (opt->rr_needaddr)
350 {
351 optptr = (unsigned char *)iph + opt->rr;
352 memcpy(&optptr[optptr[2]-5], &dev2->pa_addr, 4);
353 opt->is_changed = 1;
354 }
355 if (opt->srr_is_hit)
356 {
357 int srrptr, srrspace;
358
359 optptr = (unsigned char *)iph + opt->srr;
360
361 for ( srrptr=optptr[2], srrspace = optptr[1];
362 srrptr <= srrspace;
363 srrptr += 4
364 )
365 {
366 if (srrptr + 3 > srrspace)
367 break;
368 if (memcmp(&target_addr, &optptr[srrptr-1], 4) == 0)
369 break;
370 }
371 if (srrptr + 3 <= srrspace)
372 {
373 opt->is_changed = 1;
374 memcpy(&optptr[srrptr-1], &dev2->pa_addr, 4);
375 iph->daddr = target_addr;
376 optptr[2] = srrptr+4;
377 }
378 else
379 printk("ip_forward(): Argh! Destination lost!\n");
380 }
381 if (opt->ts_needaddr)
382 {
383 optptr = (unsigned char *)iph + opt->ts;
384 memcpy(&optptr[optptr[2]-9], &dev2->pa_addr, 4);
385 opt->is_changed = 1;
386 }
387 if (opt->is_changed)
388 {
389 opt->is_changed = 0;
390 ip_send_check(iph);
391 }
392 }
393
394
395
396
397
398
399
400
401
402
403
404 if(skb2->len > dev2->mtu + dev2->hard_header_len)
405 {
406 ip_fragment(NULL,skb2,dev2, is_frag);
407 kfree_skb(skb2,FREE_WRITE);
408 }
409 else
410 {
411 #ifdef CONFIG_IP_ACCT
412
413
414
415
416 ip_fw_chk(iph,dev,ip_acct_chain,IP_FW_F_ACCEPT,1);
417 #endif
418
419
420
421
422
423
424 if(iph->tos & IPTOS_LOWDELAY)
425 dev_queue_xmit(skb2, dev2, SOPRI_INTERACTIVE);
426 else if(iph->tos & IPTOS_THROUGHPUT)
427 dev_queue_xmit(skb2, dev2, SOPRI_BACKGROUND);
428 else
429 dev_queue_xmit(skb2, dev2, SOPRI_NORMAL);
430 }
431 }
432 else
433 {
434 if(rt)
435 ip_rt_put(rt);
436 return -1;
437 }
438 if(rt)
439 ip_rt_put(rt);
440
441
442
443
444
445 if(skb==skb2)
446 return 0;
447
448 #ifdef CONFIG_IP_MASQUERADE
449
450
451
452
453 if(skb!=skb_in)
454 {
455 kfree_skb(skb_in, FREE_WRITE);
456 return 0;
457 }
458 #endif
459 return 1;
460 }
461
462
463 #endif