Cleanup various type-o's in comments.
[dragonfly.git] / lib / libcr / net / rthdr.c
1 /*      $KAME: rthdr.c,v 1.8 2001/08/20 02:32:40 itojun Exp $   */
2
3 /*
4  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5  * All rights reserved.
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the project nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  * 
19  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  * $FreeBSD: src/lib/libc/net/rthdr.c,v 1.2.2.1 2002/04/28 05:40:24 suz Exp $
32  * $DragonFly: src/lib/libcr/net/Attic/rthdr.c,v 1.2 2003/06/17 04:26:44 dillon Exp $
33  */
34
35 #include <sys/param.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38
39 #include <netinet/in.h>
40 #include <netinet/ip6.h>
41
42 #include <string.h>
43 #include <stdio.h>
44
45 size_t
46 inet6_rthdr_space(type, seg)
47     int type, seg;
48 {
49     switch(type) {
50      case IPV6_RTHDR_TYPE_0:
51          if (seg < 1 || seg > 23)
52              return(0);
53          return(CMSG_SPACE(sizeof(struct in6_addr) * (seg - 1)
54                            + sizeof(struct ip6_rthdr0)));
55      default:
56 #ifdef DEBUG
57          fprintf(stderr, "inet6_rthdr_space: unknown type(%d)\n", type);
58 #endif 
59          return(0);
60     }
61 }
62
63 struct cmsghdr *
64 inet6_rthdr_init(bp, type)
65     void *bp;
66     int type;
67 {
68     register struct cmsghdr *ch = (struct cmsghdr *)bp;
69     register struct ip6_rthdr *rthdr;
70
71     rthdr = (struct ip6_rthdr *)CMSG_DATA(ch);
72
73     ch->cmsg_level = IPPROTO_IPV6;
74     ch->cmsg_type = IPV6_RTHDR;
75
76     switch(type) {
77      case IPV6_RTHDR_TYPE_0:
78          ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0) - sizeof(struct in6_addr));
79          bzero(rthdr, sizeof(struct ip6_rthdr0));
80          rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
81          return(ch);
82      default:
83 #ifdef DEBUG
84          fprintf(stderr, "inet6_rthdr_init: unknown type(%d)\n", type);
85 #endif 
86          return(NULL);
87     }
88 }
89
90 int
91 inet6_rthdr_add(cmsg, addr, flags)
92     struct cmsghdr *cmsg;
93     const struct in6_addr *addr;
94     u_int flags;
95 {
96     register struct ip6_rthdr *rthdr;
97
98     rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
99
100     switch(rthdr->ip6r_type) {
101      case IPV6_RTHDR_TYPE_0:
102      {
103          struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
104          if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT) {
105 #ifdef DEBUG
106              fprintf(stderr, "inet6_rthdr_add: unsupported flag(%d)\n", flags);
107 #endif 
108              return(-1);
109          }
110          if (rt0->ip6r0_segleft == 23) {
111 #ifdef DEBUG
112              fprintf(stderr, "inet6_rthdr_add: segment overflow\n");
113 #endif 
114              return(-1);
115          }
116          if (flags == IPV6_RTHDR_STRICT) {
117              int c, b;
118              c = rt0->ip6r0_segleft / 8;
119              b = rt0->ip6r0_segleft % 8;
120              rt0->ip6r0_slmap[c] |= (1 << (7 - b));
121          }
122          rt0->ip6r0_segleft++;
123          bcopy(addr, (caddr_t)rt0 + ((rt0->ip6r0_len + 1) << 3),
124                sizeof(struct in6_addr));
125          rt0->ip6r0_len += sizeof(struct in6_addr) >> 3;
126          cmsg->cmsg_len = CMSG_LEN((rt0->ip6r0_len + 1) << 3);
127          break;
128      }
129      default:
130 #ifdef DEBUG
131          fprintf(stderr, "inet6_rthdr_add: unknown type(%d)\n",
132                  rthdr->ip6r_type);
133 #endif 
134          return(-1);
135     }
136
137     return(0);
138 }
139
140 int
141 inet6_rthdr_lasthop(cmsg, flags)
142     struct cmsghdr *cmsg;
143     unsigned int flags;
144 {
145     register struct ip6_rthdr *rthdr;
146
147     rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
148
149     switch(rthdr->ip6r_type) {
150      case IPV6_RTHDR_TYPE_0:
151      {
152          struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
153          if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT) {
154 #ifdef DEBUG
155              fprintf(stderr, "inet6_rthdr_lasthop: unsupported flag(%d)\n", flags);
156 #endif 
157              return(-1);
158          }
159          if (rt0->ip6r0_segleft > 23) {
160 #ifdef DEBUG
161              fprintf(stderr, "inet6_rthdr_add: segment overflow\n");
162 #endif 
163              return(-1);
164          }
165          if (flags == IPV6_RTHDR_STRICT) {
166              int c, b;
167              c = rt0->ip6r0_segleft / 8;
168              b = rt0->ip6r0_segleft % 8;
169              rt0->ip6r0_slmap[c] |= (1 << (7 - b));
170          }
171          break;
172      }
173      default:
174 #ifdef DEBUG
175          fprintf(stderr, "inet6_rthdr_lasthop: unknown type(%d)\n",
176                  rthdr->ip6r_type);
177 #endif 
178          return(-1);
179     }
180
181     return(0);
182 }
183
184 #if 0
185 int
186 inet6_rthdr_reverse(in, out)
187     const struct cmsghdr *in;
188     struct cmsghdr *out;
189 {
190 #ifdef DEBUG
191     fprintf(stderr, "inet6_rthdr_reverse: not implemented yet\n");
192 #endif 
193     return -1;
194 }
195 #endif
196
197 int
198 inet6_rthdr_segments(cmsg)
199     const struct cmsghdr *cmsg;
200 {
201     register struct ip6_rthdr *rthdr;
202
203     rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
204
205     switch(rthdr->ip6r_type) {
206     case IPV6_RTHDR_TYPE_0:
207       {
208         struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
209
210         if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
211 #ifdef DEBUG
212             fprintf(stderr, "inet6_rthdr_segments: invalid size(%d)\n",
213                 rt0->ip6r0_len);
214 #endif 
215             return -1;
216         }
217
218         return (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
219       }
220
221     default:
222 #ifdef DEBUG
223         fprintf(stderr, "inet6_rthdr_segments: unknown type(%d)\n",
224             rthdr->ip6r_type);
225 #endif 
226         return -1;
227     }
228 }
229
230 struct in6_addr *
231 inet6_rthdr_getaddr(cmsg, idx)
232     struct cmsghdr *cmsg;
233     int idx;
234 {
235     register struct ip6_rthdr *rthdr;
236
237     rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
238
239     switch(rthdr->ip6r_type) {
240     case IPV6_RTHDR_TYPE_0:
241       {
242         struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
243         int naddr;
244
245         if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
246 #ifdef DEBUG
247             fprintf(stderr, "inet6_rthdr_getaddr: invalid size(%d)\n",
248                 rt0->ip6r0_len);
249 #endif 
250             return NULL;
251         }
252         naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
253         if (idx <= 0 || naddr < idx) {
254 #ifdef DEBUG
255             fprintf(stderr, "inet6_rthdr_getaddr: invalid idx(%d)\n", idx);
256 #endif 
257             return NULL;
258         }
259         return &rt0->ip6r0_addr[idx - 1];
260       }
261
262     default:
263 #ifdef DEBUG
264         fprintf(stderr, "inet6_rthdr_getaddr: unknown type(%d)\n",
265             rthdr->ip6r_type);
266 #endif 
267         return NULL;
268     }
269 }
270
271 int
272 inet6_rthdr_getflags(cmsg, idx)
273     const struct cmsghdr *cmsg;
274     int idx;
275 {
276     register struct ip6_rthdr *rthdr;
277
278     rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
279
280     switch(rthdr->ip6r_type) {
281     case IPV6_RTHDR_TYPE_0:
282       {
283         struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
284         int naddr;
285
286         if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
287 #ifdef DEBUG
288             fprintf(stderr, "inet6_rthdr_getflags: invalid size(%d)\n",
289                 rt0->ip6r0_len);
290 #endif 
291             return -1;
292         }
293         naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
294         if (idx < 0 || naddr < idx) {
295 #ifdef DEBUG
296             fprintf(stderr, "inet6_rthdr_getflags: invalid idx(%d)\n", idx);
297 #endif 
298             return -1;
299         }
300         if (rt0->ip6r0_slmap[idx / 8] & (0x80 >> (idx % 8)))
301             return IPV6_RTHDR_STRICT;
302         else
303             return IPV6_RTHDR_LOOSE;
304       }
305
306     default:
307 #ifdef DEBUG
308         fprintf(stderr, "inet6_rthdr_getflags: unknown type(%d)\n",
309             rthdr->ip6r_type);
310 #endif 
311         return -1;
312     }
313 }