This source file includes following definitions.
- ip_options_build
- ip_options_echo
- ip_options_fragment
- ip_options_compile
- ip_ioctl
- ip_send
- ip_send_room
- ip_build_header
- ip_send_check
- ip_frag_create
- ip_find
- ip_free
- ip_expire
- ip_create
- ip_done
- ip_glue
- ip_defrag
- ip_fragment
- ip_forward
- ip_rcv
- ip_loopback
- ip_queue_xmit
- ip_mc_procinfo
- ip_mc_find_devfor
- ip_setsockopt
- ip_getsockopt
- ip_build_xmit
- ip_rt_event
- ip_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 #include <asm/segment.h>
119 #include <asm/system.h>
120 #include <linux/types.h>
121 #include <linux/kernel.h>
122 #include <linux/sched.h>
123 #include <linux/mm.h>
124 #include <linux/string.h>
125 #include <linux/errno.h>
126 #include <linux/config.h>
127
128 #include <linux/socket.h>
129 #include <linux/sockios.h>
130 #include <linux/in.h>
131 #include <linux/inet.h>
132 #include <linux/netdevice.h>
133 #include <linux/etherdevice.h>
134 #include <linux/proc_fs.h>
135 #include <linux/stat.h>
136
137 #include <net/snmp.h>
138 #include <net/ip.h>
139 #include <net/protocol.h>
140 #include <net/route.h>
141 #include <net/tcp.h>
142 #include <net/udp.h>
143 #include <linux/skbuff.h>
144 #include <net/sock.h>
145 #include <net/arp.h>
146 #include <net/icmp.h>
147 #include <net/raw.h>
148 #include <net/checksum.h>
149 #include <linux/igmp.h>
150 #include <linux/ip_fw.h>
151 #include <linux/mroute.h>
152
153 #define CONFIG_IP_DEFRAG
154
155 extern int last_retran;
156 extern void sort_send(struct sock *sk);
157
158 #define min(a,b) ((a)<(b)?(a):(b))
159
160
161
162
163
164 #ifdef CONFIG_IP_FORWARD
165 struct ip_mib ip_statistics={1,64,};
166 #else
167 struct ip_mib ip_statistics={2,64,};
168 #endif
169
170
171
172
173
174
175
176
177
178 static void ip_options_build(struct sk_buff * skb, struct options * opt,
179 __u32 daddr, __u32 saddr,
180 int is_frag) {
181 unsigned char * iph = (unsigned char*)skb->ip_hdr;
182
183 memcpy(skb->proto_priv, opt, sizeof(struct options));
184 memcpy(iph+sizeof(struct iphdr), opt->__data, opt->optlen);
185 opt = (struct options*)skb->proto_priv;
186 opt->is_data = 0;
187
188 if (opt->srr)
189 memcpy(iph+opt->srr+iph[opt->srr+1]-4, &daddr, 4);
190
191 if (!is_frag) {
192 if (opt->rr_needaddr)
193 memcpy(iph+opt->rr+iph[opt->rr+2]-5, &saddr, 4);
194 if (opt->ts_needaddr)
195 memcpy(iph+opt->ts+iph[opt->ts+2]-9, &saddr, 4);
196 if (opt->ts_needtime) {
197 struct timeval tv;
198 __u32 midtime;
199 do_gettimeofday(&tv);
200 midtime = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
201 memcpy(iph+opt->ts+iph[opt->ts+2]-5, &midtime, 4);
202 }
203 return;
204 }
205 if (opt->rr) {
206 memset(iph+opt->rr, IPOPT_NOP, iph[opt->rr+1]);
207 opt->rr = 0;
208 opt->rr_needaddr = 0;
209 }
210 if (opt->ts) {
211 memset(iph+opt->ts, IPOPT_NOP, iph[opt->ts+1]);
212 opt->ts = 0;
213 opt->ts_needaddr = opt->ts_needtime = 0;
214 }
215 }
216
217 int ip_options_echo(struct options * dopt, struct options * sopt,
218 __u32 daddr, __u32 saddr,
219 struct sk_buff * skb) {
220 unsigned char *sptr, *dptr;
221 int soffset, doffset;
222 int optlen;
223
224 memset(dopt, 0, sizeof(struct options));
225
226 dopt->is_data = 1;
227
228 if (!sopt)
229 sopt = (struct options*)skb->proto_priv;
230
231 if (sopt->optlen == 0) {
232 dopt->optlen = 0;
233 return 0;
234 }
235
236 sptr = (sopt->is_data ? sopt->__data - sizeof(struct iphdr) :
237 (unsigned char *)skb->ip_hdr);
238 dptr = dopt->__data;
239
240 if (sopt->rr) {
241 optlen = sptr[sopt->rr+1];
242 soffset = sptr[sopt->rr+2];
243 dopt->rr = dopt->optlen + sizeof(struct iphdr);
244 memcpy(dptr, sptr+sopt->rr, optlen);
245 if (sopt->rr_needaddr && soffset <= optlen) {
246 if (soffset + 3 > optlen)
247 return -EINVAL;
248 dptr[2] = soffset + 4;
249 dopt->rr_needaddr = 1;
250 }
251 dptr += optlen;
252 dopt->optlen += optlen;
253 }
254 if (sopt->ts) {
255 optlen = sptr[sopt->ts+1];
256 soffset = sptr[sopt->ts+2];
257 dopt->ts = dopt->optlen + sizeof(struct iphdr);
258 memcpy(dptr, sptr+sopt->ts, optlen);
259 if (soffset <= optlen) {
260 if (dopt->ts_needaddr) {
261 if (soffset + 3 > optlen)
262 return -EINVAL;
263 dopt->ts_needaddr = 1;
264 soffset += 4;
265 }
266 if (dopt->ts_needtime) {
267 if (soffset + 3 > optlen)
268 return -EINVAL;
269 dopt->ts_needtime = 1;
270 soffset += 4;
271 }
272 if (((struct timestamp*)(dptr+1))->flags == IPOPT_TS_PRESPEC) {
273 __u32 addr;
274 memcpy(&addr, sptr+soffset-9, 4);
275 if (ip_chk_addr(addr) == 0) {
276 dopt->ts_needtime = 0;
277 dopt->ts_needaddr = 0;
278 soffset -= 8;
279 }
280 }
281 dptr[2] = soffset;
282 }
283 dptr += optlen;
284 dopt->optlen += optlen;
285 }
286 if (sopt->srr) {
287 unsigned char * start = sptr+sopt->srr;
288 __u32 faddr;
289
290 optlen = start[1];
291 soffset = start[2];
292 doffset = 0;
293 if (soffset > optlen)
294 soffset = optlen + 1;
295 soffset -= 4;
296 if (soffset > 3) {
297 memcpy(&faddr, &start[soffset-1], 4);
298 for (soffset-=4, doffset=4; soffset > 3; soffset-=4, doffset+=4)
299 memcpy(&dptr[doffset-1], &start[soffset-1], 4);
300
301
302
303 if (memcmp(&saddr, &start[soffset+3], 4) == 0)
304 doffset -= 4;
305 }
306 if (doffset > 3) {
307 memcpy(&start[doffset-1], &daddr, 4);
308 dopt->faddr = faddr;
309 dptr[0] = start[0];
310 dptr[1] = doffset+3;
311 dptr[2] = 4;
312 dptr += doffset+3;
313 dopt->srr = dopt->optlen + sizeof(struct iphdr);
314 dopt->optlen += doffset+3;
315 dopt->is_strictroute = sopt->is_strictroute;
316 }
317 }
318 while (dopt->optlen & 3) {
319 *dptr++ = IPOPT_END;
320 dopt->optlen++;
321 }
322 return 0;
323 }
324
325 static void ip_options_fragment(struct sk_buff * skb) {
326 unsigned char * optptr = (unsigned char*)skb->ip_hdr;
327 struct options * opt = (struct options*)skb->proto_priv;
328 int l = opt->optlen;
329 int optlen;
330
331 while (l > 0) {
332 switch (*optptr) {
333 case IPOPT_END:
334 return;
335 case IPOPT_NOOP:
336 l--;
337 optptr++;
338 continue;
339 }
340 optlen = optptr[1];
341 if (l<2 || optlen>l)
342 return;
343 if (!(*optptr & 0x80))
344 memset(optptr, IPOPT_NOOP, optlen);
345 l -= optlen;
346 optptr += optlen;
347 }
348 opt->ts = 0;
349 opt->rr = 0;
350 opt->rr_needaddr = 0;
351 opt->ts_needaddr = 0;
352 opt->ts_needtime = 0;
353 return;
354 }
355
356
357
358
359
360
361
362 int ip_options_compile(struct options * opt, struct sk_buff * skb)
363 {
364 int l;
365 unsigned char * iph;
366 unsigned char * optptr;
367 int optlen;
368 unsigned char * pp_ptr = NULL;
369
370 if (!opt) {
371 opt = (struct options*)skb->proto_priv;
372 memset(opt, 0, sizeof(struct options));
373 iph = (unsigned char*)skb->ip_hdr;
374 opt->optlen = ((struct iphdr *)iph)->ihl*4 - sizeof(struct iphdr);
375 optptr = iph + sizeof(struct iphdr);
376 opt->is_data = 0;
377 } else {
378 optptr = opt->is_data ? opt->__data : (unsigned char*)&skb->ip_hdr[1];
379 iph = optptr - sizeof(struct iphdr);
380 }
381
382 for (l = opt->optlen; l > 0; ) {
383 switch (*optptr) {
384 case IPOPT_END:
385 for (optptr++, l--; l>0; l--) {
386 if (*optptr != IPOPT_END) {
387 *optptr = IPOPT_END;
388 opt->is_changed = 1;
389 }
390 }
391 goto eol;
392 case IPOPT_NOOP:
393 l--;
394 optptr++;
395 continue;
396 }
397 optlen = optptr[1];
398 if (l<2 || optlen>l) {
399 pp_ptr = optptr;
400 break;
401 }
402 switch (*optptr) {
403 case IPOPT_SSRR:
404 case IPOPT_LSRR:
405 if (optlen < 3) {
406 pp_ptr = optptr + 1;
407 break;
408 }
409 if (optptr[2] < 4) {
410 pp_ptr = optptr + 2;
411 break;
412 }
413
414 if (opt->srr) {
415 pp_ptr = optptr;
416 break;
417 }
418 if (!skb) {
419 if (optptr[2] != 4 || optlen < 7 || ((optlen-3) & 3)) {
420 pp_ptr = optptr + 1;
421 break;
422 }
423 memcpy(&opt->faddr, &optptr[3], 4);
424 if (optlen > 7)
425 memmove(&optptr[3], &optptr[7], optlen-7);
426 }
427 opt->is_strictroute = (optptr[0] == IPOPT_SSRR);
428 opt->srr = optptr - iph;
429 break;
430 case IPOPT_RR:
431 if (opt->rr) {
432 pp_ptr = optptr;
433 break;
434 }
435 if (optlen < 3) {
436 pp_ptr = optptr + 1;
437 break;
438 }
439 if (optptr[2] < 4) {
440 pp_ptr = optptr + 2;
441 break;
442 }
443 if (optptr[2] <= optlen) {
444 if (optptr[2]+3 > optlen) {
445 pp_ptr = optptr + 2;
446 break;
447 }
448 if (skb) {
449 memcpy(&optptr[optptr[2]-1], &skb->dev->pa_addr, 4);
450 opt->is_changed = 1;
451 }
452 optptr[2] += 4;
453 opt->rr_needaddr = 1;
454 }
455 opt->rr = optptr - iph;
456 break;
457 case IPOPT_TIMESTAMP:
458 if (opt->ts) {
459 pp_ptr = optptr;
460 break;
461 }
462 if (optlen < 4) {
463 pp_ptr = optptr + 1;
464 break;
465 }
466 if (optptr[2] < 5) {
467 pp_ptr = optptr + 2;
468 break;
469 }
470 if (optptr[2] <= optlen) {
471 struct timestamp * ts = (struct timestamp*)(optptr+1);
472 __u32 * timeptr = NULL;
473 if (ts->ptr+3 > ts->len) {
474 pp_ptr = optptr + 2;
475 break;
476 }
477 switch (ts->flags) {
478 case IPOPT_TS_TSONLY:
479 opt->ts = optptr - iph;
480 if (skb) {
481 timeptr = (__u32*)&optptr[ts->ptr-1];
482 opt->is_changed = 1;
483 }
484 ts->ptr += 4;
485 break;
486 case IPOPT_TS_TSANDADDR:
487 if (ts->ptr+7 > ts->len) {
488 pp_ptr = optptr + 2;
489 break;
490 }
491 opt->ts = optptr - iph;
492 if (skb) {
493 memcpy(&optptr[ts->ptr-1], &skb->dev->pa_addr, 4);
494 timeptr = (__u32*)&optptr[ts->ptr+3];
495 }
496 opt->ts_needaddr = 1;
497 opt->ts_needtime = 1;
498 ts->ptr += 8;
499 break;
500 case IPOPT_TS_PRESPEC:
501 if (ts->ptr+7 > ts->len) {
502 pp_ptr = optptr + 2;
503 break;
504 }
505 opt->ts = optptr - iph;
506 {
507 __u32 addr;
508 memcpy(&addr, &optptr[ts->ptr-1], 4);
509 if (ip_chk_addr(addr) == 0)
510 break;
511 if (skb)
512 timeptr = (__u32*)&optptr[ts->ptr+3];
513 }
514 opt->ts_needaddr = 1;
515 opt->ts_needtime = 1;
516 ts->ptr += 8;
517 break;
518 default:
519 pp_ptr = optptr + 3;
520 break;
521 }
522 if (timeptr) {
523 struct timeval tv;
524 __u32 midtime;
525 do_gettimeofday(&tv);
526 midtime = htonl((tv.tv_sec % 86400) * 1000 + tv.tv_usec / 1000);
527 memcpy(timeptr, &midtime, sizeof(__u32));
528 opt->is_changed = 1;
529 }
530 } else {
531 struct timestamp * ts = (struct timestamp*)(optptr+1);
532 if (ts->overflow == 15) {
533 pp_ptr = optptr + 3;
534 break;
535 }
536 opt->ts = optptr - iph;
537 if (skb) {
538 ts->overflow++;
539 opt->is_changed = 1;
540 }
541 }
542 break;
543 case IPOPT_SEC:
544 case IPOPT_SID:
545 default:
546 if (!skb) {
547 pp_ptr = optptr;
548 break;
549 }
550 break;
551 }
552 l -= optlen;
553 optptr += optlen;
554 }
555
556 eol:
557 if (!pp_ptr)
558 return 0;
559
560 if (skb) {
561 icmp_send(skb, ICMP_PARAMETERPROB, 0, pp_ptr-iph, skb->dev);
562 kfree_skb(skb, FREE_READ);
563 }
564 return -EINVAL;
565 }
566
567
568
569
570
571
572
573 int ip_ioctl(struct sock *sk, int cmd, unsigned long arg)
574 {
575 switch(cmd)
576 {
577 default:
578 return(-EINVAL);
579 }
580 }
581
582
583
584
585
586
587 static int ip_send(struct sk_buff *skb, __u32 daddr, int len, struct device *dev, __u32 saddr)
588 {
589 int mac = 0;
590
591 skb->dev = dev;
592 skb->arp = 1;
593 if (dev->hard_header)
594 {
595
596
597
598
599 skb_reserve(skb,(dev->hard_header_len+15)&~15);
600 mac = dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, len);
601 if (mac < 0)
602 {
603 mac = -mac;
604 skb->arp = 0;
605 skb->raddr = daddr;
606 }
607 }
608 return mac;
609 }
610
611 static int ip_send_room(struct sk_buff *skb, __u32 daddr, int len, struct device *dev, __u32 saddr)
612 {
613 int mac = 0;
614
615 skb->dev = dev;
616 skb->arp = 1;
617 if (dev->hard_header)
618 {
619 skb_reserve(skb,MAX_HEADER);
620 mac = dev->hard_header(skb, dev, ETH_P_IP, NULL, NULL, len);
621 if (mac < 0)
622 {
623 mac = -mac;
624 skb->arp = 0;
625 skb->raddr = daddr;
626 }
627 }
628 return mac;
629 }
630
631 int ip_id_count = 0;
632
633
634
635
636
637
638
639 int ip_build_header(struct sk_buff *skb, __u32 saddr, __u32 daddr,
640 struct device **dev, int type, struct options *opt, int len, int tos, int ttl)
641 {
642 struct rtable *rt;
643 __u32 raddr;
644 int tmp;
645 __u32 src;
646 struct iphdr *iph;
647 __u32 final_daddr = daddr;
648
649 if (opt && opt->srr)
650 daddr = opt->faddr;
651
652
653
654
655
656 #ifdef CONFIG_IP_MULTICAST
657 if(MULTICAST(daddr) && *dev==NULL && skb->sk && *skb->sk->ip_mc_name)
658 *dev=dev_get(skb->sk->ip_mc_name);
659 #endif
660 if (*dev == NULL)
661 {
662 if(skb->localroute)
663 rt = ip_rt_local(daddr, NULL, &src);
664 else
665 rt = ip_rt_route(daddr, NULL, &src);
666 if (rt == NULL)
667 {
668 ip_statistics.IpOutNoRoutes++;
669 return(-ENETUNREACH);
670 }
671
672 *dev = rt->rt_dev;
673
674
675
676
677 if (LOOPBACK(saddr) && !LOOPBACK(daddr))
678 saddr = src;
679 raddr = rt->rt_gateway;
680
681 }
682 else
683 {
684
685
686
687 if(skb->localroute)
688 rt = ip_rt_local(daddr, NULL, &src);
689 else
690 rt = ip_rt_route(daddr, NULL, &src);
691
692
693
694
695 if (LOOPBACK(saddr) && !LOOPBACK(daddr))
696 saddr = src;
697
698 raddr = (rt == NULL) ? 0 : rt->rt_gateway;
699 }
700
701
702
703
704 if (saddr == 0)
705 saddr = src;
706
707
708
709
710 if (raddr == 0)
711 raddr = daddr;
712
713
714
715
716
717 if(type==IPPROTO_TCP)
718 tmp = ip_send_room(skb, raddr, len, *dev, saddr);
719 else
720 tmp = ip_send(skb, raddr, len, *dev, saddr);
721
722
723
724
725
726 skb->dev = *dev;
727 skb->saddr = saddr;
728
729
730
731
732
733
734
735
736
737
738 if(type == IPPROTO_RAW)
739 return (tmp);
740
741
742
743
744
745 if (opt)
746 iph=(struct iphdr *)skb_put(skb,sizeof(struct iphdr) + opt->optlen);
747 else
748 iph=(struct iphdr *)skb_put(skb,sizeof(struct iphdr));
749
750 iph->version = 4;
751 iph->ihl = 5;
752 iph->tos = tos;
753 iph->frag_off = 0;
754 iph->ttl = ttl;
755 iph->daddr = daddr;
756 iph->saddr = saddr;
757 iph->protocol = type;
758 skb->ip_hdr = iph;
759
760 if (!opt || !opt->optlen)
761 return sizeof(struct iphdr) + tmp;
762 if (opt->is_strictroute && rt && rt->rt_gateway) {
763 ip_statistics.IpOutNoRoutes++;
764 return -ENETUNREACH;
765 }
766 iph->ihl += opt->optlen>>2;
767 ip_options_build(skb, opt, final_daddr, (*dev)->pa_addr, 0);
768 return iph->ihl*4 + tmp;
769 }
770
771
772
773
774
775
776 void ip_send_check(struct iphdr *iph)
777 {
778 iph->check = 0;
779 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
780 }
781
782
783
784
785
786
787
788
789
790
791 static struct ipq *ipqueue = NULL;
792
793
794
795
796
797 static struct ipfrag *ip_frag_create(int offset, int end, struct sk_buff *skb, unsigned char *ptr)
798 {
799 struct ipfrag *fp;
800
801 fp = (struct ipfrag *) kmalloc(sizeof(struct ipfrag), GFP_ATOMIC);
802 if (fp == NULL)
803 {
804 NETDEBUG(printk("IP: frag_create: no memory left !\n"));
805 return(NULL);
806 }
807 memset(fp, 0, sizeof(struct ipfrag));
808
809
810 fp->offset = offset;
811 fp->end = end;
812 fp->len = end - offset;
813 fp->skb = skb;
814 fp->ptr = ptr;
815
816 return(fp);
817 }
818
819
820
821
822
823
824
825 static struct ipq *ip_find(struct iphdr *iph)
826 {
827 struct ipq *qp;
828 struct ipq *qplast;
829
830 cli();
831 qplast = NULL;
832 for(qp = ipqueue; qp != NULL; qplast = qp, qp = qp->next)
833 {
834 if (iph->id== qp->iph->id && iph->saddr == qp->iph->saddr &&
835 iph->daddr == qp->iph->daddr && iph->protocol == qp->iph->protocol)
836 {
837 del_timer(&qp->timer);
838 sti();
839 return(qp);
840 }
841 }
842 sti();
843 return(NULL);
844 }
845
846
847
848
849
850
851
852
853 static void ip_free(struct ipq *qp)
854 {
855 struct ipfrag *fp;
856 struct ipfrag *xp;
857
858
859
860
861
862 del_timer(&qp->timer);
863
864
865 cli();
866 if (qp->prev == NULL)
867 {
868 ipqueue = qp->next;
869 if (ipqueue != NULL)
870 ipqueue->prev = NULL;
871 }
872 else
873 {
874 qp->prev->next = qp->next;
875 if (qp->next != NULL)
876 qp->next->prev = qp->prev;
877 }
878
879
880
881 fp = qp->fragments;
882 while (fp != NULL)
883 {
884 xp = fp->next;
885 IS_SKB(fp->skb);
886 kfree_skb(fp->skb,FREE_READ);
887 kfree_s(fp, sizeof(struct ipfrag));
888 fp = xp;
889 }
890
891
892 kfree_s(qp->iph, 64 + 8);
893
894
895 kfree_s(qp, sizeof(struct ipq));
896 sti();
897 }
898
899
900
901
902
903
904 static void ip_expire(unsigned long arg)
905 {
906 struct ipq *qp;
907
908 qp = (struct ipq *)arg;
909
910
911
912
913
914 ip_statistics.IpReasmTimeout++;
915 ip_statistics.IpReasmFails++;
916
917 if(qp->fragments!=NULL)
918 icmp_send(qp->fragments->skb,ICMP_TIME_EXCEEDED,
919 ICMP_EXC_FRAGTIME, 0, qp->dev);
920
921
922
923
924 ip_free(qp);
925 }
926
927
928
929
930
931
932
933
934
935 static struct ipq *ip_create(struct sk_buff *skb, struct iphdr *iph, struct device *dev)
936 {
937 struct ipq *qp;
938 int ihlen;
939
940 qp = (struct ipq *) kmalloc(sizeof(struct ipq), GFP_ATOMIC);
941 if (qp == NULL)
942 {
943 NETDEBUG(printk("IP: create: no memory left !\n"));
944 return(NULL);
945 skb->dev = qp->dev;
946 }
947 memset(qp, 0, sizeof(struct ipq));
948
949
950
951
952
953 ihlen = iph->ihl * 4;
954 qp->iph = (struct iphdr *) kmalloc(64 + 8, GFP_ATOMIC);
955 if (qp->iph == NULL)
956 {
957 NETDEBUG(printk("IP: create: no memory left !\n"));
958 kfree_s(qp, sizeof(struct ipq));
959 return(NULL);
960 }
961
962 memcpy(qp->iph, iph, ihlen + 8);
963 qp->len = 0;
964 qp->ihlen = ihlen;
965 qp->fragments = NULL;
966 qp->dev = dev;
967
968
969 qp->timer.expires = jiffies + IP_FRAG_TIME;
970 qp->timer.data = (unsigned long) qp;
971 qp->timer.function = ip_expire;
972 add_timer(&qp->timer);
973
974
975 qp->prev = NULL;
976 cli();
977 qp->next = ipqueue;
978 if (qp->next != NULL)
979 qp->next->prev = qp;
980 ipqueue = qp;
981 sti();
982 return(qp);
983 }
984
985
986
987
988
989
990 static int ip_done(struct ipq *qp)
991 {
992 struct ipfrag *fp;
993 int offset;
994
995
996 if (qp->len == 0)
997 return(0);
998
999
1000 fp = qp->fragments;
1001 offset = 0;
1002 while (fp != NULL)
1003 {
1004 if (fp->offset > offset)
1005 return(0);
1006 offset = fp->end;
1007 fp = fp->next;
1008 }
1009
1010
1011 return(1);
1012 }
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023 static struct sk_buff *ip_glue(struct ipq *qp)
1024 {
1025 struct sk_buff *skb;
1026 struct iphdr *iph;
1027 struct ipfrag *fp;
1028 unsigned char *ptr;
1029 int count, len;
1030
1031
1032
1033
1034 len = qp->ihlen + qp->len;
1035
1036 if ((skb = dev_alloc_skb(len)) == NULL)
1037 {
1038 ip_statistics.IpReasmFails++;
1039 NETDEBUG(printk("IP: queue_glue: no memory for gluing queue %p\n", qp));
1040 ip_free(qp);
1041 return(NULL);
1042 }
1043
1044
1045 skb_put(skb,len);
1046 skb->h.raw = skb->data;
1047 skb->free = 1;
1048
1049
1050 ptr = (unsigned char *) skb->h.raw;
1051 memcpy(ptr, ((unsigned char *) qp->iph), qp->ihlen);
1052 ptr += qp->ihlen;
1053
1054 count = 0;
1055
1056
1057 fp = qp->fragments;
1058 while(fp != NULL)
1059 {
1060 if(count+fp->len > skb->len)
1061 {
1062 NETDEBUG(printk("Invalid fragment list: Fragment over size.\n"));
1063 ip_free(qp);
1064 kfree_skb(skb,FREE_WRITE);
1065 ip_statistics.IpReasmFails++;
1066 return NULL;
1067 }
1068 memcpy((ptr + fp->offset), fp->ptr, fp->len);
1069 count += fp->len;
1070 fp = fp->next;
1071 }
1072
1073
1074 ip_free(qp);
1075
1076
1077 iph = skb->h.iph;
1078 iph->frag_off = 0;
1079 iph->tot_len = htons((iph->ihl * 4) + count);
1080 skb->ip_hdr = iph;
1081
1082 ip_statistics.IpReasmOKs++;
1083 return(skb);
1084 }
1085
1086
1087
1088
1089
1090
1091 static struct sk_buff *ip_defrag(struct iphdr *iph, struct sk_buff *skb, struct device *dev)
1092 {
1093 struct ipfrag *prev, *next, *tmp;
1094 struct ipfrag *tfp;
1095 struct ipq *qp;
1096 struct sk_buff *skb2;
1097 unsigned char *ptr;
1098 int flags, offset;
1099 int i, ihl, end;
1100
1101 ip_statistics.IpReasmReqds++;
1102
1103
1104 qp = ip_find(iph);
1105
1106
1107 offset = ntohs(iph->frag_off);
1108 flags = offset & ~IP_OFFSET;
1109 offset &= IP_OFFSET;
1110 if (((flags & IP_MF) == 0) && (offset == 0))
1111 {
1112 if (qp != NULL)
1113 ip_free(qp);
1114 return(skb);
1115 }
1116
1117 offset <<= 3;
1118 ihl = iph->ihl * 4;
1119
1120
1121
1122
1123
1124
1125
1126 if (qp != NULL)
1127 {
1128
1129
1130
1131 if (offset == 0)
1132 {
1133 qp->ihlen = ihl;
1134 memcpy(qp->iph, iph, ihl+8);
1135 }
1136 del_timer(&qp->timer);
1137 qp->timer.expires = jiffies + IP_FRAG_TIME;
1138 qp->timer.data = (unsigned long) qp;
1139 qp->timer.function = ip_expire;
1140 add_timer(&qp->timer);
1141 }
1142 else
1143 {
1144
1145
1146
1147 if ((qp = ip_create(skb, iph, dev)) == NULL)
1148 {
1149 skb->sk = NULL;
1150 kfree_skb(skb, FREE_READ);
1151 ip_statistics.IpReasmFails++;
1152 return NULL;
1153 }
1154 }
1155
1156
1157
1158
1159
1160 end = offset + ntohs(iph->tot_len) - ihl;
1161
1162
1163
1164
1165
1166 ptr = skb->data + ihl;
1167
1168
1169
1170
1171
1172 if ((flags & IP_MF) == 0)
1173 qp->len = end;
1174
1175
1176
1177
1178
1179
1180
1181 prev = NULL;
1182 for(next = qp->fragments; next != NULL; next = next->next)
1183 {
1184 if (next->offset > offset)
1185 break;
1186 prev = next;
1187 }
1188
1189
1190
1191
1192
1193
1194 if (prev != NULL && offset < prev->end)
1195 {
1196 i = prev->end - offset;
1197 offset += i;
1198 ptr += i;
1199 }
1200
1201
1202
1203
1204
1205
1206 for(tmp=next; tmp != NULL; tmp = tfp)
1207 {
1208 tfp = tmp->next;
1209 if (tmp->offset >= end)
1210 break;
1211
1212 i = end - next->offset;
1213 tmp->len -= i;
1214 tmp->offset += i;
1215 tmp->ptr += i;
1216
1217
1218
1219
1220 if (tmp->len <= 0)
1221 {
1222 if (tmp->prev != NULL)
1223 tmp->prev->next = tmp->next;
1224 else
1225 qp->fragments = tmp->next;
1226
1227 if (tfp->next != NULL)
1228 tmp->next->prev = tmp->prev;
1229
1230 next=tfp;
1231
1232 kfree_skb(tmp->skb,FREE_READ);
1233 kfree_s(tmp, sizeof(struct ipfrag));
1234 }
1235 }
1236
1237
1238
1239
1240
1241 tfp = NULL;
1242 tfp = ip_frag_create(offset, end, skb, ptr);
1243
1244
1245
1246
1247
1248 if (!tfp)
1249 {
1250 skb->sk = NULL;
1251 kfree_skb(skb, FREE_READ);
1252 return NULL;
1253 }
1254 tfp->prev = prev;
1255 tfp->next = next;
1256 if (prev != NULL)
1257 prev->next = tfp;
1258 else
1259 qp->fragments = tfp;
1260
1261 if (next != NULL)
1262 next->prev = tfp;
1263
1264
1265
1266
1267
1268
1269
1270 if (ip_done(qp))
1271 {
1272 skb2 = ip_glue(qp);
1273 return(skb2);
1274 }
1275 return(NULL);
1276 }
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291 static void ip_fragment(struct sock *sk, struct sk_buff *skb, struct device *dev, int is_frag)
1292 {
1293 struct iphdr *iph;
1294 unsigned char *raw;
1295 unsigned char *ptr;
1296 struct sk_buff *skb2;
1297 int left, mtu, hlen, len;
1298 int offset;
1299 unsigned long flags;
1300
1301
1302
1303
1304
1305 raw = skb->data;
1306 #if 0
1307 iph = (struct iphdr *) (raw + dev->hard_header_len);
1308 skb->ip_hdr = iph;
1309 #else
1310 iph = skb->ip_hdr;
1311 #endif
1312
1313
1314
1315
1316
1317 hlen = iph->ihl * 4;
1318 left = ntohs(iph->tot_len) - hlen;
1319 hlen += dev->hard_header_len;
1320 mtu = (dev->mtu - hlen);
1321 ptr = (raw + hlen);
1322
1323
1324
1325
1326
1327 if (ntohs(iph->frag_off) & IP_DF)
1328 {
1329 ip_statistics.IpFragFails++;
1330 printk("ip_queue_xmit: frag needed\n");
1331 return;
1332 }
1333
1334
1335
1336
1337
1338
1339
1340 if(mtu<8)
1341 {
1342
1343 icmp_send(skb,ICMP_DEST_UNREACH,ICMP_FRAG_NEEDED,dev->mtu, dev);
1344 ip_statistics.IpFragFails++;
1345 return;
1346 }
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357 if (is_frag & 2)
1358 offset = (ntohs(iph->frag_off) & IP_OFFSET) << 3;
1359 else
1360 offset = 0;
1361
1362
1363
1364
1365
1366
1367 while(left > 0)
1368 {
1369 len = left;
1370
1371 if (len > mtu)
1372 len = mtu;
1373
1374
1375 if (len < left)
1376 {
1377 len/=8;
1378 len*=8;
1379 }
1380
1381
1382
1383
1384 if ((skb2 = alloc_skb(len + hlen+15,GFP_ATOMIC)) == NULL)
1385 {
1386 NETDEBUG(printk("IP: frag: no memory for new fragment!\n"));
1387 ip_statistics.IpFragFails++;
1388 return;
1389 }
1390
1391
1392
1393
1394
1395 skb2->arp = skb->arp;
1396 if(skb->free==0)
1397 printk("IP fragmenter: BUG free!=1 in fragmenter\n");
1398 skb2->free = 1;
1399 skb_put(skb2,len + hlen);
1400 skb2->h.raw=(char *) skb2->data;
1401
1402
1403
1404
1405
1406 save_flags(flags);
1407 if (sk)
1408 {
1409 cli();
1410 sk->wmem_alloc += skb2->truesize;
1411 skb2->sk=sk;
1412 }
1413 restore_flags(flags);
1414 skb2->raddr = skb->raddr;
1415
1416
1417
1418
1419
1420 memcpy(skb2->h.raw, raw, hlen);
1421
1422
1423
1424
1425 memcpy(skb2->h.raw + hlen, ptr, len);
1426 left -= len;
1427
1428 skb2->h.raw+=dev->hard_header_len;
1429
1430
1431
1432
1433 iph = (struct iphdr *)(skb2->h.raw);
1434 iph->frag_off = htons((offset >> 3));
1435 skb2->ip_hdr = iph;
1436
1437
1438
1439
1440
1441
1442
1443 if (offset == 0)
1444 ip_options_fragment(skb);
1445
1446
1447
1448
1449
1450 if (left > 0 || (is_frag & 1))
1451 iph->frag_off |= htons(IP_MF);
1452 ptr += len;
1453 offset += len;
1454
1455
1456
1457
1458
1459 ip_statistics.IpFragCreates++;
1460
1461 ip_queue_xmit(sk, dev, skb2, 2);
1462 }
1463 ip_statistics.IpFragOKs++;
1464 }
1465
1466
1467
1468 #ifdef CONFIG_IP_FORWARD
1469
1470
1471
1472
1473
1474 int ip_forward(struct sk_buff *skb, struct device *dev, int is_frag,
1475 __u32 target_addr)
1476 {
1477 struct device *dev2;
1478 struct iphdr *iph;
1479 struct sk_buff *skb2;
1480 struct rtable *rt;
1481 unsigned char *ptr;
1482 unsigned long raddr;
1483 struct options * opt = (struct options*)skb->proto_priv;
1484 #ifdef CONFIG_IP_FIREWALL
1485 int fw_res = 0;
1486 #ifdef CONFIG_IP_MASQUERADE
1487 struct sk_buff *skb_in = skb;
1488 #endif
1489
1490
1491
1492
1493
1494
1495
1496 if(!(is_frag&4))
1497 {
1498 fw_res=ip_fw_chk(skb->h.iph, dev, ip_fw_fwd_chain, ip_fw_fwd_policy, 0);
1499 switch (fw_res) {
1500 case FW_ACCEPT:
1501 #ifdef CONFIG_IP_MASQUERADE
1502 case FW_MASQUERADE:
1503 #endif
1504 break;
1505 case FW_REJECT:
1506 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev);
1507
1508 default:
1509 return -1;
1510 }
1511 }
1512 #endif
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524 iph = skb->h.iph;
1525 iph->ttl--;
1526
1527
1528
1529
1530
1531
1532
1533 iph->check = ntohs(iph->check) + 0x0100;
1534 if ((iph->check & 0xFF00) == 0)
1535 iph->check++;
1536 iph->check = htons(iph->check);
1537
1538 if (iph->ttl <= 0)
1539 {
1540
1541 icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, dev);
1542 return -1;
1543 }
1544
1545
1546
1547
1548
1549
1550 rt = ip_rt_route(target_addr, NULL, NULL);
1551 if (rt == NULL)
1552 {
1553
1554
1555
1556
1557 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_UNREACH, 0, dev);
1558 return -1;
1559 }
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570 raddr = rt->rt_gateway;
1571
1572 if (raddr != 0)
1573 {
1574
1575
1576
1577
1578 if (opt->is_strictroute)
1579 {
1580 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0, dev);
1581 return -1;
1582 }
1583
1584
1585
1586
1587
1588
1589 #if 0
1590 rt = ip_rt_route(raddr, NULL, NULL);
1591 if (rt == NULL)
1592 {
1593
1594
1595
1596 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, dev);
1597 return -1;
1598 }
1599 if (rt->rt_gateway != 0)
1600 raddr = rt->rt_gateway;
1601 #endif
1602 }
1603 else
1604 raddr = target_addr;
1605
1606
1607
1608
1609
1610 dev2 = rt->rt_dev;
1611
1612
1613
1614
1615
1616
1617 #ifndef CONFIG_IP_NO_ICMP_REDIRECT
1618 if (dev == dev2 && !((iph->saddr^iph->daddr)&dev->pa_mask) &&
1619 (rt->rt_flags&RTF_MODIFIED) && !opt->srr)
1620 icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, raddr, dev);
1621 #endif
1622
1623
1624
1625
1626
1627
1628 if (dev2->flags & IFF_UP)
1629 {
1630 #ifdef CONFIG_IP_MASQUERADE
1631
1632
1633
1634
1635 if (!(is_frag&4) && fw_res==2)
1636 ip_fw_masquerade(&skb, dev2);
1637 #endif
1638 IS_SKB(skb);
1639
1640 if (skb->len > dev2->mtu && (ntohs(iph->frag_off) & IP_DF)) {
1641 ip_statistics.IpFragFails++;
1642 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, dev2->mtu, dev);
1643 return -1;
1644 }
1645
1646 if(skb_headroom(skb)<dev2->hard_header_len)
1647 {
1648 skb2 = alloc_skb(dev2->hard_header_len + skb->len + 15, GFP_ATOMIC);
1649 IS_SKB(skb2);
1650
1651
1652
1653
1654
1655
1656 if (skb2 == NULL)
1657 {
1658 NETDEBUG(printk("\nIP: No memory available for IP forward\n"));
1659 return -1;
1660 }
1661
1662
1663
1664
1665
1666 ip_send(skb2,raddr,skb->len,dev2,dev2->pa_addr);
1667
1668
1669
1670
1671
1672
1673 ptr = skb_put(skb2,skb->len);
1674 skb2->free = 1;
1675 skb2->h.raw = ptr;
1676
1677
1678
1679
1680 memcpy(ptr, skb->h.raw, skb->len);
1681 memcpy(skb2->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
1682 iph = skb2->ip_hdr = skb2->h.iph;
1683 }
1684 else
1685 {
1686
1687
1688
1689
1690 skb2 = skb;
1691 skb2->dev=dev2;
1692 skb->arp=1;
1693 skb->raddr=raddr;
1694 if(dev2->hard_header)
1695 {
1696 if(dev2->hard_header(skb, dev2, ETH_P_IP, NULL, NULL, skb->len)<0)
1697 skb->arp=0;
1698 }
1699 ip_statistics.IpForwDatagrams++;
1700 }
1701
1702 if (opt->optlen) {
1703 unsigned char * optptr;
1704 if (opt->rr_needaddr) {
1705 optptr = (unsigned char *)iph + opt->rr;
1706 memcpy(&optptr[optptr[2]-5], &dev2->pa_addr, 4);
1707 opt->is_changed = 1;
1708 }
1709 if (opt->srr_is_hit) {
1710 int srrptr, srrspace;
1711
1712 optptr = (unsigned char *)iph + opt->srr;
1713
1714 for ( srrptr=optptr[2], srrspace = optptr[1];
1715 srrptr <= srrspace;
1716 srrptr += 4
1717 ) {
1718 if (srrptr + 3 > srrspace)
1719 break;
1720 if (memcmp(&target_addr, &optptr[srrptr-1], 4) == 0)
1721 break;
1722 }
1723 if (srrptr + 3 <= srrspace) {
1724 opt->is_changed = 1;
1725 memcpy(&optptr[srrptr-1], &dev2->pa_addr, 4);
1726 iph->daddr = target_addr;
1727 optptr[2] = srrptr+4;
1728 } else
1729 printk("ip_forward(): Argh! Destination lost!\n");
1730 }
1731 if (opt->ts_needaddr) {
1732 optptr = (unsigned char *)iph + opt->ts;
1733 memcpy(&optptr[optptr[2]-9], &dev2->pa_addr, 4);
1734 opt->is_changed = 1;
1735 }
1736 if (opt->is_changed) {
1737 opt->is_changed = 0;
1738 ip_send_check(iph);
1739 }
1740 }
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752 if(skb2->len > dev2->mtu + dev2->hard_header_len)
1753 {
1754 ip_fragment(NULL,skb2,dev2, is_frag);
1755 kfree_skb(skb2,FREE_WRITE);
1756 }
1757 else
1758 {
1759 #ifdef CONFIG_IP_ACCT
1760
1761
1762
1763
1764 ip_fw_chk(iph,dev,ip_acct_chain,IP_FW_F_ACCEPT,1);
1765 #endif
1766
1767
1768
1769
1770
1771
1772 if(iph->tos & IPTOS_LOWDELAY)
1773 dev_queue_xmit(skb2, dev2, SOPRI_INTERACTIVE);
1774 else if(iph->tos & IPTOS_THROUGHPUT)
1775 dev_queue_xmit(skb2, dev2, SOPRI_BACKGROUND);
1776 else
1777 dev_queue_xmit(skb2, dev2, SOPRI_NORMAL);
1778 }
1779 }
1780 else
1781 return -1;
1782
1783
1784
1785
1786
1787 if(skb==skb2)
1788 return 0;
1789
1790 #ifdef CONFIG_IP_MASQUERADE
1791
1792
1793
1794
1795 if(skb!=skb_in)
1796 {
1797 kfree_skb(skb_in, FREE_WRITE);
1798 return 0;
1799 }
1800 #endif
1801 return 1;
1802 }
1803
1804
1805 #endif
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815 int ip_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
1816 {
1817 struct iphdr *iph = skb->h.iph;
1818 struct sock *raw_sk=NULL;
1819 unsigned char hash;
1820 unsigned char flag = 0;
1821 struct inet_protocol *ipprot;
1822 int brd=IS_MYADDR;
1823 struct options * opt = NULL;
1824 int is_frag=0;
1825 #ifdef CONFIG_IP_FIREWALL
1826 int err;
1827 #endif
1828
1829 #ifdef CONFIG_NET_IPV6
1830
1831
1832
1833
1834 if(iph->version == 6)
1835 return ipv6_rcv(skb,dev,pt);
1836 #endif
1837
1838 ip_statistics.IpInReceives++;
1839
1840
1841
1842
1843
1844 skb->ip_hdr = iph;
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859 if (skb->len<sizeof(struct iphdr) || iph->ihl<5 || iph->version != 4 || ip_fast_csum((unsigned char *)iph, iph->ihl) !=0
1860 || skb->len < ntohs(iph->tot_len))
1861 {
1862 ip_statistics.IpInHdrErrors++;
1863 kfree_skb(skb, FREE_WRITE);
1864 return(0);
1865 }
1866
1867
1868
1869
1870
1871
1872
1873 skb_trim(skb,ntohs(iph->tot_len));
1874
1875 if (iph->ihl > 5) {
1876 skb->ip_summed = 0;
1877 if (ip_options_compile(NULL, skb))
1878 return(0);
1879 opt = (struct options*)skb->proto_priv;
1880 #ifdef CONFIG_IP_NOSR
1881 if (opt->srr) {
1882 kfree_skb(skb, FREE_READ);
1883 return -EINVAL;
1884 }
1885 #endif
1886 }
1887
1888
1889
1890
1891
1892 #ifdef CONFIG_IP_FIREWALL
1893
1894 if ((err=ip_fw_chk(iph,dev,ip_fw_blk_chain,ip_fw_blk_policy, 0))<FW_ACCEPT)
1895 {
1896 if(err==FW_REJECT)
1897 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0, dev);
1898 kfree_skb(skb, FREE_WRITE);
1899 return 0;
1900 }
1901
1902 #endif
1903
1904
1905
1906
1907
1908 if(iph->frag_off)
1909 {
1910 if (iph->frag_off & htons(IP_MF))
1911 is_frag|=1;
1912
1913
1914
1915
1916 if (iph->frag_off & htons(IP_OFFSET))
1917 is_frag|=2;
1918 }
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932 if ( iph->daddr == skb->dev->pa_addr || (brd = ip_chk_addr(iph->daddr)) != 0)
1933 {
1934 if (opt && opt->srr) {
1935 int srrspace, srrptr;
1936 __u32 nexthop;
1937 unsigned char * optptr = ((unsigned char *)iph) + opt->srr;
1938
1939 if (brd != IS_MYADDR || skb->pkt_type != PACKET_HOST) {
1940 kfree_skb(skb, FREE_WRITE);
1941 return 0;
1942 }
1943
1944 for ( srrptr=optptr[2], srrspace = optptr[1];
1945 srrptr <= srrspace;
1946 srrptr += 4
1947 ) {
1948 int brd2;
1949 if (srrptr + 3 > srrspace) {
1950 icmp_send(skb, ICMP_PARAMETERPROB, 0, opt->srr+2,
1951 skb->dev);
1952 kfree_skb(skb, FREE_WRITE);
1953 return 0;
1954 }
1955 memcpy(&nexthop, &optptr[srrptr-1], 4);
1956 if ((brd2 = ip_chk_addr(nexthop)) == 0)
1957 break;
1958 if (brd2 != IS_MYADDR) {
1959
1960
1961
1962 kfree_skb(skb, FREE_WRITE);
1963 return -EINVAL;
1964 }
1965 }
1966 if (srrptr <= srrspace) {
1967 opt->srr_is_hit = 1;
1968 opt->is_changed = 1;
1969 #ifdef CONFIG_IP_FORWARD
1970 if (ip_forward(skb, dev, is_frag, nexthop))
1971 kfree_skb(skb, FREE_WRITE);
1972 #else
1973 ip_statistics.IpInAddrErrors++;
1974 kfree_skb(skb, FREE_WRITE);
1975 #endif
1976 return 0;
1977 }
1978 }
1979
1980 #ifdef CONFIG_IP_MULTICAST
1981 if(!(dev->flags&IFF_ALLMULTI) && brd==IS_MULTICAST && iph->daddr!=IGMP_ALL_HOSTS && !(dev->flags&IFF_LOOPBACK))
1982 {
1983
1984
1985
1986 struct ip_mc_list *ip_mc=dev->ip_mc_list;
1987 do
1988 {
1989 if(ip_mc==NULL)
1990 {
1991 kfree_skb(skb, FREE_WRITE);
1992 return 0;
1993 }
1994 if(ip_mc->multiaddr==iph->daddr)
1995 break;
1996 ip_mc=ip_mc->next;
1997 }
1998 while(1);
1999 }
2000 #endif
2001
2002 #ifdef CONFIG_IP_MASQUERADE
2003
2004
2005
2006 if (ip_fw_demasquerade(skb))
2007 {
2008 struct iphdr *iph=skb->h.iph;
2009 if (ip_forward(skb, dev, is_frag|4, iph->daddr))
2010 kfree_skb(skb, FREE_WRITE);
2011 return(0);
2012 }
2013 #endif
2014
2015
2016
2017
2018
2019 #ifdef CONFIG_IP_ACCT
2020 ip_fw_chk(iph,dev,ip_acct_chain,IP_FW_F_ACCEPT,1);
2021 #endif
2022
2023
2024
2025
2026
2027 if(is_frag)
2028 {
2029
2030 skb=ip_defrag(iph,skb,dev);
2031 if(skb==NULL)
2032 return 0;
2033 skb->dev = dev;
2034 iph=skb->h.iph;
2035 }
2036
2037
2038
2039
2040
2041 skb->ip_hdr = iph;
2042 skb->h.raw += iph->ihl*4;
2043
2044
2045
2046
2047
2048
2049
2050 hash = iph->protocol & (SOCK_ARRAY_SIZE-1);
2051
2052
2053
2054
2055
2056 if((raw_sk=raw_prot.sock_array[hash])!=NULL)
2057 {
2058 struct sock *sknext=NULL;
2059 struct sk_buff *skb1;
2060 raw_sk=get_sock_raw(raw_sk, iph->protocol, iph->saddr, iph->daddr);
2061 if(raw_sk)
2062 {
2063 do
2064 {
2065
2066 sknext=get_sock_raw(raw_sk->next, iph->protocol, iph->saddr, iph->daddr);
2067 if(sknext)
2068 skb1=skb_clone(skb, GFP_ATOMIC);
2069 else
2070 break;
2071 if(skb1)
2072 raw_rcv(raw_sk, skb1, dev, iph->saddr,iph->daddr);
2073 raw_sk=sknext;
2074 }
2075 while(raw_sk!=NULL);
2076
2077
2078
2079
2080
2081
2082
2083
2084 }
2085 }
2086
2087
2088
2089
2090
2091 hash = iph->protocol & (MAX_INET_PROTOS -1);
2092 for (ipprot = (struct inet_protocol *)inet_protos[hash];ipprot != NULL;ipprot=(struct inet_protocol *)ipprot->next)
2093 {
2094 struct sk_buff *skb2;
2095
2096 if (ipprot->protocol != iph->protocol)
2097 continue;
2098
2099
2100
2101
2102
2103
2104
2105 if (ipprot->copy || raw_sk)
2106 {
2107 skb2 = skb_clone(skb, GFP_ATOMIC);
2108 if(skb2==NULL)
2109 continue;
2110 }
2111 else
2112 {
2113 skb2 = skb;
2114 }
2115 flag = 1;
2116
2117
2118
2119
2120
2121
2122
2123 ipprot->handler(skb2, dev, opt, iph->daddr,
2124 (ntohs(iph->tot_len) - (iph->ihl * 4)),
2125 iph->saddr, 0, ipprot);
2126 }
2127
2128
2129
2130
2131
2132
2133
2134
2135 if(raw_sk!=NULL)
2136 raw_rcv(raw_sk, skb, dev, iph->saddr, iph->daddr);
2137 else if (!flag)
2138 {
2139 if (brd != IS_BROADCAST && brd!=IS_MULTICAST)
2140 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PROT_UNREACH, 0, dev);
2141 kfree_skb(skb, FREE_WRITE);
2142 }
2143
2144 return(0);
2145 }
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155 if(skb->pkt_type!=PACKET_HOST || brd==IS_BROADCAST)
2156 {
2157 kfree_skb(skb,FREE_WRITE);
2158 return 0;
2159 }
2160
2161
2162
2163
2164
2165 #ifdef CONFIG_IP_FORWARD
2166 if (opt && opt->is_strictroute) {
2167 icmp_send(skb, ICMP_PARAMETERPROB, 0, 16, skb->dev);
2168 kfree_skb(skb, FREE_WRITE);
2169 return -1;
2170 }
2171 if (ip_forward(skb, dev, is_frag, iph->daddr))
2172 kfree_skb(skb, FREE_WRITE);
2173 #else
2174
2175
2176 ip_statistics.IpInAddrErrors++;
2177 kfree_skb(skb, FREE_WRITE);
2178 #endif
2179 return(0);
2180 }
2181
2182
2183
2184
2185
2186
2187 static void ip_loopback(struct device *old_dev, struct sk_buff *skb)
2188 {
2189 struct device *dev=&loopback_dev;
2190 int len=ntohs(skb->ip_hdr->tot_len);
2191 struct sk_buff *newskb=dev_alloc_skb(len+dev->hard_header_len+15);
2192
2193 if(newskb==NULL)
2194 return;
2195
2196 newskb->link3=NULL;
2197 newskb->sk=NULL;
2198 newskb->dev=dev;
2199 newskb->saddr=skb->saddr;
2200 newskb->daddr=skb->daddr;
2201 newskb->raddr=skb->raddr;
2202 newskb->free=1;
2203 newskb->lock=0;
2204 newskb->users=0;
2205 newskb->pkt_type=skb->pkt_type;
2206
2207
2208
2209
2210 ip_send(newskb, skb->ip_hdr->daddr, len, dev, skb->ip_hdr->saddr);
2211
2212
2213
2214 newskb->ip_hdr=(struct iphdr *)skb_put(newskb, len);
2215 memcpy(newskb->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
2216
2217
2218
2219
2220 memcpy(newskb->ip_hdr,skb->ip_hdr,len);
2221
2222
2223
2224
2225 ip_queue_xmit(NULL, dev, newskb, 1);
2226 }
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238 void ip_queue_xmit(struct sock *sk, struct device *dev,
2239 struct sk_buff *skb, int free)
2240 {
2241 struct iphdr *iph;
2242
2243
2244
2245 if (dev == NULL)
2246 {
2247 NETDEBUG(printk("IP: ip_queue_xmit dev = NULL\n"));
2248 return;
2249 }
2250
2251 IS_SKB(skb);
2252
2253
2254
2255
2256
2257
2258 skb->dev = dev;
2259 skb->when = jiffies;
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269 #if 0
2270 ptr = skb->data;
2271 ptr += dev->hard_header_len;
2272 iph = (struct iphdr *)ptr;
2273 skb->ip_hdr = iph;
2274 #else
2275 iph = skb->ip_hdr;
2276 #endif
2277 iph->tot_len = ntohs(skb->len-(((unsigned char *)iph)-skb->data));
2278
2279 #ifdef CONFIG_IP_FIREWALL
2280 if(ip_fw_chk(iph, dev, ip_fw_blk_chain, ip_fw_blk_policy, 0) < FW_ACCEPT)
2281
2282 return;
2283 #endif
2284
2285
2286
2287
2288
2289 if(free!=2)
2290 iph->id = htons(ip_id_count++);
2291 else
2292 free=1;
2293
2294
2295 if (sk == NULL)
2296 free = 1;
2297
2298 skb->free = free;
2299
2300
2301
2302
2303
2304
2305
2306 if(ntohs(iph->tot_len)> dev->mtu)
2307 {
2308 ip_fragment(sk,skb,dev,0);
2309 IS_SKB(skb);
2310 kfree_skb(skb,FREE_WRITE);
2311 return;
2312 }
2313
2314
2315
2316
2317
2318 ip_send_check(iph);
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328 if (skb->next != NULL)
2329 {
2330 NETDEBUG(printk("ip_queue_xmit: next != NULL\n"));
2331 skb_unlink(skb);
2332 }
2333
2334
2335
2336
2337
2338
2339
2340
2341 if (!free)
2342 {
2343 unsigned long flags;
2344
2345
2346 sk->packets_out++;
2347
2348
2349 save_flags(flags);
2350 cli();
2351
2352 if (skb->link3 != NULL)
2353 {
2354 NETDEBUG(printk("ip.c: link3 != NULL\n"));
2355 skb->link3 = NULL;
2356 }
2357 if (sk->send_head == NULL)
2358 {
2359 sk->send_tail = skb;
2360 sk->send_head = skb;
2361 }
2362 else
2363 {
2364 sk->send_tail->link3 = skb;
2365 sk->send_tail = skb;
2366 }
2367
2368
2369
2370 restore_flags(flags);
2371 }
2372 else
2373
2374 skb->sk = sk;
2375
2376
2377
2378
2379
2380 ip_statistics.IpOutRequests++;
2381 #ifdef CONFIG_IP_ACCT
2382 ip_fw_chk(iph,dev,ip_acct_chain,IP_FW_F_ACCEPT,1);
2383 #endif
2384
2385 #ifdef CONFIG_IP_MULTICAST
2386
2387
2388
2389
2390
2391 if (MULTICAST(iph->daddr) && !(dev->flags&IFF_LOOPBACK))
2392 {
2393 if(sk==NULL || sk->ip_mc_loop)
2394 {
2395 if(iph->daddr==IGMP_ALL_HOSTS || (dev->flags&IFF_ALLMULTI))
2396 {
2397 ip_loopback(dev,skb);
2398 }
2399 else
2400 {
2401 struct ip_mc_list *imc=dev->ip_mc_list;
2402 while(imc!=NULL)
2403 {
2404 if(imc->multiaddr==iph->daddr)
2405 {
2406 ip_loopback(dev,skb);
2407 break;
2408 }
2409 imc=imc->next;
2410 }
2411 }
2412 }
2413
2414
2415 if(skb->ip_hdr->ttl==0)
2416 {
2417 kfree_skb(skb, FREE_READ);
2418 return;
2419 }
2420 }
2421 #endif
2422 if((dev->flags&IFF_BROADCAST) && (iph->daddr==dev->pa_brdaddr||iph->daddr==0xFFFFFFFF) && !(dev->flags&IFF_LOOPBACK))
2423 ip_loopback(dev,skb);
2424
2425 if (dev->flags & IFF_UP)
2426 {
2427
2428
2429
2430
2431
2432 if (sk != NULL)
2433 {
2434 dev_queue_xmit(skb, dev, sk->priority);
2435 }
2436 else
2437 {
2438 dev_queue_xmit(skb, dev, SOPRI_NORMAL);
2439 }
2440 }
2441 else
2442 {
2443 if(sk)
2444 sk->err = ENETDOWN;
2445 ip_statistics.IpOutDiscards++;
2446 if (free)
2447 kfree_skb(skb, FREE_WRITE);
2448 }
2449 }
2450
2451
2452
2453 #ifdef CONFIG_IP_MULTICAST
2454
2455
2456
2457
2458
2459
2460 int ip_mc_procinfo(char *buffer, char **start, off_t offset, int length, int dummy)
2461 {
2462 off_t pos=0, begin=0;
2463 struct ip_mc_list *im;
2464 unsigned long flags;
2465 int len=0;
2466 struct device *dev;
2467
2468 len=sprintf(buffer,"Device : Count\tGroup Users Timer\n");
2469 save_flags(flags);
2470 cli();
2471
2472 for(dev = dev_base; dev; dev = dev->next)
2473 {
2474 if((dev->flags&IFF_UP)&&(dev->flags&IFF_MULTICAST))
2475 {
2476 len+=sprintf(buffer+len,"%-10s: %5d\n",
2477 dev->name, dev->mc_count);
2478 for(im = dev->ip_mc_list; im; im = im->next)
2479 {
2480 len+=sprintf(buffer+len,
2481 "\t\t\t%08lX %5d %d:%08lX\n",
2482 im->multiaddr, im->users,
2483 im->tm_running, im->timer.expires-jiffies);
2484 pos=begin+len;
2485 if(pos<offset)
2486 {
2487 len=0;
2488 begin=pos;
2489 }
2490 if(pos>offset+length)
2491 break;
2492 }
2493 }
2494 }
2495 restore_flags(flags);
2496 *start=buffer+(offset-begin);
2497 len-=(offset-begin);
2498 if(len>length)
2499 len=length;
2500 return len;
2501 }
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513 static struct device *ip_mc_find_devfor(unsigned long addr)
2514 {
2515 struct device *dev;
2516 for(dev = dev_base; dev; dev = dev->next)
2517 {
2518 if((dev->flags&IFF_UP)&&(dev->flags&IFF_MULTICAST)&&
2519 (dev->pa_addr==addr))
2520 return dev;
2521 }
2522
2523 return NULL;
2524 }
2525
2526 #endif
2527
2528 int ip_setsockopt(struct sock *sk, int level, int optname, char *optval, int optlen)
2529 {
2530 int val,err;
2531 unsigned char ucval;
2532 #if defined(CONFIG_IP_FIREWALL) || defined(CONFIG_IP_ACCT)
2533 struct ip_fw tmp_fw;
2534 #endif
2535 if (optval == NULL)
2536 {
2537 val=0;
2538 ucval=0;
2539 }
2540 else
2541 {
2542 err=verify_area(VERIFY_READ, optval, sizeof(int));
2543 if(err)
2544 return err;
2545 val = get_user((int *) optval);
2546 ucval=get_user((unsigned char *) optval);
2547 }
2548
2549 if(level!=SOL_IP)
2550 return -EOPNOTSUPP;
2551 #ifdef CONFIG_IP_MROUTE
2552 if(optname>=MRT_BASE && optname <=MRT_BASE+10)
2553 {
2554 return ip_mroute_setsockopt(sk,optname,optval,optlen);
2555 }
2556 #endif
2557
2558 switch(optname)
2559 {
2560 case IP_OPTIONS:
2561 {
2562 struct options * opt = NULL;
2563 struct options * old_opt;
2564 if (optlen > 40 || optlen < 0)
2565 return -EINVAL;
2566 err = verify_area(VERIFY_READ, optval, optlen);
2567 if (err)
2568 return err;
2569 opt = kmalloc(sizeof(struct options)+((optlen+3)&~3), GFP_KERNEL);
2570 if (!opt)
2571 return -ENOMEM;
2572 memset(opt, 0, sizeof(struct options));
2573 if (optlen)
2574 memcpy_fromfs(opt->__data, optval, optlen);
2575 while (optlen & 3)
2576 opt->__data[optlen++] = IPOPT_END;
2577 opt->optlen = optlen;
2578 opt->is_data = 1;
2579 opt->is_setbyuser = 1;
2580 if (optlen && ip_options_compile(opt, NULL)) {
2581 kfree_s(opt, sizeof(struct options) + optlen);
2582 return -EINVAL;
2583 }
2584
2585
2586
2587
2588 cli();
2589 old_opt = sk->opt;
2590 sk->opt = opt;
2591 sti();
2592 if (old_opt)
2593 kfree_s(old_opt, sizeof(struct optlen) + old_opt->optlen);
2594 return 0;
2595 }
2596 case IP_TOS:
2597 if(val<0||val>255)
2598 return -EINVAL;
2599 sk->ip_tos=val;
2600 if(val==IPTOS_LOWDELAY)
2601 sk->priority=SOPRI_INTERACTIVE;
2602 if(val==IPTOS_THROUGHPUT)
2603 sk->priority=SOPRI_BACKGROUND;
2604 return 0;
2605 case IP_TTL:
2606 if(val<1||val>255)
2607 return -EINVAL;
2608 sk->ip_ttl=val;
2609 return 0;
2610 case IP_HDRINCL:
2611 if(sk->type!=SOCK_RAW)
2612 return -ENOPROTOOPT;
2613 sk->ip_hdrincl=val?1:0;
2614 return 0;
2615 #ifdef CONFIG_IP_MULTICAST
2616 case IP_MULTICAST_TTL:
2617 {
2618 sk->ip_mc_ttl=(int)ucval;
2619 return 0;
2620 }
2621 case IP_MULTICAST_LOOP:
2622 {
2623 if(ucval!=0 && ucval!=1)
2624 return -EINVAL;
2625 sk->ip_mc_loop=(int)ucval;
2626 return 0;
2627 }
2628 case IP_MULTICAST_IF:
2629 {
2630 struct in_addr addr;
2631 struct device *dev=NULL;
2632
2633
2634
2635
2636
2637 err=verify_area(VERIFY_READ, optval, sizeof(addr));
2638 if(err)
2639 return err;
2640
2641 memcpy_fromfs(&addr,optval,sizeof(addr));
2642
2643
2644
2645
2646
2647
2648 if(addr.s_addr==INADDR_ANY)
2649 {
2650 sk->ip_mc_name[0]=0;
2651 return 0;
2652 }
2653
2654
2655
2656
2657
2658 dev=ip_mc_find_devfor(addr.s_addr);
2659
2660
2661
2662
2663
2664 if(dev)
2665 {
2666 strcpy(sk->ip_mc_name,dev->name);
2667 return 0;
2668 }
2669 return -EADDRNOTAVAIL;
2670 }
2671
2672 case IP_ADD_MEMBERSHIP:
2673 {
2674
2675
2676
2677
2678 struct ip_mreq mreq;
2679 __u32 route_src;
2680 struct rtable *rt;
2681 struct device *dev=NULL;
2682
2683
2684
2685
2686
2687 err=verify_area(VERIFY_READ, optval, sizeof(mreq));
2688 if(err)
2689 return err;
2690
2691 memcpy_fromfs(&mreq,optval,sizeof(mreq));
2692
2693
2694
2695
2696
2697 if(mreq.imr_interface.s_addr==INADDR_ANY)
2698 {
2699
2700
2701
2702 if((rt=ip_rt_route(mreq.imr_multiaddr.s_addr,NULL, &route_src))!=NULL)
2703 {
2704 dev=rt->rt_dev;
2705 rt->rt_use--;
2706 }
2707 }
2708 else
2709 {
2710
2711
2712
2713
2714 dev=ip_mc_find_devfor(mreq.imr_interface.s_addr);
2715 }
2716
2717
2718
2719
2720
2721 if(!dev)
2722 return -ENODEV;
2723
2724
2725
2726
2727
2728 return ip_mc_join_group(sk,dev,mreq.imr_multiaddr.s_addr);
2729 }
2730
2731 case IP_DROP_MEMBERSHIP:
2732 {
2733 struct ip_mreq mreq;
2734 struct rtable *rt;
2735 __u32 route_src;
2736 struct device *dev=NULL;
2737
2738
2739
2740
2741
2742 err=verify_area(VERIFY_READ, optval, sizeof(mreq));
2743 if(err)
2744 return err;
2745
2746 memcpy_fromfs(&mreq,optval,sizeof(mreq));
2747
2748
2749
2750
2751
2752 if(mreq.imr_interface.s_addr==INADDR_ANY)
2753 {
2754 if((rt=ip_rt_route(mreq.imr_multiaddr.s_addr,NULL, &route_src))!=NULL)
2755 {
2756 dev=rt->rt_dev;
2757 rt->rt_use--;
2758 }
2759 }
2760 else
2761 {
2762
2763 dev=ip_mc_find_devfor(mreq.imr_interface.s_addr);
2764 }
2765
2766
2767
2768
2769
2770 if(!dev)
2771 return -ENODEV;
2772
2773
2774
2775
2776
2777 return ip_mc_leave_group(sk,dev,mreq.imr_multiaddr.s_addr);
2778 }
2779 #endif
2780 #ifdef CONFIG_IP_FIREWALL
2781 case IP_FW_ADD_BLK:
2782 case IP_FW_DEL_BLK:
2783 case IP_FW_ADD_FWD:
2784 case IP_FW_DEL_FWD:
2785 case IP_FW_CHK_BLK:
2786 case IP_FW_CHK_FWD:
2787 case IP_FW_FLUSH_BLK:
2788 case IP_FW_FLUSH_FWD:
2789 case IP_FW_ZERO_BLK:
2790 case IP_FW_ZERO_FWD:
2791 case IP_FW_POLICY_BLK:
2792 case IP_FW_POLICY_FWD:
2793 if(!suser())
2794 return -EPERM;
2795 if(optlen>sizeof(tmp_fw) || optlen<1)
2796 return -EINVAL;
2797 err=verify_area(VERIFY_READ,optval,optlen);
2798 if(err)
2799 return err;
2800 memcpy_fromfs(&tmp_fw,optval,optlen);
2801 err=ip_fw_ctl(optname, &tmp_fw,optlen);
2802 return -err;
2803
2804 #endif
2805 #ifdef CONFIG_IP_ACCT
2806 case IP_ACCT_DEL:
2807 case IP_ACCT_ADD:
2808 case IP_ACCT_FLUSH:
2809 case IP_ACCT_ZERO:
2810 if(!suser())
2811 return -EPERM;
2812 if(optlen>sizeof(tmp_fw) || optlen<1)
2813 return -EINVAL;
2814 err=verify_area(VERIFY_READ,optval,optlen);
2815 if(err)
2816 return err;
2817 memcpy_fromfs(&tmp_fw, optval,optlen);
2818 err=ip_acct_ctl(optname, &tmp_fw,optlen);
2819 return -err;
2820 #endif
2821
2822 default:
2823 return(-ENOPROTOOPT);
2824 }
2825 }
2826
2827
2828
2829
2830
2831
2832 int ip_getsockopt(struct sock *sk, int level, int optname, char *optval, int *optlen)
2833 {
2834 int val,err;
2835 #ifdef CONFIG_IP_MULTICAST
2836 int len;
2837 #endif
2838
2839 if(level!=SOL_IP)
2840 return -EOPNOTSUPP;
2841
2842 #ifdef CONFIG_IP_MROUTE
2843 if(optname>=MRT_BASE && optname <=MRT_BASE+10)
2844 {
2845 return ip_mroute_getsockopt(sk,optname,optval,optlen);
2846 }
2847 #endif
2848
2849 switch(optname)
2850 {
2851 case IP_OPTIONS:
2852 {
2853 unsigned char optbuf[sizeof(struct options)+40];
2854 struct options * opt = (struct options*)optbuf;
2855 err = verify_area(VERIFY_WRITE, optlen, sizeof(int));
2856 if (err)
2857 return err;
2858 cli();
2859 opt->optlen = 0;
2860 if (sk->opt)
2861 memcpy(optbuf, sk->opt, sizeof(struct options)+sk->opt->optlen);
2862 sti();
2863 if (opt->optlen == 0) {
2864 put_fs_long(0,(unsigned long *) optlen);
2865 return 0;
2866 }
2867 err = verify_area(VERIFY_WRITE, optval, opt->optlen);
2868 if (err)
2869 return err;
2870
2871
2872
2873 if (opt->srr) {
2874 unsigned char * optptr = opt->__data+opt->srr-sizeof(struct iphdr);
2875 memmove(optptr+7, optptr+4, optptr[1]-7);
2876 memcpy(optptr+3, &opt->faddr, 4);
2877 }
2878 if (opt->rr_needaddr) {
2879 unsigned char * optptr = opt->__data+opt->rr-sizeof(struct iphdr);
2880 memset(&optptr[optptr[2]-1], 0, 4);
2881 optptr[2] -= 4;
2882 }
2883 if (opt->ts) {
2884 unsigned char * optptr = opt->__data+opt->ts-sizeof(struct iphdr);
2885 if (opt->ts_needtime) {
2886 memset(&optptr[optptr[2]-1], 0, 4);
2887 optptr[2] -= 4;
2888 }
2889 if (opt->ts_needaddr) {
2890 memset(&optptr[optptr[2]-1], 0, 4);
2891 optptr[2] -= 4;
2892 }
2893 }
2894 put_fs_long(opt->optlen, (unsigned long *) optlen);
2895 memcpy_tofs(optval, opt->__data, opt->optlen);
2896 }
2897 return 0;
2898 case IP_TOS:
2899 val=sk->ip_tos;
2900 break;
2901 case IP_TTL:
2902 val=sk->ip_ttl;
2903 break;
2904 case IP_HDRINCL:
2905 val=sk->ip_hdrincl;
2906 break;
2907 #ifdef CONFIG_IP_MULTICAST
2908 case IP_MULTICAST_TTL:
2909 val=sk->ip_mc_ttl;
2910 break;
2911 case IP_MULTICAST_LOOP:
2912 val=sk->ip_mc_loop;
2913 break;
2914 case IP_MULTICAST_IF:
2915 err=verify_area(VERIFY_WRITE, optlen, sizeof(int));
2916 if(err)
2917 return err;
2918 len=strlen(sk->ip_mc_name);
2919 err=verify_area(VERIFY_WRITE, optval, len);
2920 if(err)
2921 return err;
2922 put_user(len,(int *) optlen);
2923 memcpy_tofs((void *)optval,sk->ip_mc_name, len);
2924 return 0;
2925 #endif
2926 default:
2927 return(-ENOPROTOOPT);
2928 }
2929 err=verify_area(VERIFY_WRITE, optlen, sizeof(int));
2930 if(err)
2931 return err;
2932 put_user(sizeof(int),(int *) optlen);
2933
2934 err=verify_area(VERIFY_WRITE, optval, sizeof(int));
2935 if(err)
2936 return err;
2937 put_user(val,(int *) optval);
2938
2939 return(0);
2940 }
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962 int ip_build_xmit(struct sock *sk,
2963 void getfrag (const void *,
2964 __u32,
2965 char *,
2966 unsigned int,
2967 unsigned int),
2968 const void *frag,
2969 unsigned short int length,
2970 __u32 daddr,
2971 __u32 user_saddr,
2972 struct options * opt,
2973 int flags,
2974 int type)
2975 {
2976 struct rtable *rt;
2977 unsigned int fraglen, maxfraglen, fragheaderlen;
2978 int offset, mf;
2979 __u32 saddr;
2980 unsigned short id;
2981 struct iphdr *iph;
2982 int local=0;
2983 struct device *dev;
2984 int nfrags=0;
2985 __u32 true_daddr = daddr;
2986
2987 if (opt && opt->srr && !sk->ip_hdrincl)
2988 daddr = opt->faddr;
2989
2990 ip_statistics.IpOutRequests++;
2991
2992 #ifdef CONFIG_IP_MULTICAST
2993 if(sk && MULTICAST(daddr) && *sk->ip_mc_name)
2994 {
2995 dev=dev_get(sk->ip_mc_name);
2996 if(!dev)
2997 return -ENODEV;
2998 rt=NULL;
2999 if (sk->saddr && (!LOOPBACK(sk->saddr) || LOOPBACK(daddr)))
3000 saddr = sk->saddr;
3001 else
3002 saddr = dev->pa_addr;
3003 }
3004 else
3005 {
3006 #endif
3007
3008
3009
3010
3011 if(sk->localroute || flags&MSG_DONTROUTE)
3012 local=1;
3013
3014 rt = sk->ip_route_cache;
3015
3016
3017
3018
3019
3020
3021 saddr=sk->ip_route_saddr;
3022 if(!rt || sk->ip_route_stamp != rt_stamp ||
3023 daddr!=sk->ip_route_daddr || sk->ip_route_local!=local ||
3024 (sk->saddr && sk->saddr != saddr))
3025 {
3026 if(local)
3027 rt = ip_rt_local(daddr, NULL, &saddr);
3028 else
3029 rt = ip_rt_route(daddr, NULL, &saddr);
3030 sk->ip_route_local=local;
3031 sk->ip_route_daddr=daddr;
3032 sk->ip_route_saddr=saddr;
3033 sk->ip_route_stamp=rt_stamp;
3034 sk->ip_route_cache=rt;
3035 sk->ip_hcache_ver=NULL;
3036 sk->ip_hcache_state= 0;
3037 }
3038 else if(rt)
3039 {
3040
3041
3042
3043
3044
3045
3046 if(rt->rt_dev->header_cache && sk->ip_hcache_state!= -1)
3047 {
3048 if(sk->ip_hcache_ver==NULL || sk->ip_hcache_stamp!=*sk->ip_hcache_ver)
3049 rt->rt_dev->header_cache(rt->rt_dev,sk,saddr,daddr);
3050 else
3051
3052 sk->ip_hcache_state= -1;
3053 }
3054 }
3055
3056 if (rt == NULL)
3057 {
3058 ip_statistics.IpOutNoRoutes++;
3059 return(-ENETUNREACH);
3060 }
3061
3062 if (sk->saddr && (!LOOPBACK(sk->saddr) || LOOPBACK(daddr)))
3063 saddr = sk->saddr;
3064
3065 dev=rt->rt_dev;
3066 #ifdef CONFIG_IP_MULTICAST
3067 }
3068 #endif
3069 if (user_saddr)
3070 saddr = user_saddr;
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081 length += 20;
3082 if (!sk->ip_hdrincl && opt) {
3083 length += opt->optlen;
3084 if (opt->is_strictroute && rt && rt->rt_gateway) {
3085 ip_statistics.IpOutNoRoutes++;
3086 return -ENETUNREACH;
3087 }
3088 }
3089 if(length <= dev->mtu && !MULTICAST(daddr) && daddr!=0xFFFFFFFF && daddr!=dev->pa_brdaddr)
3090 {
3091 int error;
3092 struct sk_buff *skb=sock_alloc_send_skb(sk, length+15+dev->hard_header_len,0, 0,&error);
3093 if(skb==NULL)
3094 {
3095 ip_statistics.IpOutDiscards++;
3096 return error;
3097 }
3098 skb->dev=dev;
3099 skb->free=1;
3100 skb->when=jiffies;
3101 skb->sk=sk;
3102 skb->arp=0;
3103 skb->saddr=saddr;
3104 skb->raddr=(rt&&rt->rt_gateway)?rt->rt_gateway:daddr;
3105 skb_reserve(skb,(dev->hard_header_len+15)&~15);
3106 if(sk->ip_hcache_state>0)
3107 {
3108 memcpy(skb_push(skb,dev->hard_header_len),sk->ip_hcache_data,dev->hard_header_len);
3109 skb->arp=1;
3110 }
3111 else if(dev->hard_header)
3112 {
3113 if(dev->hard_header(skb,dev,ETH_P_IP,NULL,NULL,0)>0)
3114 skb->arp=1;
3115 }
3116 else
3117 skb->arp=1;
3118 skb->ip_hdr=iph=(struct iphdr *)skb_put(skb,length);
3119 dev_lock_list();
3120 if(!sk->ip_hdrincl)
3121 {
3122 iph->version=4;
3123 iph->ihl=5;
3124 iph->tos=sk->ip_tos;
3125 iph->tot_len = htons(length);
3126 iph->id=htons(ip_id_count++);
3127 iph->frag_off = 0;
3128 iph->ttl=sk->ip_ttl;
3129 iph->protocol=type;
3130 iph->saddr=saddr;
3131 iph->daddr=daddr;
3132 if (opt) {
3133 iph->ihl += opt->optlen>>2;
3134 ip_options_build(skb, opt,
3135 true_daddr, dev->pa_addr, 0);
3136 }
3137 iph->check=0;
3138 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
3139 getfrag(frag,saddr,((char *)iph)+iph->ihl*4,0, length-iph->ihl*4);
3140 }
3141 else
3142 getfrag(frag,saddr,(void *)iph,0,length-20);
3143 dev_unlock_list();
3144 #ifdef CONFIG_IP_FIREWALL
3145 if(ip_fw_chk(iph, dev, ip_fw_blk_chain, ip_fw_blk_policy,0) < FW_ACCEPT)
3146 {
3147 kfree_skb(skb, FREE_WRITE);
3148 return -EPERM;
3149 }
3150 #endif
3151 #ifdef CONFIG_IP_ACCT
3152 ip_fw_chk((void *)skb->data,dev,ip_acct_chain, IP_FW_F_ACCEPT,1);
3153 #endif
3154 if(dev->flags&IFF_UP)
3155 dev_queue_xmit(skb,dev,sk->priority);
3156 else
3157 {
3158 ip_statistics.IpOutDiscards++;
3159 kfree_skb(skb, FREE_WRITE);
3160 }
3161 return 0;
3162 }
3163 length-=20;
3164 if (sk && !sk->ip_hdrincl && opt) {
3165 length -= opt->optlen;
3166 fragheaderlen = dev->hard_header_len + sizeof(struct iphdr) + opt->optlen;
3167 maxfraglen = ((dev->mtu-sizeof(struct iphdr)-opt->optlen) & ~7) + fragheaderlen;
3168 } else {
3169 fragheaderlen = dev->hard_header_len;
3170 if(!sk->ip_hdrincl)
3171 fragheaderlen += 20;
3172
3173
3174
3175
3176
3177
3178 maxfraglen = ((dev->mtu-20) & ~7) + fragheaderlen;
3179 }
3180
3181
3182
3183
3184
3185 offset = length - (length % (maxfraglen - fragheaderlen));
3186
3187
3188
3189
3190
3191 fraglen = length - offset + fragheaderlen;
3192
3193 if(length-offset==0)
3194 {
3195 fraglen = maxfraglen;
3196 offset -= maxfraglen-fragheaderlen;
3197 }
3198
3199
3200
3201
3202
3203
3204 mf = 0;
3205
3206
3207
3208
3209
3210 if (sk->ip_hdrincl && offset > 0)
3211 return(-EMSGSIZE);
3212
3213
3214
3215
3216
3217 dev_lock_list();
3218
3219
3220
3221
3222
3223 id = htons(ip_id_count++);
3224
3225
3226
3227
3228
3229 do
3230 {
3231 struct sk_buff * skb;
3232 int error;
3233 char *data;
3234
3235
3236
3237
3238
3239 skb = sock_alloc_send_skb(sk, fraglen+15, 0, 0, &error);
3240 if (skb == NULL)
3241 {
3242 ip_statistics.IpOutDiscards++;
3243 if(nfrags>1)
3244 ip_statistics.IpFragCreates++;
3245 dev_unlock_list();
3246 return(error);
3247 }
3248
3249
3250
3251
3252
3253 skb->next = skb->prev = NULL;
3254 skb->dev = dev;
3255 skb->when = jiffies;
3256 skb->free = 1;
3257 skb->sk = sk;
3258 skb->arp = 0;
3259 skb->saddr = saddr;
3260 skb->raddr = (rt&&rt->rt_gateway) ? rt->rt_gateway : daddr;
3261 skb_reserve(skb,(dev->hard_header_len+15)&~15);
3262 data = skb_put(skb, fraglen-dev->hard_header_len);
3263
3264
3265
3266
3267
3268
3269
3270
3271 if(sk->ip_hcache_state>0)
3272 {
3273 memcpy(skb_push(skb,dev->hard_header_len),sk->ip_hcache_data, dev->hard_header_len);
3274 skb->arp=1;
3275 }
3276 else if (dev->hard_header)
3277 {
3278 if(dev->hard_header(skb, dev, ETH_P_IP,
3279 NULL, NULL, 0)>0)
3280 skb->arp=1;
3281 }
3282
3283
3284
3285
3286
3287 skb->ip_hdr = iph = (struct iphdr *)data;
3288
3289
3290
3291
3292
3293 if(!sk->ip_hdrincl)
3294 {
3295
3296 iph->version = 4;
3297 iph->ihl = 5;
3298 if (opt) {
3299 iph->ihl += opt->optlen>>2;
3300 ip_options_build(skb, opt,
3301 true_daddr, dev->pa_addr, offset);
3302 }
3303 iph->tos = sk->ip_tos;
3304 iph->tot_len = htons(fraglen - fragheaderlen + iph->ihl*4);
3305 iph->id = id;
3306 iph->frag_off = htons(offset>>3);
3307 iph->frag_off |= mf;
3308 #ifdef CONFIG_IP_MULTICAST
3309 if (MULTICAST(daddr))
3310 iph->ttl = sk->ip_mc_ttl;
3311 else
3312 #endif
3313 iph->ttl = sk->ip_ttl;
3314 iph->protocol = type;
3315 iph->check = 0;
3316 iph->saddr = saddr;
3317 iph->daddr = daddr;
3318 iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
3319 data += iph->ihl*4;
3320
3321
3322
3323
3324
3325 mf = htons(IP_MF);
3326 }
3327
3328
3329
3330
3331
3332 getfrag(frag, saddr, data, offset, fraglen-fragheaderlen);
3333
3334
3335
3336
3337
3338 #ifdef CONFIG_IP_FIREWALL
3339 if(!offset && ip_fw_chk(iph, dev, ip_fw_blk_chain, ip_fw_blk_policy,0) < FW_ACCEPT)
3340 {
3341 kfree_skb(skb, FREE_WRITE);
3342 dev_unlock_list();
3343 return -EPERM;
3344 }
3345 #endif
3346 #ifdef CONFIG_IP_ACCT
3347 if(!offset)
3348 ip_fw_chk(iph, dev, ip_acct_chain, IP_FW_F_ACCEPT, 1);
3349 #endif
3350 offset -= (maxfraglen-fragheaderlen);
3351 fraglen = maxfraglen;
3352
3353 #ifdef CONFIG_IP_MULTICAST
3354
3355
3356
3357
3358
3359 if (MULTICAST(daddr) && !(dev->flags&IFF_LOOPBACK))
3360 {
3361
3362
3363
3364
3365
3366
3367
3368 if(sk==NULL || sk->ip_mc_loop)
3369 {
3370 if(skb->daddr==IGMP_ALL_HOSTS || (dev->flags&IFF_ALLMULTI))
3371 ip_loopback(rt?rt->rt_dev:dev,skb);
3372 else
3373 {
3374 struct ip_mc_list *imc=rt?rt->rt_dev->ip_mc_list:dev->ip_mc_list;
3375 while(imc!=NULL)
3376 {
3377 if(imc->multiaddr==daddr)
3378 {
3379 ip_loopback(rt?rt->rt_dev:dev,skb);
3380 break;
3381 }
3382 imc=imc->next;
3383 }
3384 }
3385 }
3386
3387
3388
3389
3390
3391
3392 if(skb->ip_hdr->ttl==0)
3393 kfree_skb(skb, FREE_READ);
3394 }
3395 #endif
3396
3397 nfrags++;
3398
3399
3400
3401
3402
3403 if((dev->flags&IFF_BROADCAST) && (daddr==0xFFFFFFFF || daddr==dev->pa_brdaddr) && !(dev->flags&IFF_LOOPBACK))
3404 ip_loopback(dev,skb);
3405
3406
3407
3408
3409
3410 if (dev->flags & IFF_UP)
3411 {
3412 dev_queue_xmit(skb, dev, sk->priority);
3413 }
3414 else
3415 {
3416
3417
3418
3419
3420 ip_statistics.IpOutDiscards++;
3421 if(nfrags>1)
3422 ip_statistics.IpFragCreates+=nfrags;
3423 kfree_skb(skb, FREE_WRITE);
3424 dev_unlock_list();
3425
3426
3427
3428 if(sk!=NULL)
3429 sk->err=ENETDOWN;
3430 return(0);
3431 }
3432 }
3433 while (offset >= 0);
3434 if(nfrags>1)
3435 ip_statistics.IpFragCreates+=nfrags;
3436 dev_unlock_list();
3437 return(0);
3438 }
3439
3440
3441
3442
3443
3444
3445 static struct packet_type ip_packet_type =
3446 {
3447 0,
3448 NULL,
3449 ip_rcv,
3450 NULL,
3451 NULL,
3452 };
3453
3454
3455
3456
3457
3458 static int ip_rt_event(unsigned long event, void *ptr)
3459 {
3460 if(event==NETDEV_DOWN)
3461 ip_rt_flush(ptr);
3462 return NOTIFY_DONE;
3463 }
3464
3465 struct notifier_block ip_rt_notifier={
3466 ip_rt_event,
3467 NULL,
3468 0
3469 };
3470
3471
3472
3473
3474
3475 void ip_init(void)
3476 {
3477 ip_packet_type.type=htons(ETH_P_IP);
3478 dev_add_pack(&ip_packet_type);
3479
3480
3481 register_netdevice_notifier(&ip_rt_notifier);
3482
3483
3484
3485
3486
3487
3488 #ifdef CONFIG_IP_MULTICAST
3489 proc_net_register(&(struct proc_dir_entry) {
3490 PROC_NET_IGMP, 4, "igmp",
3491 S_IFREG | S_IRUGO, 1, 0, 0,
3492 0, &proc_net_inode_operations,
3493 ip_mc_procinfo
3494 });
3495 #endif
3496 }
3497