Merge /spare/repo/linux-2.6/
[linux-2.6] / net / ipv6 / exthdrs.c
1 /*
2  *      Extension Header handling for IPv6
3  *      Linux INET6 implementation
4  *
5  *      Authors:
6  *      Pedro Roque             <roque@di.fc.ul.pt>
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  *      Mitsuru KANDA @USAGI and: Remove ipv6_parse_exthdrs().
22  *      YOSHIFUJI Hideaki @USAGI  Register inbound extension header
23  *                                handlers as inet6_protocol{}.
24  */
25
26 #include <linux/errno.h>
27 #include <linux/types.h>
28 #include <linux/socket.h>
29 #include <linux/sockios.h>
30 #include <linux/sched.h>
31 #include <linux/net.h>
32 #include <linux/netdevice.h>
33 #include <linux/in6.h>
34 #include <linux/icmpv6.h>
35
36 #include <net/sock.h>
37 #include <net/snmp.h>
38
39 #include <net/ipv6.h>
40 #include <net/protocol.h>
41 #include <net/transp_v6.h>
42 #include <net/rawv6.h>
43 #include <net/ndisc.h>
44 #include <net/ip6_route.h>
45 #include <net/addrconf.h>
46
47 #include <asm/uaccess.h>
48
49 /*
50  *      Parsing tlv encoded headers.
51  *
52  *      Parsing function "func" returns 1, if parsing succeed
53  *      and 0, if it failed.
54  *      It MUST NOT touch skb->h.
55  */
56
57 struct tlvtype_proc {
58         int     type;
59         int     (*func)(struct sk_buff *skb, int offset);
60 };
61
62 /*********************
63   Generic functions
64  *********************/
65
66 /* An unknown option is detected, decide what to do */
67
68 static int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff)
69 {
70         switch ((skb->nh.raw[optoff] & 0xC0) >> 6) {
71         case 0: /* ignore */
72                 return 1;
73
74         case 1: /* drop packet */
75                 break;
76
77         case 3: /* Send ICMP if not a multicast address and drop packet */
78                 /* Actually, it is redundant check. icmp_send
79                    will recheck in any case.
80                  */
81                 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr))
82                         break;
83         case 2: /* send ICMP PARM PROB regardless and drop packet */
84                 icmpv6_param_prob(skb, ICMPV6_UNK_OPTION, optoff);
85                 return 0;
86         };
87
88         kfree_skb(skb);
89         return 0;
90 }
91
92 /* Parse tlv encoded option header (hop-by-hop or destination) */
93
94 static int ip6_parse_tlv(struct tlvtype_proc *procs, struct sk_buff *skb)
95 {
96         struct tlvtype_proc *curr;
97         int off = skb->h.raw - skb->nh.raw;
98         int len = ((skb->h.raw[1]+1)<<3);
99
100         if ((skb->h.raw + len) - skb->data > skb_headlen(skb))
101                 goto bad;
102
103         off += 2;
104         len -= 2;
105
106         while (len > 0) {
107                 int optlen = skb->nh.raw[off+1]+2;
108
109                 switch (skb->nh.raw[off]) {
110                 case IPV6_TLV_PAD0:
111                         optlen = 1;
112                         break;
113
114                 case IPV6_TLV_PADN:
115                         break;
116
117                 default: /* Other TLV code so scan list */
118                         if (optlen > len)
119                                 goto bad;
120                         for (curr=procs; curr->type >= 0; curr++) {
121                                 if (curr->type == skb->nh.raw[off]) {
122                                         /* type specific length/alignment 
123                                            checks will be performed in the 
124                                            func(). */
125                                         if (curr->func(skb, off) == 0)
126                                                 return 0;
127                                         break;
128                                 }
129                         }
130                         if (curr->type < 0) {
131                                 if (ip6_tlvopt_unknown(skb, off) == 0)
132                                         return 0;
133                         }
134                         break;
135                 }
136                 off += optlen;
137                 len -= optlen;
138         }
139         if (len == 0)
140                 return 1;
141 bad:
142         kfree_skb(skb);
143         return 0;
144 }
145
146 /*****************************
147   Destination options header.
148  *****************************/
149
150 static struct tlvtype_proc tlvprocdestopt_lst[] = {
151         /* No destination options are defined now */
152         {-1,                    NULL}
153 };
154
155 static int ipv6_destopt_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
156 {
157         struct sk_buff *skb = *skbp;
158         struct inet6_skb_parm *opt = IP6CB(skb);
159
160         if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
161             !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
162                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
163                 kfree_skb(skb);
164                 return -1;
165         }
166
167         opt->dst1 = skb->h.raw - skb->nh.raw;
168
169         if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) {
170                 skb->h.raw += ((skb->h.raw[1]+1)<<3);
171                 *nhoffp = opt->dst1;
172                 return 1;
173         }
174
175         IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
176         return -1;
177 }
178
179 static struct inet6_protocol destopt_protocol = {
180         .handler        =       ipv6_destopt_rcv,
181         .flags          =       INET6_PROTO_NOPOLICY,
182 };
183
184 void __init ipv6_destopt_init(void)
185 {
186         if (inet6_add_protocol(&destopt_protocol, IPPROTO_DSTOPTS) < 0)
187                 printk(KERN_ERR "ipv6_destopt_init: Could not register protocol\n");
188 }
189
190 /********************************
191   NONE header. No data in packet.
192  ********************************/
193
194 static int ipv6_nodata_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
195 {
196         struct sk_buff *skb = *skbp;
197
198         kfree_skb(skb);
199         return 0;
200 }
201
202 static struct inet6_protocol nodata_protocol = {
203         .handler        =       ipv6_nodata_rcv,
204         .flags          =       INET6_PROTO_NOPOLICY,
205 };
206
207 void __init ipv6_nodata_init(void)
208 {
209         if (inet6_add_protocol(&nodata_protocol, IPPROTO_NONE) < 0)
210                 printk(KERN_ERR "ipv6_nodata_init: Could not register protocol\n");
211 }
212
213 /********************************
214   Routing header.
215  ********************************/
216
217 static int ipv6_rthdr_rcv(struct sk_buff **skbp, unsigned int *nhoffp)
218 {
219         struct sk_buff *skb = *skbp;
220         struct inet6_skb_parm *opt = IP6CB(skb);
221         struct in6_addr *addr;
222         struct in6_addr daddr;
223         int n, i;
224
225         struct ipv6_rt_hdr *hdr;
226         struct rt0_hdr *rthdr;
227
228         if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
229             !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
230                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
231                 kfree_skb(skb);
232                 return -1;
233         }
234
235         hdr = (struct ipv6_rt_hdr *) skb->h.raw;
236
237         if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
238             skb->pkt_type != PACKET_HOST) {
239                 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
240                 kfree_skb(skb);
241                 return -1;
242         }
243
244 looped_back:
245         if (hdr->segments_left == 0) {
246                 opt->srcrt = skb->h.raw - skb->nh.raw;
247                 skb->h.raw += (hdr->hdrlen + 1) << 3;
248                 opt->dst0 = opt->dst1;
249                 opt->dst1 = 0;
250                 *nhoffp = (&hdr->nexthdr) - skb->nh.raw;
251                 return 1;
252         }
253
254         if (hdr->type != IPV6_SRCRT_TYPE_0) {
255                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
256                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
257                 return -1;
258         }
259         
260         if (hdr->hdrlen & 0x01) {
261                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
262                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
263                 return -1;
264         }
265
266         /*
267          *      This is the routing header forwarding algorithm from
268          *      RFC 2460, page 16.
269          */
270
271         n = hdr->hdrlen >> 1;
272
273         if (hdr->segments_left > n) {
274                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
275                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
276                 return -1;
277         }
278
279         /* We are about to mangle packet header. Be careful!
280            Do not damage packets queued somewhere.
281          */
282         if (skb_cloned(skb)) {
283                 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
284                 kfree_skb(skb);
285                 /* the copy is a forwarded packet */
286                 if (skb2 == NULL) {
287                         IP6_INC_STATS_BH(IPSTATS_MIB_OUTDISCARDS);      
288                         return -1;
289                 }
290                 *skbp = skb = skb2;
291                 opt = IP6CB(skb2);
292                 hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
293         }
294
295         if (skb->ip_summed == CHECKSUM_HW)
296                 skb->ip_summed = CHECKSUM_NONE;
297
298         i = n - --hdr->segments_left;
299
300         rthdr = (struct rt0_hdr *) hdr;
301         addr = rthdr->addr;
302         addr += i - 1;
303
304         if (ipv6_addr_is_multicast(addr)) {
305                 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS);
306                 kfree_skb(skb);
307                 return -1;
308         }
309
310         ipv6_addr_copy(&daddr, addr);
311         ipv6_addr_copy(addr, &skb->nh.ipv6h->daddr);
312         ipv6_addr_copy(&skb->nh.ipv6h->daddr, &daddr);
313
314         dst_release(xchg(&skb->dst, NULL));
315         ip6_route_input(skb);
316         if (skb->dst->error) {
317                 skb_push(skb, skb->data - skb->nh.raw);
318                 dst_input(skb);
319                 return -1;
320         }
321
322         if (skb->dst->dev->flags&IFF_LOOPBACK) {
323                 if (skb->nh.ipv6h->hop_limit <= 1) {
324                         IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
325                         icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
326                                     0, skb->dev);
327                         kfree_skb(skb);
328                         return -1;
329                 }
330                 skb->nh.ipv6h->hop_limit--;
331                 goto looped_back;
332         }
333
334         skb_push(skb, skb->data - skb->nh.raw);
335         dst_input(skb);
336         return -1;
337 }
338
339 static struct inet6_protocol rthdr_protocol = {
340         .handler        =       ipv6_rthdr_rcv,
341         .flags          =       INET6_PROTO_NOPOLICY,
342 };
343
344 void __init ipv6_rthdr_init(void)
345 {
346         if (inet6_add_protocol(&rthdr_protocol, IPPROTO_ROUTING) < 0)
347                 printk(KERN_ERR "ipv6_rthdr_init: Could not register protocol\n");
348 };
349
350 /*
351    This function inverts received rthdr.
352    NOTE: specs allow to make it automatically only if
353    packet authenticated.
354
355    I will not discuss it here (though, I am really pissed off at
356    this stupid requirement making rthdr idea useless)
357
358    Actually, it creates severe problems  for us.
359    Embryonic requests has no associated sockets,
360    so that user have no control over it and
361    cannot not only to set reply options, but
362    even to know, that someone wants to connect
363    without success. :-(
364
365    For now we need to test the engine, so that I created
366    temporary (or permanent) backdoor.
367    If listening socket set IPV6_RTHDR to 2, then we invert header.
368                                                    --ANK (980729)
369  */
370
371 struct ipv6_txoptions *
372 ipv6_invert_rthdr(struct sock *sk, struct ipv6_rt_hdr *hdr)
373 {
374         /* Received rthdr:
375
376            [ H1 -> H2 -> ... H_prev ]  daddr=ME
377
378            Inverted result:
379            [ H_prev -> ... -> H1 ] daddr =sender
380
381            Note, that IP output engine will rewrite this rthdr
382            by rotating it left by one addr.
383          */
384
385         int n, i;
386         struct rt0_hdr *rthdr = (struct rt0_hdr*)hdr;
387         struct rt0_hdr *irthdr;
388         struct ipv6_txoptions *opt;
389         int hdrlen = ipv6_optlen(hdr);
390
391         if (hdr->segments_left ||
392             hdr->type != IPV6_SRCRT_TYPE_0 ||
393             hdr->hdrlen & 0x01)
394                 return NULL;
395
396         n = hdr->hdrlen >> 1;
397         opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
398         if (opt == NULL)
399                 return NULL;
400         memset(opt, 0, sizeof(*opt));
401         opt->tot_len = sizeof(*opt) + hdrlen;
402         opt->srcrt = (void*)(opt+1);
403         opt->opt_nflen = hdrlen;
404
405         memcpy(opt->srcrt, hdr, sizeof(*hdr));
406         irthdr = (struct rt0_hdr*)opt->srcrt;
407         /* Obsolete field, MBZ, when originated by us */
408         irthdr->bitmap = 0;
409         opt->srcrt->segments_left = n;
410         for (i=0; i<n; i++)
411                 memcpy(irthdr->addr+i, rthdr->addr+(n-1-i), 16);
412         return opt;
413 }
414
415 /**********************************
416   Hop-by-hop options.
417  **********************************/
418
419 /* Router Alert as of RFC 2711 */
420
421 static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
422 {
423         if (skb->nh.raw[optoff+1] == 2) {
424                 IP6CB(skb)->ra = optoff;
425                 return 1;
426         }
427         LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_ra: wrong RA length %d\n",
428                        skb->nh.raw[optoff+1]);
429         kfree_skb(skb);
430         return 0;
431 }
432
433 /* Jumbo payload */
434
435 static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
436 {
437         u32 pkt_len;
438
439         if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
440                 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
441                                skb->nh.raw[optoff+1]);
442                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
443                 goto drop;
444         }
445
446         pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2));
447         if (pkt_len <= IPV6_MAXPLEN) {
448                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
449                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
450                 return 0;
451         }
452         if (skb->nh.ipv6h->payload_len) {
453                 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS);
454                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
455                 return 0;
456         }
457
458         if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
459                 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS);
460                 goto drop;
461         }
462         if (pkt_len + sizeof(struct ipv6hdr) < skb->len) {
463                 __pskb_trim(skb, pkt_len + sizeof(struct ipv6hdr));
464                 if (skb->ip_summed == CHECKSUM_HW)
465                         skb->ip_summed = CHECKSUM_NONE;
466         }
467         return 1;
468
469 drop:
470         kfree_skb(skb);
471         return 0;
472 }
473
474 static struct tlvtype_proc tlvprochopopt_lst[] = {
475         {
476                 .type   = IPV6_TLV_ROUTERALERT,
477                 .func   = ipv6_hop_ra,
478         },
479         {
480                 .type   = IPV6_TLV_JUMBO,
481                 .func   = ipv6_hop_jumbo,
482         },
483         { -1, }
484 };
485
486 int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff)
487 {
488         IP6CB(skb)->hop = sizeof(struct ipv6hdr);
489         if (ip6_parse_tlv(tlvprochopopt_lst, skb))
490                 return sizeof(struct ipv6hdr);
491         return -1;
492 }
493
494 /*
495  *      Creating outbound headers.
496  *
497  *      "build" functions work when skb is filled from head to tail (datagram)
498  *      "push"  functions work when headers are added from tail to head (tcp)
499  *
500  *      In both cases we assume, that caller reserved enough room
501  *      for headers.
502  */
503
504 static void ipv6_push_rthdr(struct sk_buff *skb, u8 *proto,
505                             struct ipv6_rt_hdr *opt,
506                             struct in6_addr **addr_p)
507 {
508         struct rt0_hdr *phdr, *ihdr;
509         int hops;
510
511         ihdr = (struct rt0_hdr *) opt;
512         
513         phdr = (struct rt0_hdr *) skb_push(skb, (ihdr->rt_hdr.hdrlen + 1) << 3);
514         memcpy(phdr, ihdr, sizeof(struct rt0_hdr));
515
516         hops = ihdr->rt_hdr.hdrlen >> 1;
517
518         if (hops > 1)
519                 memcpy(phdr->addr, ihdr->addr + 1,
520                        (hops - 1) * sizeof(struct in6_addr));
521
522         ipv6_addr_copy(phdr->addr + (hops - 1), *addr_p);
523         *addr_p = ihdr->addr;
524
525         phdr->rt_hdr.nexthdr = *proto;
526         *proto = NEXTHDR_ROUTING;
527 }
528
529 static void ipv6_push_exthdr(struct sk_buff *skb, u8 *proto, u8 type, struct ipv6_opt_hdr *opt)
530 {
531         struct ipv6_opt_hdr *h = (struct ipv6_opt_hdr *)skb_push(skb, ipv6_optlen(opt));
532
533         memcpy(h, opt, ipv6_optlen(opt));
534         h->nexthdr = *proto;
535         *proto = type;
536 }
537
538 void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
539                           u8 *proto,
540                           struct in6_addr **daddr)
541 {
542         if (opt->srcrt)
543                 ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
544         if (opt->dst0opt)
545                 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst0opt);
546         if (opt->hopopt)
547                 ipv6_push_exthdr(skb, proto, NEXTHDR_HOP, opt->hopopt);
548 }
549
550 void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt, u8 *proto)
551 {
552         if (opt->dst1opt)
553                 ipv6_push_exthdr(skb, proto, NEXTHDR_DEST, opt->dst1opt);
554 }
555
556 struct ipv6_txoptions *
557 ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt)
558 {
559         struct ipv6_txoptions *opt2;
560
561         opt2 = sock_kmalloc(sk, opt->tot_len, GFP_ATOMIC);
562         if (opt2) {
563                 long dif = (char*)opt2 - (char*)opt;
564                 memcpy(opt2, opt, opt->tot_len);
565                 if (opt2->hopopt)
566                         *((char**)&opt2->hopopt) += dif;
567                 if (opt2->dst0opt)
568                         *((char**)&opt2->dst0opt) += dif;
569                 if (opt2->dst1opt)
570                         *((char**)&opt2->dst1opt) += dif;
571                 if (opt2->srcrt)
572                         *((char**)&opt2->srcrt) += dif;
573         }
574         return opt2;
575 }