]>
git.saurik.com Git - apple/libinfo.git/blob - gen.subproj/rthdr.c
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * $FreeBSD: src/lib/libc/net/rthdr.c,v 1.2 2000/03/03 11:12:59 shin Exp $
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <netinet/ip6.h>
43 inet6_rthdr_space(type
, seg
)
47 case IPV6_RTHDR_TYPE_0
:
48 if (seg
< 1 || seg
> 23)
50 return(CMSG_SPACE(sizeof(struct in6_addr
) * (seg
- 1)
51 + sizeof(struct ip6_rthdr0
)));
54 fprintf(stderr
, "inet6_rthdr_space: unknown type(%d)\n", type
);
61 inet6_rthdr_init(bp
, type
)
65 register struct cmsghdr
*ch
= (struct cmsghdr
*)bp
;
66 register struct ip6_rthdr
*rthdr
;
68 rthdr
= (struct ip6_rthdr
*)CMSG_DATA(ch
);
70 ch
->cmsg_level
= IPPROTO_IPV6
;
71 ch
->cmsg_type
= IPV6_RTHDR
;
74 case IPV6_RTHDR_TYPE_0
:
75 ch
->cmsg_len
= CMSG_LEN(sizeof(struct ip6_rthdr0
) - sizeof(struct in6_addr
));
76 bzero(rthdr
, sizeof(struct ip6_rthdr0
));
77 rthdr
->ip6r_type
= IPV6_RTHDR_TYPE_0
;
81 fprintf(stderr
, "inet6_rthdr_init: unknown type(%d)\n", type
);
88 inet6_rthdr_add(cmsg
, addr
, flags
)
90 const struct in6_addr
*addr
;
93 register struct ip6_rthdr
*rthdr
;
95 rthdr
= (struct ip6_rthdr
*)CMSG_DATA(cmsg
);
97 switch(rthdr
->ip6r_type
) {
98 case IPV6_RTHDR_TYPE_0
:
100 struct ip6_rthdr0
*rt0
= (struct ip6_rthdr0
*)rthdr
;
101 if (flags
!= IPV6_RTHDR_LOOSE
&& flags
!= IPV6_RTHDR_STRICT
) {
103 fprintf(stderr
, "inet6_rthdr_add: unsupported flag(%d)\n", flags
);
107 if (rt0
->ip6r0_segleft
== 23) {
109 fprintf(stderr
, "inet6_rthdr_add: segment overflow\n");
113 if (flags
== IPV6_RTHDR_STRICT
) {
115 c
= rt0
->ip6r0_segleft
/ 8;
116 b
= rt0
->ip6r0_segleft
% 8;
117 rt0
->ip6r0_slmap
[c
] |= (1 << (7 - b
));
119 rt0
->ip6r0_segleft
++;
120 bcopy(addr
, (caddr_t
)rt0
+ ((rt0
->ip6r0_len
+ 1) << 3),
121 sizeof(struct in6_addr
));
122 rt0
->ip6r0_len
+= sizeof(struct in6_addr
) >> 3;
123 cmsg
->cmsg_len
= CMSG_LEN((rt0
->ip6r0_len
+ 1) << 3);
128 fprintf(stderr
, "inet6_rthdr_add: unknown type(%d)\n",
138 inet6_rthdr_lasthop(cmsg
, flags
)
139 struct cmsghdr
*cmsg
;
142 register struct ip6_rthdr
*rthdr
;
144 rthdr
= (struct ip6_rthdr
*)CMSG_DATA(cmsg
);
146 switch(rthdr
->ip6r_type
) {
147 case IPV6_RTHDR_TYPE_0
:
149 struct ip6_rthdr0
*rt0
= (struct ip6_rthdr0
*)rthdr
;
150 if (flags
!= IPV6_RTHDR_LOOSE
&& flags
!= IPV6_RTHDR_STRICT
) {
152 fprintf(stderr
, "inet6_rthdr_lasthop: unsupported flag(%d)\n", flags
);
156 if (rt0
->ip6r0_segleft
> 23) {
158 fprintf(stderr
, "inet6_rthdr_add: segment overflow\n");
162 if (flags
== IPV6_RTHDR_STRICT
) {
164 c
= rt0
->ip6r0_segleft
/ 8;
165 b
= rt0
->ip6r0_segleft
% 8;
166 rt0
->ip6r0_slmap
[c
] |= (1 << (7 - b
));
172 fprintf(stderr
, "inet6_rthdr_lasthop: unknown type(%d)\n",
183 inet6_rthdr_reverse(in
, out
)
184 const struct cmsghdr
*in
;
188 fprintf(stderr
, "inet6_rthdr_reverse: not implemented yet\n");
195 inet6_rthdr_segments(cmsg
)
196 const struct cmsghdr
*cmsg
;
198 register struct ip6_rthdr
*rthdr
;
200 rthdr
= (struct ip6_rthdr
*)CMSG_DATA(cmsg
);
202 switch(rthdr
->ip6r_type
) {
203 case IPV6_RTHDR_TYPE_0
:
205 struct ip6_rthdr0
*rt0
= (struct ip6_rthdr0
*)rthdr
;
207 if (rt0
->ip6r0_len
% 2 || 46 < rt0
->ip6r0_len
) {
209 fprintf(stderr
, "inet6_rthdr_segments: invalid size(%d)\n",
215 return (rt0
->ip6r0_len
* 8) / sizeof(struct in6_addr
);
220 fprintf(stderr
, "inet6_rthdr_segments: unknown type(%d)\n",
228 inet6_rthdr_getaddr(cmsg
, index
)
229 struct cmsghdr
*cmsg
;
232 register struct ip6_rthdr
*rthdr
;
234 rthdr
= (struct ip6_rthdr
*)CMSG_DATA(cmsg
);
236 switch(rthdr
->ip6r_type
) {
237 case IPV6_RTHDR_TYPE_0
:
239 struct ip6_rthdr0
*rt0
= (struct ip6_rthdr0
*)rthdr
;
242 if (rt0
->ip6r0_len
% 2 || 46 < rt0
->ip6r0_len
) {
244 fprintf(stderr
, "inet6_rthdr_getaddr: invalid size(%d)\n",
249 naddr
= (rt0
->ip6r0_len
* 8) / sizeof(struct in6_addr
);
250 if (index
<= 0 || naddr
< index
) {
252 fprintf(stderr
, "inet6_rthdr_getaddr: invalid index(%d)\n", index
);
256 return &rt0
->ip6r0_addr
[index
- 1];
261 fprintf(stderr
, "inet6_rthdr_getaddr: unknown type(%d)\n",
269 inet6_rthdr_getflags(cmsg
, index
)
270 const struct cmsghdr
*cmsg
;
273 register struct ip6_rthdr
*rthdr
;
275 rthdr
= (struct ip6_rthdr
*)CMSG_DATA(cmsg
);
277 switch(rthdr
->ip6r_type
) {
278 case IPV6_RTHDR_TYPE_0
:
280 struct ip6_rthdr0
*rt0
= (struct ip6_rthdr0
*)rthdr
;
283 if (rt0
->ip6r0_len
% 2 || 46 < rt0
->ip6r0_len
) {
285 fprintf(stderr
, "inet6_rthdr_getflags: invalid size(%d)\n",
290 naddr
= (rt0
->ip6r0_len
* 8) / sizeof(struct in6_addr
);
291 if (index
< 0 || naddr
< index
) {
293 fprintf(stderr
, "inet6_rthdr_getflags: invalid index(%d)\n", index
);
297 if (rt0
->ip6r0_slmap
[index
/ 8] & (0x80 >> (index
% 8)))
298 return IPV6_RTHDR_STRICT
;
300 return IPV6_RTHDR_LOOSE
;
305 fprintf(stderr
, "inet6_rthdr_getflags: unknown type(%d)\n",