1 /*
2  *	Extension Header handling for IPv6
3  *	Linux INET6 implementation
4  *
5  *	Authors:
6  *	Pedro Roque		<pedro_m@yahoo.com>
7  *	Andi Kleen		<ak@muc.de>
8  *	Alexey Kuznetsov	<kuznet@ms2.inr.ac.ru>
9  *
10  *	$Id: exthdrs.c,v 1.13 2001/06/19 15:58:56 davem Exp $
11  *
12  *	This program is free software; you can redistribute it and/or
13  *      modify it under the terms of the GNU General Public License
14  *      as published by the Free Software Foundation; either version
15  *      2 of the License, or (at your option) any later version.
16  */
17 
18 /* Changes:
19  *	yoshfuji		: ensure not to overrun while parsing
20  *				  tlv options.
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  *	Parsing inbound headers.
48  *
49  *	Parsing function "func" returns offset wrt skb->nh of the place,
50  *	where next nexthdr value is stored or NULL, if parsing
51  *	failed. It should also update skb->h tp point at the next header.
52  */
53 
54 struct hdrtype_proc
55 {
56 	int	type;
57 	int	(*func) (struct sk_buff **, int offset);
58 };
59 
60 /*
61  *	Parsing tlv encoded headers.
62  *
63  *	Parsing function "func" returns 1, if parsing succeed
64  *	and 0, if it failed.
65  *	It MUST NOT touch skb->h.
66  */
67 
68 struct tlvtype_proc
69 {
70 	int	type;
71 	int	(*func) (struct sk_buff *, int offset);
72 };
73 
74 /*********************
75   Generic functions
76  *********************/
77 
78 /* An unknown option is detected, decide what to do */
79 
ip6_tlvopt_unknown(struct sk_buff * skb,int optoff)80 int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff)
81 {
82 	switch ((skb->nh.raw[optoff] & 0xC0) >> 6) {
83 	case 0: /* ignore */
84 		return 1;
85 
86 	case 1: /* drop packet */
87 		break;
88 
89 	case 3: /* Send ICMP if not a multicast address and drop packet */
90 		/* Actually, it is redundant check. icmp_send
91 		   will recheck in any case.
92 		 */
93 		if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
94 			break;
95 	case 2: /* send ICMP PARM PROB regardless and drop packet */
96 		icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
97 		return 0;
98 	};
99 
100 	kfree_skb(skb);
101 	return 0;
102 }
103 
104 /* Parse tlv encoded option header (hop-by-hop or destination) */
105 
ip6_parse_tlv(struct tlvtype_proc * procs,struct sk_buff * skb)106 static 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: /* Other TLV code so scan list */
130 			if (optlen > len)
131 				goto bad;
132 			for (curr=procs; curr->type >= 0; curr++) {
133 				if (curr->type == skb->nh.raw[off]) {
134 					/* type specific length/alignment
135 					   checks will be perfomed in the
136 					   func(). */
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;
153 bad:
154 	kfree_skb(skb);
155 	return 0;
156 }
157 
158 /*****************************
159   Destination options header.
160  *****************************/
161 
162 struct tlvtype_proc tlvprocdestopt_lst[] = {
163 	/* No destination options are defined now */
164 	{-1,			NULL}
165 };
166 
ipv6_dest_opt(struct sk_buff ** skb_ptr,int nhoff)167 static 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   NONE header. No data in packet.
190  ********************************/
191 
ipv6_nodata(struct sk_buff ** skb_ptr,int nhoff)192 static int ipv6_nodata(struct sk_buff **skb_ptr, int nhoff)
193 {
194 	kfree_skb(*skb_ptr);
195 	return -1;
196 }
197 
198 /********************************
199   Routing header.
200  ********************************/
201 
ipv6_routing_header(struct sk_buff ** skb_ptr,int nhoff)202 static 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 
229 looped_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 	 *	This is the routing header forwarding algorithm from
250 	 *	RFC 1883, page 17.
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 	/* We are about to mangle packet header. Be careful!
261 	   Do not damage packets queued somewhere.
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    This function inverts received rthdr.
319    NOTE: specs allow to make it automatically only if
320    packet authenticated.
321 
322    I will not discuss it here (though, I am really pissed off at
323    this stupid requirement making rthdr idea useless)
324 
325    Actually, it creates severe problems  for us.
326    Embrionic requests has no associated sockets,
327    so that user have no control over it and
328    cannot not only to set reply options, but
329    even to know, that someone wants to connect
330    without success. :-(
331 
332    For now we need to test the engine, so that I created
333    temporary (or permanent) backdoor.
334    If listening socket set IPV6_RTHDR to 2, then we invert header.
335                                                    --ANK (980729)
336  */
337 
338 struct ipv6_txoptions *
ipv6_invert_rthdr(struct sock * sk,struct ipv6_rt_hdr * hdr)339 ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
340 {
341 	/* Received rthdr:
342 
343 	   [ H1 -> H2 -> ... H_prev ]  daddr=ME
344 
345 	   Inverted result:
346 	   [ H_prev -> ... -> H1 ] daddr =sender
347 
348 	   Note, that IP output engine will rewrire this rthdr
349 	   by rotating it left by one addr.
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 	/* Obsolete field, MBZ, when originated by us */
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   AUTH header.
384  ********************************/
385 
386 /*
387    rfc1826 said, that if a host does not implement AUTH header
388    it MAY ignore it. We use this hole 8)
389 
390    Actually, now we can implement OSPFv6 without kernel IPsec.
391    Authentication for poors may be done in user space with the same success.
392 
393    Yes, it means, that we allow application to send/receive
394    raw authentication header. Apparently, we suppose, that it knows
395    what it does and calculates authentication data correctly.
396    Certainly, it is possible only for udp and raw sockets, but not for tcp.
397 
398    AUTH header has 4byte granular length, which kills all the idea
399    behind AUTOMATIC 64bit alignment of IPv6. Now we will lose
400    cpu ticks, checking that sender did not something stupid
401    and opt->hdrlen is even. Shit!		--ANK (980730)
402  */
403 
ipv6_auth_hdr(struct sk_buff ** skb_ptr,int nhoff)404 static 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 	 * RFC2402 2.2 Payload Length
415 	 * The 8-bit field specifies the length of AH in 32-bit words
416 	 * (4-byte units), minus "2".
417 	 * -- Noriaki Takamiya @USAGI Project
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 
431 fail:
432 	kfree_skb(skb);
433 	return -1;
434 }
435 
436 /* This list MUST NOT contain entry for NEXTHDR_HOP.
437    It is parsed immediately after packet received
438    and if it occurs somewhere in another place we must
439    generate error.
440  */
441 
442 struct 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 	{NEXTHDR_ESP,		ipv6_esp_hdr},
450     */
451 	{-1,			NULL}
452 };
453 
ipv6_parse_exthdrs(struct sk_buff ** skb_in,int nhoff)454 int 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 
459 restart:
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   Hop-by-hop options.
475  **********************************/
476 
477 /* Router Alert as of draft-ietf-ipngwg-ipv6router-alert-04 */
478 
ipv6_hop_ra(struct sk_buff * skb,int optoff)479 static 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 /* Jumbo payload */
492 
ipv6_hop_jumbo(struct sk_buff * skb,int optoff)493 static 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 
524 drop:
525 	kfree_skb(skb);
526 	return 0;
527 }
528 
529 struct tlvtype_proc tlvprochopopt_lst[] = {
530 	{IPV6_TLV_ROUTERALERT,	ipv6_hop_ra},
531 	{IPV6_TLV_JUMBO,	ipv6_hop_jumbo},
532 	{-1,			NULL}
533 };
534 
ipv6_parse_hopopts(struct sk_buff * skb,int nhoff)535 int 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  *	Creating outbound headers.
545  *
546  *	"build" functions work when skb is filled from head to tail (datagram)
547  *	"push"	functions work when headers are added from tail to head (tcp)
548  *
549  *	In both cases we assume, that caller reserved enough room
550  *	for headers.
551  */
552 
ipv6_build_rthdr(struct sk_buff * skb,u8 * prev_hdr,struct ipv6_rt_hdr * opt,struct in6_addr * addr)553 u8 *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 
ipv6_build_exthdr(struct sk_buff * skb,u8 * prev_hdr,u8 type,struct ipv6_opt_hdr * opt)577 static 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 
ipv6_build_authhdr(struct sk_buff * skb,u8 * prev_hdr,struct ipv6_opt_hdr * opt)587 static 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 
ipv6_build_nfrag_opts(struct sk_buff * skb,u8 * prev_hdr,struct ipv6_txoptions * opt,struct in6_addr * daddr,u32 jumbolen)598 u8 *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 
ipv6_build_frag_opts(struct sk_buff * skb,u8 * prev_hdr,struct ipv6_txoptions * opt)634 u8 *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 
ipv6_push_rthdr(struct sk_buff * skb,u8 * proto,struct ipv6_rt_hdr * opt,struct in6_addr ** addr_p)643 static 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 
ipv6_push_exthdr(struct sk_buff * skb,u8 * proto,u8 type,struct ipv6_opt_hdr * opt)668 static 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 
ipv6_push_authhdr(struct sk_buff * skb,u8 * proto,struct ipv6_opt_hdr * opt)677 static 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 
ipv6_push_nfrag_opts(struct sk_buff * skb,struct ipv6_txoptions * opt,u8 * proto,struct in6_addr ** daddr)686 void 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 
ipv6_push_frag_opts(struct sk_buff * skb,struct ipv6_txoptions * opt,u8 * proto)698 void 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 
706 struct ipv6_txoptions *
ipv6_dup_options(struct sock * sk,struct ipv6_txoptions * opt)707 ipv6_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  * find out if nexthdr is a well-known extension header or a protocol
732  */
733 
ipv6_ext_hdr(u8 nexthdr)734 int ipv6_ext_hdr(u8 nexthdr)
735 {
736 	/*
737 	 * find out if nexthdr is an extension header or a protocol
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  * Skip any extension headers. This is used by the ICMP module.
749  *
750  * Note that strictly speaking this conflicts with RFC1883 4.0:
751  * ...The contents and semantics of each extension header determine whether
752  * or not to proceed to the next header.  Therefore, extension headers must
753  * be processed strictly in the order they appear in the packet; a
754  * receiver must not, for example, scan through a packet looking for a
755  * particular kind of extension header and process that header prior to
756  * processing all preceding ones.
757  *
758  * We do exactly this. This is a protocol bug. We can't decide after a
759  * seeing an unknown discard-with-error flavour TLV option if it's a
760  * ICMP error message or not (errors should never be send in reply to
761  * ICMP error messages).
762  *
763  * But I see no other way to do this. This might need to be reexamined
764  * when Linux implements ESP (and maybe AUTH) headers.
765  * --AK
766  *
767  * This function parses (probably truncated) exthdr set "hdr"
768  * of length "len". "nexthdrp" initially points to some place,
769  * where type of the first header can be found.
770  *
771  * It skips all well-known exthdrs, and returns pointer to the start
772  * of unparsable area i.e. the first header with unknown type.
773  * If it is not NULL *nexthdr is updated by type/protocol of this header.
774  *
775  * NOTES: - if packet terminated with NEXTHDR_NONE it returns NULL.
776  *        - it may return pointer pointing beyond end of packet,
777  *	    if the last recognized header is truncated in the middle.
778  *        - if packet is truncated, so that all parsed headers are skipped,
779  *	    it returns NULL.
780  *	  - First fragment header is skipped, not-first ones
781  *	    are considered as unparsable.
782  *	  - ESP is unparsable for now and considered like
783  *	    normal payload protocol.
784  *	  - Note also special handling of AUTH header. Thanks to IPsec wizards.
785  *
786  * --ANK (980726)
787  */
788 
ipv6_skip_exthdr(const struct sk_buff * skb,int start,u8 * nexthdrp,int len)789 int 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