1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include <linux/errno.h>
24#include <linux/types.h>
25#include <linux/socket.h>
26#include <linux/sockios.h>
27#include <linux/sched.h>
28#include <linux/net.h>
29#include <linux/netdevice.h>
30#include <linux/in6.h>
31#include <linux/icmpv6.h>
32
33#include <net/sock.h>
34#include <net/snmp.h>
35
36#include <net/ipv6.h>
37#include <net/protocol.h>
38#include <net/transp_v6.h>
39#include <net/rawv6.h>
40#include <net/ndisc.h>
41#include <net/ip6_route.h>
42#include <net/addrconf.h>
43
44#include <asm/uaccess.h>
45
46
47
48
49
50
51
52
53
54struct hdrtype_proc
55{
56 int type;
57 int (*func) (struct sk_buff **, int offset);
58};
59
60
61
62
63
64
65
66
67
68struct tlvtype_proc
69{
70 int type;
71 int (*func) (struct sk_buff *, int offset);
72};
73
74
75
76
77
78
79
80int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff)
81{
82 switch ((skb->nh.raw[optoff] & 0xC0) >> 6) {
83 case 0:
84 return 1;
85
86 case 1:
87 break;
88
89 case 3:
90
91
92
93 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
94 break;
95 case 2:
96 icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
97 return 0;
98 };
99
100 kfree_skb(skb);
101 return 0;
102}
103
104
105
106static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff *skb)
107{
108 struct tlvtype_proc *curr;
109 int off = skb->h.raw - skb->nh.raw;
110 int len = ((skb->h.raw[1]+1)<<3);
111
112 if ((skb->h.raw + len) - skb->data > skb_headlen(skb))
113 goto bad;
114
115 off += 2;
116 len -= 2;
117
118 while (len > 0) {
119 int optlen = skb->nh.raw[off+1]+2;
120
121 switch (skb->nh.raw[off]) {
122 case IPV6_TLV_PAD0:
123 optlen = 1;
124 break;
125
126 case IPV6_TLV_PADN:
127 break;
128
129 default:
130 if (optlen > len)
131 goto bad;
132 for (curr=procs; curr->type >= 0; curr++) {
133 if (curr->type == skb->nh.raw[off]) {
134
135
136
137 if (curr->func(skb, off) == 0)
138 return 0;
139 break;
140 }
141 }
142 if (curr->type < 0) {
143 if (ip6_tlvopt_unknown(skb, off) == 0)
144 return 0;
145 }
146 break;
147 }
148 off += optlen;
149 len -= optlen;
150 }
151 if (len == 0)
152 return 1;
153bad:
154 kfree_skb(skb);
155 return 0;
156}
157
158
159
160
161
162struct tlvtype_proc tlvprocdestopt_lst[] = {
163
164 {-1, NULL}
165};
166
167static int ipv6_dest_opt(struct sk_buff **skb_ptr, int nhoff)
168{
169 struct sk_buff *skb=*skb_ptr;
170 struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
171
172 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
173 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
174 kfree_skb(skb);
175 return -1;
176 }
177
178 opt->dst1 = skb->h.raw - skb->nh.raw;
179
180 if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
181 skb->h.raw += ((skb->h.raw[1]+1)<<3);
182 return opt->dst1;
183 }
184
185 return -1;
186}
187
188
189
190
191
192static int ipv6_nodata(struct sk_buff **skb_ptr, int nhoff)
193{
194 kfree_skb(*skb_ptr);
195 return -1;
196}
197
198
199
200
201
202static int ipv6_routing_header(struct sk_buff **skb_ptr, int nhoff)
203{
204 struct sk_buff *skb = *skb_ptr;
205 struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
206 struct in6_addr *addr;
207 struct in6_addr daddr;
208 int addr_type;
209 int n, i;
210
211 struct ipv6_rt_hdr *hdr;
212 struct rt0_hdr *rthdr;
213
214 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
215 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
216 IP6_INC_STATS_BH(Ip6InHdrErrors);
217 kfree_skb(skb);
218 return -1;
219 }
220
221 hdr = (struct ipv6_rt_hdr *) skb->h.raw;
222
223 if ((ipv6_addr_type(&skb->nh.ipv6h->daddr)&IPV6_ADDR_MULTICAST) ||
224 skb->pkt_type != PACKET_HOST) {
225 kfree_skb(skb);
226 return -1;
227 }
228
229looped_back:
230 if (hdr->segments_left == 0) {
231 opt->srcrt = skb->h.raw - skb->nh.raw;
232 skb->h.raw += (hdr->hdrlen + 1) << 3;
233 opt->dst0 = opt->dst1;
234 opt->dst1 = 0;
235 return (&hdr->nexthdr) - skb->nh.raw;
236 }
237
238 if (hdr->type != IPV6_SRCRT_TYPE_0) {
239 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
240 return -1;
241 }
242
243 if (hdr->hdrlen & 0x01) {
244 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
245 return -1;
246 }
247
248
249
250
251
252
253 n = hdr->hdrlen >> 1;
254
255 if (hdr->segments_left > n) {
256 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
257 return -1;
258 }
259
260
261
262
263 if (skb_cloned(skb)) {
264 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
265 kfree_skb(skb);
266 if (skb2 == NULL)
267 return -1;
268 *skb_ptr = skb = skb2;
269 opt = (struct inet6_skb_parm *)skb2->cb;
270 hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
271 }
272
273 if (skb->ip_summed == CHECKSUM_HW)
274 skb->ip_summed = CHECKSUM_NONE;
275
276 i = n - --hdr->segments_left;
277
278 rthdr = (struct rt0_hdr *) hdr;
279 addr = rthdr->addr;
280 addr += i - 1;
281
282 addr_type = ipv6_addr_type(addr);
283
284 if (addr_type&IPV6_ADDR_MULTICAST) {
285 kfree_skb(skb);
286 return -1;
287 }
288
289 ipv6_addr_copy(&daddr, addr);
290 ipv6_addr_copy(addr, &skb->nh.ipv6h->daddr);
291 ipv6_addr_copy(&skb->nh.ipv6h->daddr, &daddr);
292
293 dst_release(xchg(&skb->dst, NULL));
294 ip6_route_input(skb);
295 if (skb->dst->error) {
296 skb_push(skb, skb->data - skb->nh.raw);
297 skb->dst->input(skb);
298 return -1;
299 }
300
301 if (skb->dst->dev->flags&IFF_LOOPBACK) {
302 if (skb->nh.ipv6h->hop_limit <= 1) {
303 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
304 0, skb->dev);
305 kfree_skb(skb);
306 return -1;
307 }
308 skb->nh.ipv6h->hop_limit--;
309 goto looped_back;
310 }
311
312 skb_push(skb, skb->data - skb->nh.raw);
313 skb->dst->input(skb);
314 return -1;
315}
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338struct ipv6_txoptions *
339ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
340{
341
342
343
344
345
346
347
348
349
350
351
352 int n, i;
353 struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
354 struct rt0_hdr *irthdr;
355 struct ipv6_txoptions *opt;
356 int hdrlen = ipv6_optlen(hdr);
357
358 if (hdr->segments_left ||
359 hdr->type != IPV6_SRCRT_TYPE_0 ||
360 hdr->hdrlen & 0x01)
361 return NULL;
362
363 n = hdr->hdrlen >> 1;
364 opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
365 if (opt == NULL)
366 return NULL;
367 memset(opt, 0, sizeof(*opt));
368 opt->tot_len = sizeof(*opt) + hdrlen;
369 opt->srcrt = (void*)(opt+1);
370 opt->opt_nflen = hdrlen;
371
372 memcpy(opt->srcrt, hdr, sizeof(*hdr));
373 irthdr = (struct rt0_hdr*)opt->srcrt;
374
375 irthdr->bitmap = 0;
376 opt->srcrt->segments_left = n;
377 for (i=0; i<n; i++)
378 memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
379 return opt;
380}
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404static int ipv6_auth_hdr(struct sk_buff **skb_ptr, int nhoff)
405{
406 struct sk_buff *skb=*skb_ptr;
407 struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
408 int len;
409
410 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8))
411 goto fail;
412
413
414
415
416
417
418
419 len = (skb->h.raw[1]+2)<<2;
420
421 if (len&7)
422 goto fail;
423
424 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+len))
425 goto fail;
426
427 opt->auth = skb->h.raw - skb->nh.raw;
428 skb->h.raw += len;
429 return opt->auth;
430
431fail:
432 kfree_skb(skb);
433 return -1;
434}
435
436
437
438
439
440
441
442struct hdrtype_proc hdrproc_lst[] = {
443 {NEXTHDR_FRAGMENT, ipv6_reassembly},
444 {NEXTHDR_ROUTING, ipv6_routing_header},
445 {NEXTHDR_DEST, ipv6_dest_opt},
446 {NEXTHDR_NONE, ipv6_nodata},
447 {NEXTHDR_AUTH, ipv6_auth_hdr},
448
449
450
451 {-1, NULL}
452};
453
454int ipv6_parse_exthdrs(struct sk_buff **skb_in, int nhoff)
455{
456 struct hdrtype_proc *hdrt;
457 u8 nexthdr = (*skb_in)->nh.raw[nhoff];
458
459restart:
460 for (hdrt=hdrproc_lst; hdrt->type >= 0; hdrt++) {
461 if (hdrt->type == nexthdr) {
462 if ((nhoff = hdrt->func(skb_in, nhoff)) >= 0) {
463 nexthdr = (*skb_in)->nh.raw[nhoff];
464 goto restart;
465 }
466 return -1;
467 }
468 }
469 return nhoff;
470}
471
472
473
474
475
476
477
478
479static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
480{
481 if (skb->nh.raw[optoff+1] == 2) {
482 ((struct inet6_skb_parm*)skb->cb)->ra = optoff;
483 return 1;
484 }
485 if (net_ratelimit())
486 printk(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n", skb->nh.raw[optoff+1]);
487 kfree_skb(skb);
488 return 0;
489}
490
491
492
493static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
494{
495 u32 pkt_len;
496
497 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
498 if (net_ratelimit())
499 printk(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", skb->nh.raw[optoff+1]);
500 goto drop;
501 }
502
503 pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2));
504 if (pkt_len < 0x10000) {
505 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
506 return 0;
507 }
508 if (skb->nh.ipv6h->payload_len) {
509 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
510 return 0;
511 }
512
513 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
514 IP6_INC_STATS_BH(Ip6InTruncatedPkts);
515 goto drop;
516 }
517 if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
518 __pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr));
519 if (skb->ip_summed == CHECKSUM_HW)
520 skb->ip_summed = CHECKSUM_NONE;
521 }
522 return 1;
523
524drop:
525 kfree_skb(skb);
526 return 0;
527}
528
529struct tlvtype_proc tlvprochopopt_lst[] = {
530 {IPV6_TLV_ROUTERALERT, ipv6_hop_ra},
531 {IPV6_TLV_JUMBO, ipv6_hop_jumbo},
532 {-1, NULL}
533};
534
535int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff)
536{
537 ((struct inet6_skb_parm*)skb->cb)->hop = sizeof(struct ipv6hdr);
538 if (ip6_parse_tlv(tlvprochopopt_lst, skb))
539 return sizeof(struct ipv6hdr);
540 return -1;
541}
542
543
544
545
546
547
548
549
550
551
552
553u8 *ipv6_build_rthdr(struct sk_buff *skb, u8 *prev_hdr,
554 struct ipv6_rt_hdr *opt, struct in6_addr *addr)
555{
556 struct rt0_hdr *phdr, *ihdr;
557 int hops;
558
559 ihdr = (struct rt0_hdr *) opt;
560
561 phdr = (struct rt0_hdr *) skb_put(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
562 memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
563
564 hops = ihdr->rt_hdr.hdrlen >> 1;
565
566 if (hops > 1)
567 memcpy(phdr->addr, ihdr->addr + 1,
568 (hops - 1) * sizeof(struct in6_addr));
569
570 ipv6_addr_copy(phdr->addr + (hops - 1), addr);
571
572 phdr->rt_hdr.nexthdr = *prev_hdr;
573 *prev_hdr = NEXTHDR_ROUTING;
574 return &phdr->rt_hdr.nexthdr;
575}
576
577static u8 *ipv6_build_exthdr(struct sk_buff *skb, u8 *prev_hdr, u8 type, struct ipv6_opt_hdr *opt)
578{
579 struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_put(skb, ipv6_optlen(opt));
580
581 memcpy(h, opt, ipv6_optlen(opt));
582 h->nexthdr = *prev_hdr;
583 *prev_hdr = type;
584 return &h->nexthdr;
585}
586
587static u8 *ipv6_build_authhdr(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_opt_hdr *opt)
588{
589 struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_put(skb, (opt->hdrlen+2)<<2);
590
591 memcpy(h, opt, (opt->hdrlen+2)<<2);
592 h->nexthdr = *prev_hdr;
593 *prev_hdr = NEXTHDR_AUTH;
594 return &h->nexthdr;
595}
596
597
598u8 *ipv6_build_nfrag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptions *opt,
599 struct in6_addr *daddr, u32 jumbolen)
600{
601 struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb->data;
602
603 if (opt && opt->hopopt)
604 prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_HOP, opt->hopopt);
605
606 if (jumbolen) {
607 u8 *jumboopt = (u8 *)skb_put(skb, 8);
608
609 if (opt && opt->hopopt) {
610 *jumboopt++ = IPV6_TLV_PADN;
611 *jumboopt++ = 0;
612 h->hdrlen++;
613 } else {
614 h = (struct ipv6_opt_hdr *)jumboopt;
615 h->nexthdr = *prev_hdr;
616 h->hdrlen = 0;
617 jumboopt += 2;
618 *prev_hdr = NEXTHDR_HOP;
619 prev_hdr = &h->nexthdr;
620 }
621 jumboopt[0] = IPV6_TLV_JUMBO;
622 jumboopt[1] = 4;
623 *(u32*)(jumboopt+2) = htonl(jumbolen);
624 }
625 if (opt) {
626 if (opt->dst0opt)
627 prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst0opt);
628 if (opt->srcrt)
629 prev_hdr = ipv6_build_rthdr(skb, prev_hdr, opt->srcrt, daddr);
630 }
631 return prev_hdr;
632}
633
634u8 *ipv6_build_frag_opts(struct sk_buff *skb, u8 *prev_hdr, struct ipv6_txoptions *opt)
635{
636 if (opt->auth)
637 prev_hdr = ipv6_build_authhdr(skb, prev_hdr, opt->auth);
638 if (opt->dst1opt)
639 prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst1opt);
640 return prev_hdr;
641}
642
643static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
644 struct ipv6_rt_hdr *opt,
645 struct in6_addr **addr_p)
646{
647 struct rt0_hdr *phdr, *ihdr;
648 int hops;
649
650 ihdr = (struct rt0_hdr *) opt;
651
652 phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
653 memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
654
655 hops = ihdr->rt_hdr.hdrlen >> 1;
656
657 if (hops > 1)
658 memcpy(phdr->addr, ihdr->addr + 1,
659 (hops - 1) * sizeof(struct in6_addr));
660
661 ipv6_addr_copy(phdr->addr + (hops - 1), *addr_p);
662 *addr_p = ihdr->addr;
663
664 phdr->rt_hdr.nexthdr = *proto;
665 *proto = NEXTHDR_ROUTING;
666}
667
668static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
669{
670 struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
671
672 memcpy(h, opt, ipv6_optlen(opt));
673 h->nexthdr = *proto;
674 *proto = type;
675}
676
677static void ipv6_push_authhdr(struct sk_buff *skb, u8 *proto, struct ipv6_opt_hdr *opt)
678{
679 struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, (opt->hdrlen+2)<<2);
680
681 memcpy(h, opt, (opt->hdrlen+2)<<2);
682 h->nexthdr = *proto;
683 *proto = NEXTHDR_AUTH;
684}
685
686void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
687 u8 *proto,
688 struct in6_addr **daddr)
689{
690 if (opt->srcrt)
691 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
692 if (opt->dst0opt)
693 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
694 if (opt->hopopt)
695 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
696}
697
698void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
699{
700 if (opt->dst1opt)
701 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
702 if (opt->auth)
703 ipv6_push_authhdr(skb, proto, opt->auth);
704}
705
706struct ipv6_txoptions *
707ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
708{
709 struct ipv6_txoptions *opt2;
710
711 opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
712 if (opt2) {
713 long dif = (char*)opt2 - (char*)opt;
714 memcpy(opt2, opt, opt->tot_len);
715 if (opt2->hopopt)
716 *((char**)&opt2->hopopt) += dif;
717 if (opt2->dst0opt)
718 *((char**)&opt2->dst0opt) += dif;
719 if (opt2->dst1opt)
720 *((char**)&opt2->dst1opt) += dif;
721 if (opt2->auth)
722 *((char**)&opt2->auth) += dif;
723 if (opt2->srcrt)
724 *((char**)&opt2->srcrt) += dif;
725 }
726 return opt2;
727}
728
729
730
731
732
733
734int ipv6_ext_hdr(u8 nexthdr)
735{
736
737
738
739 return ( (nexthdr == NEXTHDR_HOP) ||
740 (nexthdr == NEXTHDR_ROUTING) ||
741 (nexthdr == NEXTHDR_FRAGMENT) ||
742 (nexthdr == NEXTHDR_AUTH) ||
743 (nexthdr == NEXTHDR_NONE) ||
744 (nexthdr == NEXTHDR_DEST) );
745}
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp, int len)
790{
791 u8 nexthdr = *nexthdrp;
792
793 while (ipv6_ext_hdr(nexthdr)) {
794 struct ipv6_opt_hdr hdr;
795 int hdrlen;
796
797 if (len < (int)sizeof(struct ipv6_opt_hdr))
798 return -1;
799 if (nexthdr == NEXTHDR_NONE)
800 return -1;
801 if (skb_copy_bits(skb, start, &hdr, sizeof(hdr)))
802 BUG();
803 if (nexthdr == NEXTHDR_FRAGMENT) {
804 unsigned short frag_off;
805 if (skb_copy_bits(skb,
806 start+offsetof(struct frag_hdr,
807 frag_off),
808 &frag_off,
809 sizeof(frag_off))) {
810 return -1;
811 }
812
813 if (ntohs(frag_off) & ~0x7)
814 break;
815 hdrlen = 8;
816 } else if (nexthdr == NEXTHDR_AUTH)
817 hdrlen = (hdr.hdrlen+2)<<2;
818 else
819 hdrlen = ipv6_optlen(&hdr);
820
821 nexthdr = hdr.nexthdr;
822 len -= hdrlen;
823 start += hdrlen;
824 }
825
826 *nexthdrp = nexthdr;
827 return start;
828}
829
830