summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libc/net/Makefile.inc20
-rw-r--r--src/lib/libc/net/inet6_option_space.3452
-rw-r--r--src/lib/libc/net/inet6_rthdr_space.3322
-rw-r--r--src/lib/libc/net/ip6opt.c388
-rw-r--r--src/lib/libc/net/rthdr.c298
-rw-r--r--src/lib/libc/net/vars6.c42
6 files changed, 1520 insertions, 2 deletions
diff --git a/src/lib/libc/net/Makefile.inc b/src/lib/libc/net/Makefile.inc
index 95f937a320..8b708aae9a 100644
--- a/src/lib/libc/net/Makefile.inc
+++ b/src/lib/libc/net/Makefile.inc
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile.inc,v 1.25 1999/11/17 05:22:41 millert Exp $ 1# $OpenBSD: Makefile.inc,v 1.26 1999/12/11 08:09:11 itojun Exp $
2 2
3# net sources 3# net sources
4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/net ${LIBCSRCDIR}/net 4.PATH: ${LIBCSRCDIR}/arch/${MACHINE_ARCH}/net ${LIBCSRCDIR}/net
@@ -19,6 +19,9 @@ SRCS+= base64.c freeaddrinfo.c gai_strerror.c getaddrinfo.c gethostnamadr.c \
19 res_init.c res_mkquery.c res_query.c res_random.c res_send.c send.c \ 19 res_init.c res_mkquery.c res_query.c res_random.c res_send.c send.c \
20 sethostent.c ethers.c rcmdsh.c 20 sethostent.c ethers.c rcmdsh.c
21 21
22# IPv6
23SRCS+= ip6opt.c rthdr.c vars6.c
24
22# machine-dependent net sources 25# machine-dependent net sources
23# m-d Makefile.inc must include sources for: 26# m-d Makefile.inc must include sources for:
24# htonl() htons() ntohl() ntohs() 27# htonl() htons() ntohl() ntohs()
@@ -28,7 +31,8 @@ SRCS+= base64.c freeaddrinfo.c gai_strerror.c getaddrinfo.c gethostnamadr.c \
28MAN+= byteorder.3 ethers.3 getaddrinfo.3 gethostbyname.3 getnameinfo.3 \ 31MAN+= byteorder.3 ethers.3 getaddrinfo.3 gethostbyname.3 getnameinfo.3 \
29 getnetent.3 getprotoent.3 getservent.3 inet.3 if_indextoname.3 \ 32 getnetent.3 getprotoent.3 getservent.3 inet.3 if_indextoname.3 \
30 inet_net.3 iso_addr.3 link_addr.3 ns.3 ipx.3 \ 33 inet_net.3 iso_addr.3 link_addr.3 ns.3 ipx.3 \
31 rcmd.3 rcmdsh.3 resolver.3 net_addrcmp.3 34 rcmd.3 rcmdsh.3 resolver.3 net_addrcmp.3 \
35 inet6_option_space.3 inet6_rthdr_space.3
32 36
33 37
34MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ 38MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \
@@ -64,3 +68,15 @@ MLINKS+=rcmd.3 iruserok.3 rcmd.3 rresvport.3 rcmd.3 ruserok.3
64MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ 68MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \
65 resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \ 69 resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \
66 resolver.3 res_search.3 70 resolver.3 res_search.3
71MLINKS+=inet6_option_space.3 inet6_option_init.3 \
72 inet6_option_space.3 inet6_option_append.3 \
73 inet6_option_space.3 inet6_option_alloc.3 \
74 inet6_option_space.3 inet6_option_next.3 \
75 inet6_option_space.3 inet6_option_find.3
76MLINKS+=inet6_rthdr_space.3 inet6_rthdr_init.3 \
77 inet6_rthdr_space.3 inet6_rthdr_add.3 \
78 inet6_rthdr_space.3 inet6_rthdr_lasthop.3 \
79 inet6_rthdr_space.3 inet6_rthdr_reverse.3 \
80 inet6_rthdr_space.3 inet6_rthdr_segments.3 \
81 inet6_rthdr_space.3 inet6_rthdr_getaddr.3 \
82 inet6_rthdr_space.3 inet6_rthdr_getflags.3
diff --git a/src/lib/libc/net/inet6_option_space.3 b/src/lib/libc/net/inet6_option_space.3
new file mode 100644
index 0000000000..2427b71216
--- /dev/null
+++ b/src/lib/libc/net/inet6_option_space.3
@@ -0,0 +1,452 @@
1.\" $OpenBSD: inet6_option_space.3,v 1.1 1999/12/11 08:09:11 itojun Exp $
2.\"
3.\" Copyright (c) 1983, 1987, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
35.\" KAME Id: inet6_option_space.3,v 1.2 1999/12/10 04:46:16 itojun Exp
36.\"
37.Dd December 10, 1999
38.Dt INET6_OPTION_SPACE 3
39.Os
40.\"
41.Sh NAME
42.Nm inet6_option_space ,
43.Nm inet6_option_init ,
44.Nm inet6_option_append ,
45.Nm inet6_option_alloc ,
46.Nm inet6_option_next ,
47.Nm inet6_option_find
48.Nd IPv6 Hop-by-Hop and Destination Options manipulation
49.\"
50.Sh SYNOPSIS
51.Fd #include <netinet/in.h>
52.Ft "int"
53.Fn inet6_options_space "int nbytes"
54.Ft "int"
55.Fn inet6_option_init "void *bp" "struct cmsghdr **cmsgp" "int type"
56.Ft "int"
57.Fn inet6_option_append "struct cmsghdr *cmsg" "const u_int8_t *typep" "int multx" "int plusy"
58.Ft "u_int8_t *"
59.Fn inet6_option_alloc "struct cmsghdr *cmsg" "int datalen" "int multx" "int plusy";
60.Ft "int"
61.Fn inet6_option_next "const struct cmsghdr *cmsg" "u_int8_t **tptrp"
62.Ft "int"
63.Fn inet6_option_find "const struct cmsghdr *cmsg" "u_int8_t **tptrp" "int type"
64.\"
65.Sh DESCRIPTION
66.\"
67Building and parsing the Hop-by-Hop and Destination options is
68complicated due to alignment constranints, padding and
69ancillary data manipulation.
70RFC2292 defines a set of functions to help the application.
71The function prototypes for
72these functions are all in the
73.Aq Li netinet/in.h
74header.
75.\"
76.Ss inet6_option_space
77.Fn inet6_option_space
78returns the number of bytes required to hold an option when it is stored as
79ancillary data, including the
80.Li cmsghdr
81structure at the beginning,
82and any padding at the end
83.Po
84to make its size a multiple of 8 bytes
85.Pc .
86The argument is the size of the structure defining the option,
87which must include any pad bytes at the beginning
88.Po
89the value
90.Li y
91in the alignment term
92.Dq Li xn + y
93.Pc ,
94the type byte, the length byte, and the option data.
95.Pp
96Note: If multiple options are stored in a single ancillary data
97object, which is the recommended technique, this function
98overestimates the amount of space required by the size of
99.Li N-1
100.Li cmsghdr
101structures,
102where
103.Li N
104is the number of options to be stored in the object.
105This is of little consequence, since it is assumed that most
106Hop-by-Hop option headers and Destination option headers carry only
107one option
108.Pq appendix B of [RFC-2460] .
109.\"
110.Ss inet6_option_init
111.Fn inet6_option_init
112is called once per ancillary data object that will
113contain either Hop-by-Hop or Destination options.
114It returns
115.Li 0
116on success or
117.Li -1
118on an error.
119.Pp
120.Fa bp
121is a pointer to previously allocated space that will contain the
122ancillary data object.
123It must be large enough to contain all the
124individual options to be added by later calls to
125.Fn inet6_option_append
126and
127.Fn inet6_option_alloc .
128.Pp
129.Fa cmsgp
130is a pointer to a pointer to a
131.Li cmsghdr
132structure.
133.Fa *cmsgp
134is initialized by this function to point to the
135.Li cmsghdr
136structure constructed by this function in the buffer pointed to by
137.Fa bp .
138.Pp
139.Fa type
140is either
141.Dv IPV6_HOPOPTS
142or
143.Dv IPV6_DSTOPTS .
144This
145.Fa type
146is stored in the
147.Li cmsg_type
148member of the
149.Li cmsghdr
150structure pointed to by
151.Fa *cmsgp .
152.\"
153.Ss inet6_option_append
154This function appends a Hop-by-Hop option or a Destination option
155into an ancillary data object that has been initialized by
156.Fn inet6_option_init .
157This function returns
158.Li 0
159if it succeeds or
160.Li -1
161on an error.
162.Pp
163.Fa cmsg
164is a pointer to the
165.Li cmsghdr
166structure that must have been
167initialized by
168.Fn inet6_option_init .
169.Pp
170.Fa typep
171is a pointer to the 8-bit option type.
172It is assumed that this
173field is immediately followed by the 8-bit option data length field,
174which is then followed immediately by the option data.
175The caller
176initializes these three fields
177.Pq the type-length-value, or TLV
178before calling this function.
179.Pp
180The option type must have a value from
181.Li 2
182to
183.Li 255 , inclusive.
184.Po
185.Li 0
186and
187.Li 1
188are reserved for the
189.Li Pad1
190and
191.Li PadN
192options, respectively.
193.Pc
194.Pp
195The option data length must have a value between
196.Li 0
197and
198.Li 255 ,
199inclusive, and is the length of the option data that follows.
200.Pp
201.Fa multx
202is the value
203.Li x
204in the alignment term
205.Dq Li xn + y .
206It must have a value of
207.Li 1 ,
208.Li 2 ,
209.Li 4 ,
210or
211.Li 8 .
212.Pp
213.Fa plusy
214is the value
215.Li y
216in the alignment term
217.Dq Li xn + y .
218It must have a value between
219.Li 0
220and
221.Li 7 ,
222inclusive.
223.\"
224.Ss inet6_option_alloc
225This function appends a Hop-by-Hop option or a Destination option
226into an ancillary data object that has been initialized by
227.Fn inet6_option_init .
228This function returns a pointer to the 8-bit
229option type field that starts the option on success, or
230.Dv NULL
231on an error.
232.Pp
233The difference between this function and
234.Fn inet6_option_append
235is that the latter copies the contents of a previously built option into
236the ancillary data object while the current function returns a
237pointer to the space in the data object where the option's TLV must
238then be built by the caller.
239.Pp
240.Fa cmsg
241is a pointer to the
242.Li cmsghdr
243structure that must have been
244initialized by
245.Fn inet6_option_init .
246.Pp
247.Fa datalen
248is the value of the option data length byte for this option.
249This value is required as an argument to allow the function to
250determine if padding must be appended at the end of the option.
251.Po
252The
253.Fn inet6_option_append
254function does not need a data length argument
255since the option data length must already be stored by the caller.
256.Pc
257.Pp
258.Fa multx
259is the value
260.Li x
261in the alignment term
262.Dq Li xn + y .
263It must have a value of
264.Li 1 ,
265.Li 2 ,
266.Li 4 ,
267or
268.Li 8 .
269.Pp
270.Fa plusy
271is the value
272.Li y
273in the alignment term
274.Dq Li xn + y .
275It must have a value between
276.Li 0
277and
278.Li 7 ,
279inclusive.
280.\"
281.Ss inet6_option_next
282This function processes the next Hop-by-Hop option or Destination
283option in an ancillary data object.
284If another option remains to be
285processed, the return value of the function is
286.Li 0
287and
288.Fa *tptrp
289points to
290the 8-bit option type field
291.Po
292which is followed by the 8-bit option
293data length, followed by the option data
294.Pc .
295If no more options remain
296to be processed, the return value is
297.Li -1
298and
299.Fa *tptrp
300is
301.Dv NULL .
302If an error occurs, the return value is
303.Li -1
304and
305.Fa *tptrp
306is not
307.Dv NULL .
308.Pp
309.Fa cmsg
310is a pointer to
311.Li cmsghdr
312structure of which
313.Li cmsg_level
314equals
315.Dv IPPROTO_IPV6
316and
317.Li cmsg_type
318equals either
319.Dv IPV6_HOPOPTS
320or
321.Dv IPV6_DSTOPTS .
322.Pp
323.Fa tptrp
324is a pointer to a pointer to an 8-bit byte and
325.Fa *tptrp
326is used
327by the function to remember its place in the ancillary data object
328each time the function is called.
329The first time this function is
330called for a given ancillary data object,
331.Fa *tptrp
332must be set to
333.Dv NULL .
334.Pp
335Each time this function returns success,
336.Fa *tptrp
337points to the 8-bit
338option type field for the next option to be processed.
339.\"
340.Ss inet6_option_find
341This function is similar to the previously described
342.Fn inet6_option_next
343function, except this function lets the caller
344specify the option type to be searched for, instead of always
345returning the next option in the ancillary data object.
346.Fa cmsg
347is a
348pointer to
349.Li cmsghdr
350structure of which
351.Li cmsg_level
352equals
353.Dv IPPROTO_IPV6
354and
355.Li cmsg_type
356equals either
357.Dv IPV6_HOPOPTS
358or
359.Dv IPV6_DSTOPTS .
360.Pp
361.Fa tptrp
362is a pointer to a pointer to an 8-bit byte and
363.Fa *tptrp
364is used
365by the function to remember its place in the ancillary data object
366each time the function is called.
367The first time this function is
368called for a given ancillary data object,
369.Fa *tptrp
370must be set to
371.Dv NULL .
372.Pa
373This function starts searching for an option of the specified type
374beginning after the value of
375.Fa *tptrp .
376If an option of the specified
377type is located, this function returns
378.Li 0
379and
380.Fa *tptrp
381points to the 8-
382bit option type field for the option of the specified type.
383If an
384option of the specified type is not located, the return value is
385.Li -1
386and
387.Fa *tptrp
388is
389.Dv NULL .
390If an error occurs, the return value is
391.Li -1
392and
393.Fa *tptrp
394is not
395.Dv NULL .
396.\"
397.Sh DIAGNOSTICS
398.Fn inet6_option_init
399and
400.Fn inet6_option_append
401return
402.Li 0
403on success or
404.Li -1
405on an error.
406.Pp
407.Fn inet6_option_alloc
408returns
409.Dv NULL on an error.
410.Pp
411On errors,
412.Fn inet6_option_next
413and
414.Fn inet6_option_find
415return
416.Li -1
417setting
418.Fa *tptrp
419to non
420.Dv NULL
421value.
422.\"
423.Sh EXAMPLES
424RFC2292 gives comprehensive examples in chapter 6.
425.\"
426.Sh SEE ALSO
427.Rs
428.%A W. Stevens
429.%A M. Thomas
430.%T "Advanced Sockets API for IPv6"
431.%N RFC2292
432.%D February 1998
433.Re
434.Rs
435.%A S. Deering
436.%A R. Hinden
437.%T "Internet Protocol, Version 6 (IPv6) Specification"
438.%N RFC2460
439.%D December 1998
440.Re
441.\"
442.Sh HISTORY
443The implementation first appeared in KAME advanced networking kit.
444.\"
445.Sh STANDARDS
446The functions are
447are documented in
448.Dq Advanced Sockets API for IPv6
449.Pq RFC2292 .
450.\"
451.Sh BUGS
452The text was shamelessly copied from RFC2292.
diff --git a/src/lib/libc/net/inet6_rthdr_space.3 b/src/lib/libc/net/inet6_rthdr_space.3
new file mode 100644
index 0000000000..887d866106
--- /dev/null
+++ b/src/lib/libc/net/inet6_rthdr_space.3
@@ -0,0 +1,322 @@
1.\" $OpenBSD: inet6_rthdr_space.3,v 1.1 1999/12/11 08:09:11 itojun Exp $
2.\"
3.\" Copyright (c) 1983, 1987, 1991, 1993
4.\" The Regents of the University of California. All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\" notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\" notice, this list of conditions and the following disclaimer in the
13.\" documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\" must display the following acknowledgement:
16.\" This product includes software developed by the University of
17.\" California, Berkeley and its contributors.
18.\" 4. Neither the name of the University nor the names of its contributors
19.\" may be used to endorse or promote products derived from this software
20.\" without specific prior written permission.
21.\"
22.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32.\" SUCH DAMAGE.
33.\"
34.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
35.\" KAME Id: inet6_rthdr_space.3,v 1.1 1999/12/10 04:48:55 itojun Exp
36.\"
37.Dd December 10, 1999
38.Dt INET6_OPTION_SPACE 3
39.Os
40.\"
41.Sh NAME
42.Nm inet6_rthdr_space ,
43.Nm inet6_rthdr_init ,
44.Nm inet6_rthdr_add ,
45.Nm inet6_rthdr_lasthop ,
46.Nm inet6_rthdr_reverse ,
47.Nm inet6_rthdr_segments ,
48.Nm inet6_rthdr_getaddr ,
49.Nm inet6_rthdr_getflags
50.Nd IPv6 Routing Header Options manipulation
51.\"
52.Sh SYNOPSIS
53.Fd #include <netinet/in.h>
54.Ft size_t
55.Fn inet6_rthdr_space "int type" "int segments"
56.Ft "struct cmsghdr *"
57.Fn inet6_rthdr_init "void *bp" "int type"
58.Ft int
59.Fn inet6_rthdr_add "struct cmsghdr *cmsg" "const struct in6_addr *addr" "unsigned int flags"
60.Ft int
61.Fn inet6_rthdr_lasthop "struct cmsghdr *cmsg" "unsigned int flags"
62.Ft int
63.Fn inet6_rthdr_reverse "const struct cmsghdr *in" "struct cmsghdr *out"
64.Ft int
65.Fn inet6_rthdr_segments "const struct cmsghdr *cmsg"
66.Ft "struct in6_addr"
67.Fn inet6_rthdr_getaddr "struct cmsghdr *cmsg" "int index"
68.Ft int
69.Fn inet6_rthdr_getflags "const struct cmsghdr *cmsg" "int index"
70.\"
71.Sh DESCRIPTION
72RFC2292 IPv6 advanced API defines eight
73functions that the application calls to build and examine a Routing
74header. Four functions build a Routing header:
75.Bl -hang
76.It Fn inet6_rthdr_space
77return #bytes required for ancillary data
78.It Fn inet6_rthdr_init
79initialize ancillary data for Routing header
80.It Fn inet6_rthdr_add
81add IPv6 address & flags to Routing header
82.It Fn inet6_rthdr_lasthop
83specify the flags for the final hop
84.El
85.Pp
86Four functions deal with a returned Routing header:
87.Bl -hang
88.It Fn inet6_rthdr_reverse
89reverse a Routing header
90.It Fn inet6_rthdr_segments
91return #segments in a Routing header
92.It Fn inet6_rthdr_getaddr
93fetch one address from a Routing header
94.It Fn inet6_rthdr_getflags
95fetch one flag from a Routing header
96.El
97.Pp
98The function prototypes for these functions are all in the
99.Aq Li netinet/in.h
100header.
101.\"
102.Ss inet6_rthdr_space
103This function returns the number of bytes required to hold a Routing
104header of the specified
105.Fa type
106containing the specified number of
107.Fa segments
108.Pq addresses .
109For an IPv6 Type 0 Routing header, the number
110of segments must be between 1 and 23, inclusive. The return value
111includes the size of the cmsghdr structure that precedes the Routing
112header, and any required padding.
113.Pp
114If the return value is 0, then either the type of the Routing header
115is not supported by this implementation or the number of segments is
116invalid for this type of Routing header.
117.Pp
118Note: This function returns the size but does not allocate the space
119required for the ancillary data.
120This allows an application to
121allocate a larger buffer, if other ancillary data objects are
122desired, since all the ancillary data objects must be specified to
123.Xr sendmsg 2
124as a single
125.Li msg_control
126buffer.
127.\"
128.Ss inet6_rthdr_init
129This function initializes the buffer pointed to by
130.Fa bp
131to contain a
132.Li cmsghdr
133structure followed by a Routing header of the specified
134.Fa type .
135The
136.Li cmsg_len
137member of the
138.Li cmsghdr
139structure is initialized to the
140size of the structure plus the amount of space required by the
141Routing header.
142The
143.Li cmsg_level
144and
145.Li cmsg_type
146members are also initialized as required.
147.Pp
148The caller must allocate the buffer and its size can be determined by
149calling
150.Fn inet6_rthdr_space .
151.Pp
152Upon success the return value is the pointer to the
153.Li cmsghdr
154structure, and this is then used as the first argument to the next
155two functions.
156Upon an error the return value is
157.Dv NULL .
158.\"
159.Ss inet6_rthdr_add
160This function adds the address pointed to by
161.Fa addr
162to the end of the
163Routing header being constructed and sets the type of this hop to the
164value of
165.Fa flags .
166For an IPv6 Type 0 Routing header,
167.Fa flags
168must be
169either
170.Dv IPV6_RTHDR_LOOSE
171or
172.Dv IPV6_RTHDR_STRICT .
173.Pp
174If successful, the
175.Li cmsg_len
176member of the
177.Li cmsghdr
178structure is
179updated to account for the new address in the Routing header and the
180return value of the function is 0.
181Upon an error the return value of
182the function is -1.
183.\"
184.Ss inet6_rthdr_lasthop
185This function specifies the Strict/Loose flag for the final hop of a
186Routing header.
187For an IPv6 Type 0 Routing header,
188.Fa flags
189must be either
190.Dv IPV6_RTHDR_LOOSE
191or
192.Dv IPV6_RTHDR_STRICT .
193.Pp
194The return value of the function is 0 upon success, or -1 upon an error.
195.Pp
196Notice that a Routing header specifying
197.Li N
198intermediate nodes requires
199.Li N+1
200Strict/Loose flags.
201This requires
202.Li N
203calls to
204.Fn inet6_rthdr_add
205followed by one call to
206.Fn inet6_rthdr_lasthop .
207.\"
208.Ss inet6_rthdr_reverse
209This function takes a Routing header that was received as ancillary
210data
211.Po
212pointed to by the first argument,
213.Fa in
214.Pc
215and writes a new Routing
216header that sends datagrams along the reverse of that route.
217Both
218arguments are allowed to point to the same buffer
219.Pq that is, the reversal can occur in place .
220.Pp
221The return value of the function is 0 on success, or -1 upon an
222error.
223.\"
224.Ss inet6_rthdr_segments
225This function returns the number of segments
226.Pq addresses
227contained in
228the Routing header described by
229.Fa cmsg .
230On success the return value is
231between 1 and 23, inclusive.
232The return value of the function is -1 upon an error.
233.\"
234.Ss inet6_rthdr_getaddr
235This function returns a pointer to the IPv6 address specified by
236.Fa index
237.Po
238which must have a value between 1 and the value returned by
239.Fn inet6_rthdr_segments
240.Pc
241in the Routing header described by
242.Fa cmsg .
243An
244application should first call
245.Fn inet6_rthdr_segments
246to obtain the number of segments in the Routing header.
247.Pp
248Upon an error the return value of the function is
249.Dv NULL .
250.\"
251.Ss inet6_rthdr_getflags
252This function returns the flags value specified by
253.Fa index
254.Po
255which must
256have a value between 0 and the value returned by
257.Fn inet6_rthdr_segments
258.Pc
259in the Routing header described by
260.Fa cmsg .
261For an IPv6 Type 0 Routing header the return value will be either
262.Dv IPV6_RTHDR_LOOSE
263or
264.Dv IPV6_RTHDR_STRICT .
265.Pp
266Upon an error the return value of the function is -1.
267.Pp
268Note: Addresses are indexed starting at 1, and flags starting at 0,
269to maintain consistency with the terminology and figures in RFC2460.
270.\"
271.Sh DIAGNOSTICS
272.Fn inet6_rthdr_space
273returns 0 on errors.
274.Pp
275.Fn inet6_rthdr_add ,
276.Fn inet6_rthdr_lasthop
277and
278.Fn inet6_rthdr_reverse
279return 0 on success, and returns -1 on error.
280.Pp
281.Fn inet6_rthdr_init
282and
283.Fn inet6_rthdr_getaddr
284return
285.Dv NULL
286on error.
287.Pp
288.Fn inet6_rthdr_segments
289and
290.Fn inet6_rthdr_getflags
291return -1 on error.
292.\"
293.Sh EXAMPLES
294RFC2292 gives comprehensive examples in chapter 8.
295.\"
296.Sh SEE ALSO
297.Rs
298.%A W. Stevens
299.%A M. Thomas
300.%T "Advanced Sockets API for IPv6"
301.%N RFC2292
302.%D February 1998
303.Re
304.Rs
305.%A S. Deering
306.%A R. Hinden
307.%T "Internet Protocol, Version 6 (IPv6) Specification"
308.%N RFC2460
309.%D December 1998
310.Re
311.\"
312.Sh HISTORY
313The implementation first appeared in KAME advanced networking kit.
314.\"
315.Sh STANDARDS
316The functions are
317are documented in
318.Dq Advanced Sockets API for IPv6
319.Pq RFC2292 .
320.\"
321.Sh BUGS
322The text was shamelessly copied from RFC2292.
diff --git a/src/lib/libc/net/ip6opt.c b/src/lib/libc/net/ip6opt.c
new file mode 100644
index 0000000000..cbd49f0c22
--- /dev/null
+++ b/src/lib/libc/net/ip6opt.c
@@ -0,0 +1,388 @@
1/* $OpenBSD: ip6opt.c,v 1.1 1999/12/11 08:09:11 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
32#include <sys/param.h>
33#include <sys/types.h>
34#include <sys/socket.h>
35
36#include <netinet/in.h>
37#include <netinet/ip6.h>
38
39#include <string.h>
40#include <stdio.h>
41
42static int ip6optlen(u_int8_t *opt, u_int8_t *lim);
43static void inet6_insert_padopt(u_char *p, int len);
44
45/*
46 * This function returns the number of bytes required to hold an option
47 * when it is stored as ancillary data, including the cmsghdr structure
48 * at the beginning, and any padding at the end (to make its size a
49 * multiple of 8 bytes). The argument is the size of the structure
50 * defining the option, which must include any pad bytes at the
51 * beginning (the value y in the alignment term "xn + y"), the type
52 * byte, the length byte, and the option data.
53 */
54int
55inet6_option_space(nbytes)
56 int nbytes;
57{
58 nbytes += 2; /* we need space for nxt-hdr and length fields */
59 return(CMSG_SPACE((nbytes + 7) & ~7));
60}
61
62/*
63 * This function is called once per ancillary data object that will
64 * contain either Hop-by-Hop or Destination options. It returns 0 on
65 * success or -1 on an error.
66 */
67int
68inet6_option_init(bp, cmsgp, type)
69 void *bp;
70 struct cmsghdr **cmsgp;
71 int type;
72{
73 register struct cmsghdr *ch = (struct cmsghdr *)bp;
74
75 /* argument validation */
76 if (type != IPV6_HOPOPTS && type != IPV6_DSTOPTS)
77 return(-1);
78
79 ch->cmsg_level = IPPROTO_IPV6;
80 ch->cmsg_type = type;
81 ch->cmsg_len = CMSG_LEN(0);
82
83 *cmsgp = ch;
84 return(0);
85}
86
87/*
88 * This function appends a Hop-by-Hop option or a Destination option
89 * into an ancillary data object that has been initialized by
90 * inet6_option_init(). This function returns 0 if it succeeds or -1 on
91 * an error.
92 * multx is the value x in the alignment term "xn + y" described
93 * earlier. It must have a value of 1, 2, 4, or 8.
94 * plusy is the value y in the alignment term "xn + y" described
95 * earlier. It must have a value between 0 and 7, inclusive.
96 */
97int
98inet6_option_append(cmsg, typep, multx, plusy)
99 struct cmsghdr *cmsg;
100 const u_int8_t *typep;
101 int multx;
102 int plusy;
103{
104 int padlen, optlen, off;
105 register u_char *bp = (u_char *)cmsg + cmsg->cmsg_len;
106 struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg);
107
108 /* argument validation */
109 if (multx != 1 && multx != 2 && multx != 4 && multx != 8)
110 return(-1);
111 if (plusy < 0 || plusy > 7)
112 return(-1);
113 if (typep[0] > 255)
114 return(-1);
115
116 /*
117 * If this is the first option, allocate space for the
118 * first 2 bytes(for next header and length fields) of
119 * the option header.
120 */
121 if (bp == (u_char *)eh) {
122 bp += 2;
123 cmsg->cmsg_len += 2;
124 }
125
126 /* calculate pad length before the option. */
127 off = bp - (u_char *)eh;
128 padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
129 (off % multx);
130 padlen += plusy;
131 padlen %= multx; /* keep the pad as short as possible */
132 /* insert padding */
133 inet6_insert_padopt(bp, padlen);
134 cmsg->cmsg_len += padlen;
135 bp += padlen;
136
137 /* copy the option */
138 if (typep[0] == IP6OPT_PAD1)
139 optlen = 1;
140 else
141 optlen = typep[1] + 2;
142 memcpy(bp, typep, optlen);
143 bp += optlen;
144 cmsg->cmsg_len += optlen;
145
146 /* calculate pad length after the option and insert the padding */
147 off = bp - (u_char *)eh;
148 padlen = ((off + 7) & ~7) - off;
149 inet6_insert_padopt(bp, padlen);
150 bp += padlen;
151 cmsg->cmsg_len += padlen;
152
153 /* update the length field of the ip6 option header */
154 eh->ip6e_len = ((bp - (u_char *)eh) >> 3) - 1;
155
156 return(0);
157}
158
159/*
160 * This function appends a Hop-by-Hop option or a Destination option
161 * into an ancillary data object that has been initialized by
162 * inet6_option_init(). This function returns a pointer to the 8-bit
163 * option type field that starts the option on success, or NULL on an
164 * error.
165 * The difference between this function and inet6_option_append() is
166 * that the latter copies the contents of a previously built option into
167 * the ancillary data object while the current function returns a
168 * pointer to the space in the data object where the option's TLV must
169 * then be built by the caller.
170 *
171 */
172u_int8_t *
173inet6_option_alloc(cmsg, datalen, multx, plusy)
174 struct cmsghdr *cmsg;
175 int datalen;
176 int multx;
177 int plusy;
178{
179 int padlen, off;
180 register u_int8_t *bp = (u_char *)cmsg + cmsg->cmsg_len;
181 u_int8_t *retval;
182 struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg);
183
184 /* argument validation */
185 if (multx != 1 && multx != 2 && multx != 4 && multx != 8)
186 return(NULL);
187 if (plusy < 0 || plusy > 7)
188 return(NULL);
189
190 /*
191 * If this is the first option, allocate space for the
192 * first 2 bytes(for next header and length fields) of
193 * the option header.
194 */
195 if (bp == (u_char *)eh) {
196 bp += 2;
197 cmsg->cmsg_len += 2;
198 }
199
200 /* calculate pad length before the option. */
201 off = bp - (u_char *)eh;
202 padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
203 (off % multx);
204 padlen += plusy;
205 padlen %= multx; /* keep the pad as short as possible */
206 /* insert padding */
207 inet6_insert_padopt(bp, padlen);
208 cmsg->cmsg_len += padlen;
209 bp += padlen;
210
211 /* keep space to store specified length of data */
212 retval = bp;
213 bp += datalen;
214 cmsg->cmsg_len += datalen;
215
216 /* calculate pad length after the option and insert the padding */
217 off = bp - (u_char *)eh;
218 padlen = ((off + 7) & ~7) - off;
219 inet6_insert_padopt(bp, padlen);
220 bp += padlen;
221 cmsg->cmsg_len += padlen;
222
223 /* update the length field of the ip6 option header */
224 eh->ip6e_len = ((bp - (u_char *)eh) >> 3) - 1;
225
226 return(retval);
227}
228
229/*
230 * This function processes the next Hop-by-Hop option or Destination
231 * option in an ancillary data object. If another option remains to be
232 * processed, the return value of the function is 0 and *tptrp points to
233 * the 8-bit option type field (which is followed by the 8-bit option
234 * data length, followed by the option data). If no more options remain
235 * to be processed, the return value is -1 and *tptrp is NULL. If an
236 * error occurs, the return value is -1 and *tptrp is not NULL.
237 * (RFC 2292, 6.3.5)
238 */
239int
240inet6_option_next(cmsg, tptrp)
241 const struct cmsghdr *cmsg;
242 u_int8_t **tptrp;
243{
244 struct ip6_ext *ip6e;
245 int hdrlen, optlen;
246 u_int8_t *lim;
247
248 if (cmsg->cmsg_level != IPPROTO_IPV6 ||
249 (cmsg->cmsg_type != IPV6_HOPOPTS &&
250 cmsg->cmsg_type != IPV6_DSTOPTS))
251 return(-1);
252
253 /* message length validation */
254 if (cmsg->cmsg_len < CMSG_SPACE(sizeof(struct ip6_ext)))
255 return(-1);
256 ip6e = (struct ip6_ext *)CMSG_DATA(cmsg);
257 hdrlen = (ip6e->ip6e_len + 1) << 3;
258 if (cmsg->cmsg_len < CMSG_SPACE(hdrlen))
259 return(-1);
260
261 /*
262 * If the caller does not specify the starting point,
263 * simply return the 1st option.
264 * Otherwise, search the option list for the next option.
265 */
266 lim = (u_int8_t *)ip6e + hdrlen;
267 if (*tptrp == NULL)
268 *tptrp = (u_int8_t *)(ip6e + 1);
269 else {
270 if ((optlen = ip6optlen(*tptrp, lim)) == 0)
271 return(-1);
272
273 *tptrp = *tptrp + optlen;
274 }
275 if (*tptrp >= lim) { /* there is no option */
276 *tptrp = NULL;
277 return(-1);
278 }
279 /*
280 * Finally, checks if the next option is safely stored in the
281 * cmsg data.
282 */
283 if (ip6optlen(*tptrp, lim) == 0)
284 return(-1);
285 else
286 return(0);
287}
288
289/*
290 * This function is similar to the inet6_option_next() function,
291 * except this function lets the caller specify the option type to be
292 * searched for, instead of always returning the next option in the
293 * ancillary data object.
294 * Note: RFC 2292 says the type of tptrp is u_int8_t *, but we think
295 * it's a typo. The variable should be type of u_int8_t **.
296 */
297int
298inet6_option_find(cmsg, tptrp, type)
299 const struct cmsghdr *cmsg;
300 u_int8_t **tptrp;
301 int type;
302{
303 struct ip6_ext *ip6e;
304 int hdrlen, optlen;
305 u_int8_t *optp, *lim;
306
307 if (cmsg->cmsg_level != IPPROTO_IPV6 ||
308 (cmsg->cmsg_type != IPV6_HOPOPTS &&
309 cmsg->cmsg_type != IPV6_DSTOPTS))
310 return(-1);
311
312 /* message length validation */
313 if (cmsg->cmsg_len < CMSG_SPACE(sizeof(struct ip6_ext)))
314 return(-1);
315 ip6e = (struct ip6_ext *)CMSG_DATA(cmsg);
316 hdrlen = (ip6e->ip6e_len + 1) << 3;
317 if (cmsg->cmsg_len < CMSG_SPACE(hdrlen))
318 return(-1);
319
320 /*
321 * If the caller does not specify the starting point,
322 * search from the beginning of the option list.
323 * Otherwise, search from *the next option* of the specified point.
324 */
325 lim = (u_int8_t *)ip6e + hdrlen;
326 if (*tptrp == NULL)
327 *tptrp = (u_int8_t *)(ip6e + 1);
328 else {
329 if ((optlen = ip6optlen(*tptrp, lim)) == 0)
330 return(-1);
331
332 *tptrp = *tptrp + optlen;
333 }
334 for (optp = *tptrp; optp < lim; optp += optlen) {
335 if (*optp == type) {
336 *tptrp = optp;
337 return(0);
338 }
339 if ((optlen = ip6optlen(optp, lim)) == 0)
340 return(-1);
341 }
342
343 /* search failed */
344 *tptrp = NULL;
345 return(-1);
346}
347
348/*
349 * Calculate the length of a given IPv6 option. Also checks
350 * if the option is safely stored in user's buffer according to the
351 * calculated length and the limitation of the buffer.
352 */
353static int
354ip6optlen(opt, lim)
355 u_int8_t *opt, *lim;
356{
357 int optlen;
358
359 if (*opt == IP6OPT_PAD1)
360 optlen = 1;
361 else {
362 /* is there enough space to store type and len? */
363 if (opt + 2 > lim)
364 return(0);
365 optlen = *(opt + 1) + 2;
366 }
367 if (opt + optlen <= lim)
368 return(optlen);
369
370 return(0);
371}
372
373static void
374inet6_insert_padopt(u_char *p, int len)
375{
376 switch(len) {
377 case 0:
378 return;
379 case 1:
380 p[0] = IP6OPT_PAD1;
381 return;
382 default:
383 p[0] = IP6OPT_PADN;
384 p[1] = len - 2;
385 memset(&p[2], 0, len - 2);
386 return;
387 }
388}
diff --git a/src/lib/libc/net/rthdr.c b/src/lib/libc/net/rthdr.c
new file mode 100644
index 0000000000..2dff59668e
--- /dev/null
+++ b/src/lib/libc/net/rthdr.c
@@ -0,0 +1,298 @@
1/* $OpenBSD: rthdr.c,v 1.1 1999/12/11 08:09:11 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
32#include <sys/param.h>
33#include <sys/types.h>
34#include <sys/socket.h>
35
36#include <netinet/in.h>
37#include <netinet/ip6.h>
38
39#include <string.h>
40#include <stdio.h>
41
42size_t
43inet6_rthdr_space(type, seg)
44 int type, seg;
45{
46 switch(type) {
47 case IPV6_RTHDR_TYPE_0:
48 if (seg < 1 || seg > 23)
49 return(0);
50 return(CMSG_SPACE(sizeof(struct in6_addr) * (seg - 1)
51 + sizeof(struct ip6_rthdr0)));
52 default:
53#ifdef DEBUG
54 fprintf(stderr, "inet6_rthdr_space: unknown type(%d)\n", type);
55#endif
56 return(0);
57 }
58}
59
60struct cmsghdr *
61inet6_rthdr_init(bp, type)
62 void *bp;
63 int type;
64{
65 register struct cmsghdr *ch = (struct cmsghdr *)bp;
66 register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(ch + 1);
67
68 ch->cmsg_level = IPPROTO_IPV6;
69 ch->cmsg_type = IPV6_RTHDR;
70
71 switch(type) {
72 case IPV6_RTHDR_TYPE_0:
73 ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0) - sizeof(struct in6_addr));
74 bzero(rthdr, sizeof(struct ip6_rthdr0));
75 rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
76 return(ch);
77 default:
78#ifdef DEBUG
79 fprintf(stderr, "inet6_rthdr_init: unknown type(%d)\n", type);
80#endif
81 return(NULL);
82 }
83}
84
85int
86inet6_rthdr_add(cmsg, addr, flags)
87 struct cmsghdr *cmsg;
88 const struct in6_addr *addr;
89 u_int flags;
90{
91 register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(cmsg + 1);
92
93 switch(rthdr->ip6r_type) {
94 case IPV6_RTHDR_TYPE_0:
95 {
96 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
97 if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT) {
98#ifdef DEBUG
99 fprintf(stderr, "inet6_rthdr_add: unsupported flag(%d)\n", flags);
100#endif
101 return(-1);
102 }
103 if (rt0->ip6r0_segleft == 23) {
104#ifdef DEBUG
105 fprintf(stderr, "inet6_rthdr_add: segment overflow\n");
106#endif
107 return(-1);
108 }
109 if (flags == IPV6_RTHDR_STRICT) {
110 int c, b;
111 c = rt0->ip6r0_segleft / 8;
112 b = rt0->ip6r0_segleft % 8;
113 rt0->ip6r0_slmap[c] |= (1 << (7 - b));
114 }
115 rt0->ip6r0_segleft++;
116 bcopy(addr, (caddr_t)rt0 + ((rt0->ip6r0_len + 1) << 3),
117 sizeof(struct in6_addr));
118 rt0->ip6r0_len += sizeof(struct in6_addr) >> 3;
119 cmsg->cmsg_len = CMSG_LEN((rt0->ip6r0_len + 1) << 3);
120 break;
121 }
122 default:
123#ifdef DEBUG
124 fprintf(stderr, "inet6_rthdr_add: unknown type(%d)\n",
125 rthdr->ip6r_type);
126#endif
127 return(-1);
128 }
129
130 return(0);
131}
132
133int
134inet6_rthdr_lasthop(cmsg, flags)
135 struct cmsghdr *cmsg;
136 unsigned int flags;
137{
138 register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(cmsg + 1);
139
140 switch(rthdr->ip6r_type) {
141 case IPV6_RTHDR_TYPE_0:
142 {
143 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
144 if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT) {
145#ifdef DEBUG
146 fprintf(stderr, "inet6_rthdr_lasthop: unsupported flag(%d)\n", flags);
147#endif
148 return(-1);
149 }
150 if (rt0->ip6r0_segleft > 23) {
151#ifdef DEBUG
152 fprintf(stderr, "inet6_rthdr_add: segment overflow\n");
153#endif
154 return(-1);
155 }
156 if (flags == IPV6_RTHDR_STRICT) {
157 int c, b;
158 c = rt0->ip6r0_segleft / 8;
159 b = rt0->ip6r0_segleft % 8;
160 rt0->ip6r0_slmap[c] |= (1 << (7 - b));
161 }
162 break;
163 }
164 default:
165#ifdef DEBUG
166 fprintf(stderr, "inet6_rthdr_lasthop: unknown type(%d)\n",
167 rthdr->ip6r_type);
168#endif
169 return(-1);
170 }
171
172 return(0);
173}
174
175#if 0
176int
177inet6_rthdr_reverse(in, out)
178 const struct cmsghdr *in;
179 struct cmsghdr *out;
180{
181#ifdef DEBUG
182 fprintf(stderr, "inet6_rthdr_reverse: not implemented yet\n");
183#endif
184 return -1;
185}
186#endif
187
188int
189inet6_rthdr_segments(cmsg)
190 const struct cmsghdr *cmsg;
191{
192 register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(cmsg + 1);
193
194 switch(rthdr->ip6r_type) {
195 case IPV6_RTHDR_TYPE_0:
196 {
197 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
198
199 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
200#ifdef DEBUG
201 fprintf(stderr, "inet6_rthdr_segments: invalid size(%d)\n",
202 rt0->ip6r0_len);
203#endif
204 return -1;
205 }
206
207 return (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
208 }
209
210 default:
211#ifdef DEBUG
212 fprintf(stderr, "inet6_rthdr_segments: unknown type(%d)\n",
213 rthdr->ip6r_type);
214#endif
215 return -1;
216 }
217}
218
219struct in6_addr *
220inet6_rthdr_getaddr(cmsg, index)
221 struct cmsghdr *cmsg;
222 int index;
223{
224 register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(cmsg + 1);
225
226 switch(rthdr->ip6r_type) {
227 case IPV6_RTHDR_TYPE_0:
228 {
229 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
230 int naddr;
231
232 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
233#ifdef DEBUG
234 fprintf(stderr, "inet6_rthdr_getaddr: invalid size(%d)\n",
235 rt0->ip6r0_len);
236#endif
237 return NULL;
238 }
239 naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
240 if (index <= 0 || naddr < index) {
241#ifdef DEBUG
242 fprintf(stderr, "inet6_rthdr_getaddr: invalid index(%d)\n", index);
243#endif
244 return NULL;
245 }
246 return &rt0->ip6r0_addr[index - 1];
247 }
248
249 default:
250#ifdef DEBUG
251 fprintf(stderr, "inet6_rthdr_getaddr: unknown type(%d)\n",
252 rthdr->ip6r_type);
253#endif
254 return NULL;
255 }
256}
257
258int
259inet6_rthdr_getflags(cmsg, index)
260 const struct cmsghdr *cmsg;
261 int index;
262{
263 register struct ip6_rthdr *rthdr = (struct ip6_rthdr *)(cmsg + 1);
264
265 switch(rthdr->ip6r_type) {
266 case IPV6_RTHDR_TYPE_0:
267 {
268 struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
269 int naddr;
270
271 if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
272#ifdef DEBUG
273 fprintf(stderr, "inet6_rthdr_getflags: invalid size(%d)\n",
274 rt0->ip6r0_len);
275#endif
276 return -1;
277 }
278 naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
279 if (index < 0 || naddr < index) {
280#ifdef DEBUG
281 fprintf(stderr, "inet6_rthdr_getflags: invalid index(%d)\n", index);
282#endif
283 return -1;
284 }
285 if (rt0->ip6r0_slmap[index / 8] & (0x80 >> (index % 8)))
286 return IPV6_RTHDR_STRICT;
287 else
288 return IPV6_RTHDR_LOOSE;
289 }
290
291 default:
292#ifdef DEBUG
293 fprintf(stderr, "inet6_rthdr_getflags: unknown type(%d)\n",
294 rthdr->ip6r_type);
295#endif
296 return -1;
297 }
298}
diff --git a/src/lib/libc/net/vars6.c b/src/lib/libc/net/vars6.c
new file mode 100644
index 0000000000..6d0f069ef6
--- /dev/null
+++ b/src/lib/libc/net/vars6.c
@@ -0,0 +1,42 @@
1/* $OpenBSD: vars6.c,v 1.1 1999/12/11 08:09:11 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
32#include <sys/types.h>
33#include <netinet/in.h>
34
35/*
36 * Definitions of some costant IPv6 addresses.
37 */
38const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
39const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
40const struct in6_addr in6addr_nodelocal_allnodes = IN6ADDR_NODELOCAL_ALLNODES_INIT;
41const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
42