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