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 int encap = 0;
94 #ifdef CONFIG_FIREWALL
95 int fw_res = 0;
96 #ifdef CONFIG_IP_MASQUERADE
97 struct sk_buff *skb_in = skb;
98 #endif
99
100
101
102
103
104
105
106 if(!(is_frag&4))
107 {
108 fw_res=call_fw_firewall(PF_INET, skb, skb->h.iph);
109 switch (fw_res) {
110 case FW_ACCEPT:
111 case FW_MASQUERADE:
112 break;
113 case FW_REJECT:
114 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev);
115
116 default:
117 return -1;
118 }
119 }
120 #endif
121
122
123
124
125
126
127
128
129
130
131
132 iph = skb->h.iph;
133 iph->ttl--;
134
135
136
137
138
139
140
141 iph->check = ntohs(iph->check) + 0x0100;
142 if ((iph->check & 0xFF00) == 0)
143 iph->check++;
144 iph->check = htons(iph->check);
145
146 if (iph->ttl <= 0)
147 {
148
149 icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, dev);
150 return -1;
151 }
152
153 #ifdef CONFIG_IP_MROUTE
154 if(!(is_frag&8))
155 {
156 #endif
157
158
159
160
161
162 rt = ip_rt_route(target_addr, NULL, NULL);
163 if (rt == NULL)
164 {
165
166
167
168
169 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);
170 return -1;
171 }
172
173
174
175
176
177
178
179
180
181
182 raddr = rt->rt_gateway;
183
184 if (raddr != 0)
185 {
186
187
188
189
190 if (opt->is_strictroute)
191 {
192 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0, dev);
193 return -1;
194 }
195
196
197
198
199
200 }
201 else
202 raddr = target_addr;
203
204
205
206
207
208 dev2 = rt->rt_dev;
209
210
211
212
213
214 #ifndef CONFIG_IP_NO_ICMP_REDIRECT
215 if (dev == dev2 && !((iph->saddr^iph->daddr)&dev->pa_mask) &&
216 (rt->rt_flags&RTF_MODIFIED) && !opt->srr)
217 icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
218 #endif
219 #ifdef CONFIG_IP_MROUTE
220 }
221 else
222 {
223
224
225
226 dev2=skb->dev;
227 raddr=skb->raddr;
228 if(is_frag&16)
229 encap=20;
230 }
231 #endif
232
233
234
235
236
237
238
239 if (dev2->flags & IFF_UP)
240 {
241 #ifdef CONFIG_IP_MASQUERADE
242
243
244
245
246 if (!(is_frag&4) && fw_res==FW_MASQUERADE)
247 ip_fw_masquerade(&skb, dev2);
248 #endif
249 IS_SKB(skb);
250
251 if (skb->len+encap > dev2->mtu && (ntohs(iph->frag_off) & IP_DF)) {
252 ip_statistics.IpFragFails++;
253 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, dev2->mtu, dev);
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 return -1;
275 }
276
277 IS_SKB(skb2);
278
279
280
281 #ifdef CONFIG_IP_MROUTE
282 if(is_frag&16)
283 {
284 skb_reserve(skb,(encap+dev->hard_header_len+15)&~15);
285 ip_encap(skb2,skb->len, dev2, raddr);
286 }
287 else
288 #endif
289 ip_send(skb2,raddr,skb->len,dev2,dev2->pa_addr);
290
291
292
293
294
295
296 ptr = skb_put(skb2,skb->len);
297 skb2->free = 1;
298 skb2->h.raw = ptr;
299
300
301
302
303 memcpy(ptr, skb->h.raw, skb->len);
304 memcpy(skb2->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
305 iph = skb2->ip_hdr = skb2->h.iph;
306 }
307 else
308 {
309
310
311
312
313 skb2 = skb;
314 skb2->dev=dev2;
315 #ifdef CONFIG_IP_MROUTE
316 if(is_frag&16)
317 ip_encap(skb,skb->len, dev2, raddr);
318 else
319 {
320 #endif
321 skb->arp=1;
322 skb->raddr=raddr;
323 if(dev2->hard_header)
324 {
325 if(dev2->hard_header(skb, dev2, ETH_P_IP, NULL, NULL, skb->len)<0)
326 skb->arp=0;
327 }
328 #ifdef CONFIG_IP_MROUTE
329 }
330 #endif
331 ip_statistics.IpForwDatagrams++;
332 }
333
334 if (opt->optlen)
335 {
336 unsigned char * optptr;
337 if (opt->rr_needaddr)
338 {
339 optptr = (unsigned char *)iph + opt->rr;
340 memcpy(&optptr[optptr[2]-5], &dev2->pa_addr, 4);
341 opt->is_changed = 1;
342 }
343 if (opt->srr_is_hit)
344 {
345 int srrptr, srrspace;
346
347 optptr = (unsigned char *)iph + opt->srr;
348
349 for ( srrptr=optptr[2], srrspace = optptr[1];
350 srrptr <= srrspace;
351 srrptr += 4
352 )
353 {
354 if (srrptr + 3 > srrspace)
355 break;
356 if (memcmp(&target_addr, &optptr[srrptr-1], 4) == 0)
357 break;
358 }
359 if (srrptr + 3 <= srrspace)
360 {
361 opt->is_changed = 1;
362 memcpy(&optptr[srrptr-1], &dev2->pa_addr, 4);
363 iph->daddr = target_addr;
364 optptr[2] = srrptr+4;
365 }
366 else
367 printk("ip_forward(): Argh! Destination lost!\n");
368 }
369 if (opt->ts_needaddr)
370 {
371 optptr = (unsigned char *)iph + opt->ts;
372 memcpy(&optptr[optptr[2]-9], &dev2->pa_addr, 4);
373 opt->is_changed = 1;
374 }
375 if (opt->is_changed)
376 {
377 opt->is_changed = 0;
378 ip_send_check(iph);
379 }
380 }
381
382
383
384
385
386
387
388
389
390
391
392 if(skb2->len > dev2->mtu + dev2->hard_header_len)
393 {
394 ip_fragment(NULL,skb2,dev2, is_frag);
395 kfree_skb(skb2,FREE_WRITE);
396 }
397 else
398 {
399 #ifdef CONFIG_IP_ACCT
400
401
402
403
404 ip_fw_chk(iph,dev,ip_acct_chain,IP_FW_F_ACCEPT,1);
405 #endif
406
407
408
409
410
411
412 if(iph->tos & IPTOS_LOWDELAY)
413 dev_queue_xmit(skb2, dev2, SOPRI_INTERACTIVE);
414 else if(iph->tos & IPTOS_THROUGHPUT)
415 dev_queue_xmit(skb2, dev2, SOPRI_BACKGROUND);
416 else
417 dev_queue_xmit(skb2, dev2, SOPRI_NORMAL);
418 }
419 }
420 else
421 return -1;
422
423
424
425
426
427 if(skb==skb2)
428 return 0;
429
430 #ifdef CONFIG_IP_MASQUERADE
431
432
433
434
435 if(skb!=skb_in)
436 {
437 kfree_skb(skb_in, FREE_WRITE);
438 return 0;
439 }
440 #endif
441 return 1;
442 }
443
444
445 #endif