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