Add support for RFC 3542 Adv. Socket API for IPv6 (which obsoletes 2292).

* RFC 3542 isn't binary compatible with RFC 2292.
* RFC 2292 support is on by default but can be disabled.
* update ping6, telnet and traceroute6 to the new API.

From the KAME project (www.kame.net).
Reviewed by core.
This commit is contained in:
rpaulo 2006-05-05 00:03:21 +00:00
parent e48c097471
commit de8db47547
26 changed files with 2476 additions and 427 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.873 2006/04/27 20:41:58 thorpej Exp $
# $NetBSD: mi,v 1.874 2006/05/05 00:03:21 rpaulo Exp $
./etc/mtree/set.comp comp-sys-root
./usr/bin/addr2line comp-debug-bin bfd
./usr/bin/ar comp-util-bin bfd
@ -3445,6 +3445,19 @@
./usr/share/man/cat3/inet6_rthdr_reverse.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_rthdr_segments.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_rthdr_space.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_opt_init.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_opt_append.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_opt_finish.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_opt_set_val.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_opt_next.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_opt_find.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_opt_get_val.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_rth_space.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_rth_init.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_rth_add.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_rth_reverse.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_rth_segments.0 comp-c-catman .cat
./usr/share/man/cat3/inet6_rth_getaddr.0 comp-c-catman .cat
./usr/share/man/cat3/inet_addr.0 comp-c-catman .cat
./usr/share/man/cat3/inet_aton.0 comp-c-catman .cat
./usr/share/man/cat3/inet_lnaof.0 comp-c-catman .cat
@ -7492,6 +7505,19 @@
./usr/share/man/man3/inet6_rthdr_reverse.3 comp-c-man .man
./usr/share/man/man3/inet6_rthdr_segments.3 comp-c-man .man
./usr/share/man/man3/inet6_rthdr_space.3 comp-c-man .man
./usr/share/man/man3/inet6_opt_init.3 comp-c-man .man
./usr/share/man/man3/inet6_opt_append.3 comp-c-man .man
./usr/share/man/man3/inet6_opt_finish.3 comp-c-man .man
./usr/share/man/man3/inet6_opt_set_val.3 comp-c-man .man
./usr/share/man/man3/inet6_opt_next.3 comp-c-man .man
./usr/share/man/man3/inet6_opt_find.3 comp-c-man .man
./usr/share/man/man3/inet6_opt_get_val.3 comp-c-man .man
./usr/share/man/man3/inet6_rth_space.3 comp-c-man .man
./usr/share/man/man3/inet6_rth_init.3 comp-c-man .man
./usr/share/man/man3/inet6_rth_add.3 comp-c-man .man
./usr/share/man/man3/inet6_rth_reverse.3 comp-c-man .man
./usr/share/man/man3/inet6_rth_segments.3 comp-c-man .man
./usr/share/man/man3/inet6_rth_getaddr.3 comp-c-man .man
./usr/share/man/man3/inet_addr.3 comp-c-man .man
./usr/share/man/man3/inet_aton.3 comp-c-man .man
./usr/share/man/man3/inet_lnaof.3 comp-c-man .man

View File

@ -1,4 +1,4 @@
/* $NetBSD: namespace.h,v 1.115 2006/04/17 23:29:21 salo Exp $ */
/* $NetBSD: namespace.h,v 1.116 2006/05/05 00:03:21 rpaulo Exp $ */
/*-
* Copyright (c) 1997-2004 The NetBSD Foundation, Inc.
@ -364,6 +364,13 @@
#define inet6_option_init _inet6_option_init
#define inet6_option_next _inet6_option_next
#define inet6_option_space _inet6_option_space
#define inet6_opt_init _inet6_opt_init
#define inet6_opt_append _inet6_opt_append
#define inet6_opt_finish _inet6_opt_finish
#define inet6_opt_set_val _inet6_opt_set_val
#define inet6_opt_next _inet6_opt_next
#define inet6_opt_find _inet6_opt_find
#define inet6_opt_get_val _inet6_opt_get_val
#define inet6_rthdr_add _inet6_rthdr_add
#define inet6_rthdr_getaddr _inet6_rthdr_getaddr
#define inet6_rthdr_getflags _inet6_rthdr_getflags
@ -371,6 +378,12 @@
#define inet6_rthdr_lasthop _inet6_rthdr_lasthop
#define inet6_rthdr_segments _inet6_rthdr_segments
#define inet6_rthdr_space _inet6_rthdr_space
#define inet6_rth_space _inet6_rth_space
#define inet6_rth_init _inet6_rth_init
#define inet6_rth_add _inet6_rth_add
#define inet6_rth_reverse _inet6_rth_reverse
#define inet6_rth_segments _inet6_rth_segments
#define inet6_rth_getaddr _inet6_rth_getaddr
#define inet_cidr_ntop _inet_cidr_ntop
#define inet_cidr_pton _inet_cidr_pton
#define inet_lnaof _inet_lnaof

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile.inc,v 1.68 2005/01/11 06:01:41 itojun Exp $
# $NetBSD: Makefile.inc,v 1.69 2006/05/05 00:03:21 rpaulo Exp $
# @(#)Makefile.inc 8.2 (Berkeley) 9/5/93
# net sources
@ -83,7 +83,8 @@ MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \
# IPv6
MAN+= gai_strerror.3 getaddrinfo.3 getnameinfo.3 if_indextoname.3 \
inet6_option_space.3 inet6_rthdr_space.3
inet6_option_space.3 inet6_rthdr_space.3 \
inet6_opt_init.3 inet6_rth_space.3
MLINKS+=getaddrinfo.3 freeaddrinfo.3 \
getifaddrs.3 freeifaddrs.3 \
if_indextoname.3 if_nametoindex.3 if_indextoname.3 if_nameindex.3 \
@ -100,5 +101,16 @@ MLINKS+=getaddrinfo.3 freeaddrinfo.3 \
inet6_rthdr_space.3 inet6_rthdr_segments.3 \
inet6_rthdr_space.3 inet6_rthdr_getaddr.3 \
inet6_rthdr_space.3 inet6_rthdr_getflags.3 \
inet6_opt_init.3 inet6_opt_append.3 \
inet6_opt_init.3 inet6_opt_finish.3 \
inet6_opt_init.3 inet6_opt_set_val.3 \
inet6_opt_init.3 inet6_opt_next.3 \
inet6_opt_init.3 inet6_opt_find.3 \
inet6_opt_init.3 inet6_opt_get_val.3 \
inet6_rth_space.3 inet6_rth_init.3 \
inet6_rth_space.3 inet6_rth_add.3 \
inet6_rth_space.3 inet6_rth_reverse.3 \
inet6_rth_space.3 inet6_rth_segments.3 \
inet6_rth_space.3 inet6_rth_getaddr.3 \
rcmd.3 rcmd_af.3 rcmd.3 iruserok_sa.3 rcmd.3 rresvport_af.3 \
rcmd.3 orcmd_af.3

View File

@ -0,0 +1,337 @@
.\" $NetBSD: inet6_opt_init.3,v 1.1 2006/05/05 00:03:21 rpaulo Exp $
.\" $KAME: inet6_opt_init.3,v 1.7 2004/12/27 05:08:23 itojun Exp $
.\"
.\" Copyright (C) 2004 WIDE Project.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the project nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd December 23, 2004
.Dt INET6_OPT_INIT 3
.Os
.\"
.Sh NAME
.Nm inet6_opt_init ,
.Nm inet6_opt_append ,
.Nm inet6_opt_finish ,
.Nm inet6_opt_set_val ,
.Nm inet6_opt_next ,
.Nm inet6_opt_find ,
.Nm inet6_opt_get_val
.Nd IPv6 Hop-by-Hop and Destination Options manipulation
.\"
.Sh SYNOPSIS
.In netinet/in.h
.Ft "int"
.Fn inet6_opt_init "void *extbuf" "socklen_t extlen"
.Ft "int"
.Fn inet6_opt_append "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t type" "socklen_t len" "u_int8_t align" "void **databufp"
.Ft "int"
.Fn inet6_opt_finish "void *extbuf" "socklen_t extlen" "int offset"
.Ft "int"
.Fn inet6_opt_set_val "void *databuf" "int offset" "void *val" "socklen_t vallen"
.Ft "int"
.Fn inet6_opt_next "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t *typep" "socklen_t *lenp" "void **databufp"
.Ft "int"
.Fn inet6_opt_find "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t type" "socklen_t *lenp" "void **databufp"
.Ft "int"
.Fn inet6_opt_get_val "void *databuf" "socklen_t offset" "void *val" "socklen_t vallen"
.\"
.Sh DESCRIPTION
Building and parsing the Hop-by-Hop and Destination options is
complicated.
The advanced sockets API defines a set of functions to
help applications create and manipulate Hop-by-Hope and Destination
options.
.\"This man page describes the functions specified in
.\"IETF Draft RFC3542 while the
.\".Xr inet6_options_space 3
.\"man page documents the functions defined in RFC 2292.
.\"It is expected
.\"that this set of functions will supersede those in RFC 2292 but for
.\"the time being both APIs are retained.
These functions use the
formatting rules specified in Appendix B in RFC2460, i.e., that the
largest field is placed last in the option.
The function prototypes
for these functions are all contained in the
.In netinet/in.h
header file.
.\"
.Ss inet6_opt_init
The
.Fn inet6_opt_init
function
returns the number of bytes needed for an empty
extension header, one without any options.
If the
.Va extbuf
argument points to a valid section of memory
then the
.Fn inet6_opt_init
function also initializes the extension header's length field.
When attempting to initialize an extension buffer passed in the
.Va extbuf argument
.Fa extlen
must be a positive multiple of 8 or else the function fails and
returns \-1 to the caller.
.\"
.Ss inet6_opt_append
The
.Fn inet6_opt_append
function can perform to different jobs.
When a valid
.Fa extbuf
argument is supplied it appends an option to the extension buffer and
returns the updated total length as well as a pointer to the newly
created option in
.Fa databufp .
If the value
of
.Fa extbuf
is
.Dv NULL
then the
.Fn inet6_opt_append function only reports what the total length would
be if the option were actually appended.
The
.Fa len
and
.Fa align
arguments specify the length of the option and the required data
alignment which must be used when appending the option.
The
.Fa offset
argument should be the length returned by the
.Fn inet6_opt_init
function or a previous call to
.Fn inet6_opt_append .
.Pp
The
.Fa type
argument is the 8-bit option type.
.Pp
After
.Fn inet6_opt_append
has been called, the application can use the buffer pointed to by
.Fa databufp
directly, or use
.Fn inet6_opt_set_val
to specify the data to be contained in the option.
.Pp
Option types of
.Li 0
and
.Li 1
are reserved for the
.Li Pad1
and
.Li PadN
options.
All other values from 2 through 255 may be used by applications.
.Pp
The length of the option data is contained in an 8-bit value and so
may contain any value from 0 through 255.
.Pp
The
.Fa align
parameter must have a value of 1, 2, 4, or 8 and cannot exceed the
value of
.Fa len .
The alignment values represent no alignment, 16 bit, 32 bit and 64 bit
alignments respectively.
.\"
.Ss inet6_opt_finish
The
.Fn inet6_opt_finish
calculates the final padding necessary to make the extension header a
multiple of 8 bytes, as required by the IPv6 extension header
specification, and returns the extension header's updated total
length.
The
.Fa offset
argument should be the length returned by
.Fn inet6_opt_init
or
.Fn inet6_opt_append .
When
.Fa extbuf
is not
.Dv NULL
the function also sets up the appropriate padding bytes by inserting a
Pad1 or PadN option of the proper length.
.Pp
If the extension header is too small to contain the proper padding
then an error of \-1 is returned to the caller.
.\"
.Ss inet6_opt_set_val
The
.Fn inet6_opt_set_val
function inserts data items of various sizes into the data portion of
the option.
The
.Fa databuf
argument is a pointer to memory that was returned by the
.Fn inet6_opt_append
call and the
.Fa offset argument specifies where the option should be placed in the
data buffer.
The
.Fa val
argument points to an area of memory containing the data to be
inserted into the extension header, and the
.Fa vallen
argument indicates how much data to copy.
.Pp
The caller should ensure that each field is aligned on its natural
boundaries as described in Appendix B of RFC2460.
.Pp
The function returns the offset for the next field which is calculated as
.Fa offset
+
.Fa vallen
and is used when composing options with multiple fields.
.\"
.Ss inet6_opt_next
The
.Fn inet6_opt_next
function parses received extension headers.
The
.Fa extbuf
and
.Fa extlen
arguments specify the location and length of the extension header
being parsed.
The
.Fa offset
argument should either be zero, for the first option, or the length value
returned by a previous call to
.Fn inet6_opt_next
or
.Fn inet6_opt_find .
The return value specifies the position where to continue scanning the
extension buffer.
The option is returned in the arguments
.Fa typep , lenp ,
and
.Fa databufp .
.Fa typep, lenp,
and
.Fa databufp
point to the 8-bit option type, the 8-bit option length and the option
data respectively.
This function does not return any PAD1 or PADN options.
When an error occurs or there are no more options the return
value is \-1.
.\"
.Ss inet6_opt_find
The
.Fn inet6_opt_find
function searches the extension buffer for a particular option type,
passed in through the
.Fa type
argument.
If the option is found then the
.Fa lenp
and
.Fa databufp
arguments are updated to point to the option's length and data
respectively.
.Fa extbuf
and
.Fa extlen
must point to a valid extension buffer and give its length.
The
.Fa offset
argument can be used to search from a location anywhere in the
extension header.
.Ss inet6_opt_get_val
The
.Fn inet6_opt_get_val
function extracts data items of various sizes in the data portion of
the option.
The
.Fa databuf
is a pointer returned by the
.Fn inet6_opt_next
or
.Fn inet6_opt_find
functions.
The
.Fa val
argument points where the data will be extracted.
The
.Fa offset
argument specifies from where in the data portion of the option the
value should be extracted; the first byte of option data is specified
by an offset of zero.
.Pp
It is expected that each field is aligned on its natural boundaries as
described in Appendix B of RFC2460.
.Pp
The function returns the offset for the next field
by calculating
.Fa offset
+
.Fa vallen
which can be used when extracting option content with multiple fields.
Robust receivers must verify alignment before calling this function.
.\"
.Sh DIAGNOSTICS
All the functions return
\-1
on an error.
.\"
.Sh EXAMPLES
RFC3542 gives comprehensive examples in Section 23.
.Pp
KAME also provides examples in the
.Pa advapitest
directory of its kit.
.\"
.Sh SEE ALSO
.Rs
.%A W. Stevens
.%A M. Thomas
.%A E. Nordmark
.%A T. Jinmei
.%T "Advanced Sockets API for IPv6"
.%N RFC3542
.%D October 2002
.Re
.Rs
.%A S. Deering
.%A R. Hinden
.%T "Internet Protocol, Version 6 (IPv6) Specification"
.%N RFC2460
.%D December 1998
.Re
.Sh HISTORY
The implementation first appeared in KAME advanced networking kit.
.Sh STANDARDS
The functions are documented in
.Dq Advanced Sockets API for IPv6
.Pq RFC3542 .
.\"

View File

@ -0,0 +1,223 @@
.\" $NetBSD: inet6_rth_space.3,v 1.1 2006/05/05 00:03:21 rpaulo Exp $
.\" $KAME: inet6_rth_space.3,v 1.7 2005/01/05 03:00:44 itojun Exp $
.\"
.\" Copyright (C) 2004 WIDE Project.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. Neither the name of the project nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd December 24, 2004
.Dt INET6_RTH_SPACE 3
.Os
.\"
.Sh NAME
.Nm inet6_rth_space ,
.Nm inet6_rth_init ,
.Nm inet6_rth_add ,
.Nm inet6_rth_reverse ,
.Nm inet6_rth_segments ,
.Nm inet6_rth_getaddr
.Nd IPv6 Routing Header Options manipulation
.\"
.Sh SYNOPSIS
.In netinet/in.h
.Ft socklen_t
.Fn inet6_rth_space "int" "int"
.Ft "void *"
.Fn inet6_rth_init "void *" "socklen_t" "int" "int"
.Ft int
.Fn inet6_rth_add "void *" "const struct in6_addr *"
.Ft int
.Fn inet6_rth_reverse "const void *" "void *"
.Ft int
.Fn inet6_rth_segments "const void *"
.Ft "struct in6_addr *"
.Fn inet6_rth_getaddr "const void *" "int"
.\"
.Sh DESCRIPTION
The IPv6 Advanced API, RFC 3542, defines the functions that an
application calls to build and examine IPv6 Routing headers.
Routing headers are used to perform source routing in IPv6 networks.
The RFC uses the word
.Dq segments
to describe addresses and that is the term used here as well.
All of the functions are defined in the
.In netinet/in.h
header file.
The functions described in this manual page all operate
on routing header structures which are defined in
.In netinet/ip6.h
but which should not need to be modified outside the use of this API.
The size and shape of the route header structures may change, so using
the APIs is a more portable, long term, solution.
.Pp
The functions in the API are split into two groups, those that build a
routing header and those that parse a received routing header.
We will describe the builder functions followed by the parser functions.
.Ss inet6_rth_space
The
.Fn inet6_rth_space
function returns the number of bytes required to hold a Routing Header
of the type, specified in the
.Fa type
argument and containing the number of addresses specified in the
.Fa segments
argumment.
When the type is
.Dv IPV6_RTHDR_TYPE_0
the number of segments must be from 0 through 127.
Routing headers of type
.Dv IPV6_RTHDR_TYPE_2
contain only one segment, and are only used with Mobile IPv6.
The return value from this function is the number of bytes required to
store the routing header.
If the value 0 is returned then either the
route header type was not recognized or another error occurred.
.Ss inet6_rth_init
The
.Fn inet6_rth_init
function initializes the pre-allocated buffer pointed to by
.Fa bp
to contain a routing header of the specified type The
.Fa bp_len
argument is used to verify that the buffer is large enough.
The caller must allocate the buffer pointed to by bp.
The necessary buffer size should be determined by calling
.Fn inet6_rth_space
described in the previous sections.
.Pp
The
.Fn inet6_rth_init
function returns a pointer to
.Fa bp
on success and
.Dv NULL
when there is an error.
.Ss inet6_rth_add
The
.Fn inet6_rth_add
function adds the IPv6 address pointed to by
.Fa addr
to the end of the routing header being constructed.
.Pp
A successful addition results in the function returning 0, otherwise
\-1 is returned.
.Ss inet6_rth_reverse
The
.Fn inet6_rth_reverse
function takes a routing header, pointed to by the
argument
.Fa in ,
and writes a new routing header into the argument pointed to by
.Fa out .
The routing header at that sends datagrams along the reverse of that
route.
Both arguments are allowed to point to the same buffer meaning
that the reversal can occur in place.
.Pp
The return value of the function is 0 on success, or \-1 when
there is an error.
.\"
.Pp
The next set of functions operate on a routing header that the
application wants to parse.
In the usual case such a routing header
is received from the network, although these functions can also be
used with routing headers that the application itself created.
.Ss inet6_rth_segments
The
.Fn inet6_rth_segments
function returns the number of segments contained in the
routing header pointed to by
.Fa bp .
The return value is the number of segments contained in the routing
header, or \-1 if an error occurred.
It is not an error for 0 to be
returned as a routing header may contain 0 segments.
.\"
.Ss inet6_rth_getaddr
The
.Fn inet6_rth_getaddr
function is used to retrieve a single address from a routing header.
The
.Fa index
is the location in the routing header from which the application wants
to retrieve an address.
The
.Fa index
parameter must have a value between 0 and one less than the number of
segments present in the routing header.
The
.Fn inet6_rth_segments
function, described in the last section, should be used to determine
the total number of segments in the routing header.
The
.Fn inet6_rth_getaddr
function returns a pointer to an IPv6 address on success or
.Dv NULL
when an error has occurred.
.\"
.Sh DIAGNOSTICS
The
.Fn inet6_rth_space
and
.Fn inet6_rth_getaddr
functions return 0 on errors.
.Pp
The
.Fn inet6_rthdr_init
function returns
.Dv NULL
on error.
The
.Fn inet6_rth_add
and
.Fn inet6_rth_reverse
functions return 0 on success, or \-1 upon an error.
.\"
.Sh EXAMPLES
RFC 3542 gives extensive examples in Section 21, Appendix B.
.Pp
KAME also provides examples in the advapitest directory of its kit.
.\"
.Sh SEE ALSO
.Rs
.%A W. Stevens
.%A M. Thomas
.%A E. Nordmark
.%A T. Jinmei
.%T "Advanced Sockets API for IPv6"
.%N RFC 3542
.%D May 2003
.Re
.Rs
.%A S. Deering
.%A R. Hinden
.%T "Internet Protocol, Version 6 (IPv6) Specification"
.%N RFC2460
.%D December 1998
.Re
.Sh HISTORY
The implementation first appeared in KAME advanced networking kit.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6opt.c,v 1.10 2005/11/29 03:11:59 christos Exp $ */
/* $NetBSD: ip6opt.c,v 1.11 2006/05/05 00:03:21 rpaulo Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: ip6opt.c,v 1.10 2005/11/29 03:11:59 christos Exp $");
__RCSID("$NetBSD: ip6opt.c,v 1.11 2006/05/05 00:03:21 rpaulo Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@ -53,6 +53,13 @@ __weak_alias(inet6_option_find,_inet6_option_find)
__weak_alias(inet6_option_init,_inet6_option_init)
__weak_alias(inet6_option_next,_inet6_option_next)
__weak_alias(inet6_option_space,_inet6_option_space)
__weak_alias(inet6_opt_init, _inet6_opt_init)
__weak_alias(inet6_opt_append, _inet6_opt_append)
__weak_alias(inet6_opt_finish, _inet6_opt_finish)
__weak_alias(inet6_opt_set_val, _inet6_opt_set_val)
__weak_alias(inet6_opt_next, _inet6_opt_next)
__weak_alias(inet6_opt_find, _inet6_opt_find)
__weak_alias(inet6_opt_get_val, _inet6_opt_get_val)
#endif
static int ip6optlen(u_int8_t *opt, u_int8_t *lim);
@ -153,6 +160,7 @@ inet6_option_append(cmsg, typep, multx, plusy)
padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
(off % multx);
padlen += plusy;
padlen %= multx; /* keep the pad as short as possible */
/* insert padding */
inet6_insert_padopt(bp, padlen);
cmsg->cmsg_len += padlen;
@ -232,6 +240,7 @@ inet6_option_alloc(cmsg, datalen, multx, plusy)
padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
(off % multx);
padlen += plusy;
padlen %= multx; /* keep the pad as short as possible */
/* insert padding */
inet6_insert_padopt(bp, padlen);
cmsg->cmsg_len += padlen;
@ -428,3 +437,222 @@ inet6_insert_padopt(u_char *p, size_t len)
return;
}
}
/*
* The following functions are defined in RFC3542, which is a successor
* of RFC2292.
*/
int
inet6_opt_init(void *extbuf, socklen_t extlen)
{
struct ip6_ext *ext = (struct ip6_ext *)extbuf;
if (extlen % 8)
return (-1);
if (ext) {
if (extlen == 0)
return (-1);
ext->ip6e_len = (extlen >> 3) - 1;
}
return (2); /* sizeof the next and the length fields */
}
int
inet6_opt_append(void *extbuf, socklen_t extlen, int offset, u_int8_t type,
socklen_t len, u_int8_t align, void **databufp)
{
int currentlen = offset;
size_t padlen = 0;
/*
* The option type must have a value from 2 to 255, inclusive.
* (0 and 1 are reserved for the Pad1 and PadN options, respectively.)
*/
if (type < 2)
return (-1);
/*
* The option data length must have a value between 0 and 255,
* inclusive, and is the length of the option data that follows.
*/
if (len > 255)
return (-1);
/*
* The align parameter must have a value of 1, 2, 4, or 8.
* The align value can not exceed the value of len.
*/
if (align != 1 && align != 2 && align != 4 && align != 8)
return (-1);
if (align > len)
return (-1);
/* Calculate the padding length. */
currentlen += 2 + len; /* 2 means "type + len" */
if (currentlen % align)
padlen = align - (currentlen % align);
/* The option must fit in the extension header buffer. */
currentlen += padlen;
if (extlen && /* XXX: right? */
currentlen > extlen)
return (-1);
if (extbuf) {
u_int8_t *optp = (u_int8_t *)extbuf + offset;
if (padlen == 1) {
/* insert a Pad1 option */
*optp = IP6OPT_PAD1;
optp++;
} else if (padlen > 0) {
/* insert a PadN option for alignment */
*optp++ = IP6OPT_PADN;
*optp++ = padlen - 2;
memset(optp, 0, padlen - 2);
optp += (padlen - 2);
}
*optp++ = type;
*optp++ = len;
*databufp = optp;
}
return (currentlen);
}
int
inet6_opt_finish(void *extbuf, socklen_t extlen, int offset)
{
int updatelen = offset > 0 ? (1 + ((offset - 1) | 7)) : 0;;
if (extbuf) {
u_int8_t *padp;
size_t padlen = updatelen - offset;
if (updatelen > extlen)
return (-1);
padp = (u_int8_t *)extbuf + offset;
if (padlen == 1)
*padp = IP6OPT_PAD1;
else if (padlen > 0) {
*padp++ = IP6OPT_PADN;
*padp++ = (padlen - 2);
memset(padp, 0, padlen - 2);
}
}
return (updatelen);
}
int
inet6_opt_set_val(void *databuf, int offset, void *val, socklen_t vallen)
{
memcpy((u_int8_t *)databuf + offset, val, vallen);
return (offset + vallen);
}
int
inet6_opt_next(void *extbuf, socklen_t extlen, int offset, u_int8_t *typep,
socklen_t *lenp, void **databufp)
{
u_int8_t *optp, *lim;
int optlen;
/* Validate extlen. XXX: is the variable really necessary?? */
if (extlen == 0 || (extlen % 8))
return (-1);
lim = (u_int8_t *)extbuf + extlen;
/*
* If this is the first time this function called for this options
* header, simply return the 1st option.
* Otherwise, search the option list for the next option.
*/
if (offset == 0)
optp = (u_int8_t *)(void *)((struct ip6_hbh *)extbuf + 1);
else
optp = (u_int8_t *)extbuf + offset;
/* Find the next option skipping any padding options. */
while (optp < lim) {
switch(*optp) {
case IP6OPT_PAD1:
optp++;
break;
case IP6OPT_PADN:
if ((optlen = ip6optlen(optp, lim)) == 0)
goto optend;
optp += optlen;
break;
default: /* found */
if ((optlen = ip6optlen(optp, lim)) == 0)
goto optend;
*typep = *optp;
*lenp = optlen - 2;
*databufp = optp + 2;
return (optp + optlen - (u_int8_t *)extbuf);
}
}
optend:
*databufp = NULL; /* for safety */
return (-1);
}
int
inet6_opt_find(void *extbuf, socklen_t extlen, int offset, u_int8_t type,
socklen_t *lenp, void **databufp)
{
u_int8_t *optp, *lim;
int optlen;
/* Validate extlen. XXX: is the variable really necessary?? */
if (extlen == 0 || (extlen % 8))
return (-1);
lim = (u_int8_t *)extbuf + extlen;
/*
* If this is the first time this function called for this options
* header, simply return the 1st option.
* Otherwise, search the option list for the next option.
*/
if (offset == 0)
optp = (u_int8_t *)(void *)((struct ip6_hbh *)extbuf + 1);
else
optp = (u_int8_t *)extbuf + offset;
/* Find the specified option */
while (optp < lim) {
if ((optlen = ip6optlen(optp, lim)) == 0)
goto optend;
if (*optp == type) { /* found */
*lenp = optlen - 2;
*databufp = optp + 2;
return (optp + optlen - (u_int8_t *)extbuf);
}
optp += optlen;
}
optend:
*databufp = NULL; /* for safety */
return (-1);
}
int
inet6_opt_get_val(void *databuf, int offset, void *val, socklen_t vallen)
{
/* we can't assume alignment here */
memcpy(val, (u_int8_t *)databuf + offset, vallen);
return (offset + vallen);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: rthdr.c,v 1.15 2005/11/29 03:12:00 christos Exp $ */
/* $NetBSD: rthdr.c,v 1.16 2006/05/05 00:03:21 rpaulo Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: rthdr.c,v 1.15 2005/11/29 03:12:00 christos Exp $");
__RCSID("$NetBSD: rthdr.c,v 1.16 2006/05/05 00:03:21 rpaulo Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@ -54,8 +54,18 @@ __weak_alias(inet6_rthdr_init,_inet6_rthdr_init)
__weak_alias(inet6_rthdr_lasthop,_inet6_rthdr_lasthop)
__weak_alias(inet6_rthdr_segments,_inet6_rthdr_segments)
__weak_alias(inet6_rthdr_space,_inet6_rthdr_space)
__weak_alias(inet6_rth_space, _inet6_rth_space)
__weak_alias(inet6_rth_init, _inet6_rth_init)
__weak_alias(inet6_rth_add, _inet6_rth_add)
__weak_alias(inet6_rth_reverse, _inet6_rth_reverse)
__weak_alias(inet6_rth_segments, _inet6_rth_segments)
__weak_alias(inet6_rth_getaddr, _inet6_rth_getaddr)
#endif
/*
* RFC2292 API
*/
size_t
inet6_rthdr_space(type, seg)
int type, seg;
@ -89,7 +99,12 @@ inet6_rthdr_init(bp, type)
switch (type) {
case IPV6_RTHDR_TYPE_0:
#ifdef COMPAT_RFC2292
ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0) -
sizeof(struct in6_addr));
#else
ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0));
#endif
(void)memset(rthdr, 0, sizeof(struct ip6_rthdr0));
rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
return (ch);
@ -115,10 +130,12 @@ inet6_rthdr_add(cmsg, addr, flags)
case IPV6_RTHDR_TYPE_0:
{
struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)(void *)rthdr;
if (flags != IPV6_RTHDR_LOOSE)
if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT)
return (-1);
if (rt0->ip6r0_segleft == 23)
return (-1);
if (flags != IPV6_RTHDR_LOOSE)
return (-1);
rt0->ip6r0_segleft++;
(void)memcpy(((caddr_t)(void *)rt0) +
((rt0->ip6r0_len + 1) << 3), addr, sizeof(struct in6_addr));
@ -148,10 +165,10 @@ inet6_rthdr_lasthop(cmsg, flags)
case IPV6_RTHDR_TYPE_0:
{
struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)(void *)rthdr;
if (flags != IPV6_RTHDR_LOOSE)
return (-1);
if (rt0->ip6r0_segleft > 23)
return (-1);
if (flags != IPV6_RTHDR_LOOSE)
return (-1);
break;
}
default:
@ -221,7 +238,11 @@ inet6_rthdr_getaddr(cmsg, idx)
naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
if (idx <= 0 || naddr < idx)
return NULL;
#ifdef COMPAT_RFC2292
return ((struct in6_addr *)(void *)(rt0 + 1)) + idx - 1;
#else
return ((struct in6_addr *)(void *)(rt0 + 1)) + idx;
#endif
}
default:
@ -259,3 +280,183 @@ inet6_rthdr_getflags(cmsg, idx)
return (-1);
}
}
/*
* RFC3542 (2292bis) API
*/
socklen_t
inet6_rth_space(int type, int segments)
{
switch (type) {
case IPV6_RTHDR_TYPE_0:
return (((segments * 2) + 1) << 3);
default:
return (0); /* type not suppported */
}
}
void *
inet6_rth_init(void *bp, socklen_t bp_len, int type, int segments)
{
struct ip6_rthdr *rth;
struct ip6_rthdr0 *rth0;
_DIAGASSERT(bp != NULL);
rth = (struct ip6_rthdr *)bp;
switch (type) {
case IPV6_RTHDR_TYPE_0:
/* length validation */
if (bp_len < inet6_rth_space(IPV6_RTHDR_TYPE_0, segments))
return (NULL);
memset(bp, 0, bp_len);
rth0 = (struct ip6_rthdr0 *)(void *)rth;
rth0->ip6r0_len = segments * 2;
rth0->ip6r0_type = IPV6_RTHDR_TYPE_0;
rth0->ip6r0_segleft = 0;
rth0->ip6r0_reserved = 0;
break;
default:
return (NULL); /* type not supported */
}
return (bp);
}
int
inet6_rth_add(void *bp, const struct in6_addr *addr)
{
struct ip6_rthdr *rth;
struct ip6_rthdr0 *rth0;
struct in6_addr *nextaddr;
_DIAGASSERT(bp != NULL);
rth = (struct ip6_rthdr *)bp;
switch (rth->ip6r_type) {
case IPV6_RTHDR_TYPE_0:
rth0 = (struct ip6_rthdr0 *)(void *)rth;
nextaddr = (struct in6_addr *)(void *)(rth0 + 1)
+ rth0->ip6r0_segleft;
*nextaddr = *addr;
rth0->ip6r0_segleft++;
break;
default:
return (-1); /* type not supported */
}
return (0);
}
int
inet6_rth_reverse(const void *in, void *out)
{
const struct ip6_rthdr *rth_in;
const struct ip6_rthdr0 *rth0_in;
struct ip6_rthdr0 *rth0_out;
int i, segments;
_DIAGASSERT(in != NULL);
_DIAGASSERT(out != NULL);
rth_in = (const struct ip6_rthdr *)in;
switch (rth_in->ip6r_type) {
case IPV6_RTHDR_TYPE_0:
rth0_in = (const struct ip6_rthdr0 *)in;
rth0_out = (struct ip6_rthdr0 *)out;
/* parameter validation XXX too paranoid? */
if (rth0_in->ip6r0_len % 2)
return (-1);
segments = rth0_in->ip6r0_len / 2;
/* we can't use memcpy here, since in and out may overlap */
memmove((void *)rth0_out, (const void *)rth0_in,
(unsigned int)(((rth0_in->ip6r0_len) + 1) << 3));
rth0_out->ip6r0_segleft = segments;
/* reverse the addresses */
for (i = 0; i < segments / 2; i++) {
struct in6_addr addr_tmp, *addr1, *addr2;
addr1 = (struct in6_addr *)(void *)(rth0_out + 1) + i;
addr2 = (struct in6_addr *)(void *)(rth0_out + 1) +
(segments - i - 1);
addr_tmp = *addr1;
*addr1 = *addr2;
*addr2 = addr_tmp;
}
break;
default:
return (-1); /* type not supported */
}
return (0);
}
int
inet6_rth_segments(const void *bp)
{
const struct ip6_rthdr *rh;
const struct ip6_rthdr0 *rh0;
unsigned int addrs;
_DIAGASSERT(bp != NULL);
rh = (const struct ip6_rthdr *)bp;
switch (rh->ip6r_type) {
case IPV6_RTHDR_TYPE_0:
rh0 = (const struct ip6_rthdr0 *)bp;
/*
* Validation for a type-0 routing header.
* Is this too strict?
*/
if ((rh0->ip6r0_len % 2) != 0 ||
(addrs = (rh0->ip6r0_len / 2)) < rh0->ip6r0_segleft)
return (-1);
return (addrs);
default:
return (-1); /* unknown type */
}
}
struct in6_addr *
inet6_rth_getaddr(const void *bp, int idx)
{
const struct ip6_rthdr *rh;
const struct ip6_rthdr0 *rh0;
unsigned int addrs;
_DIAGASSERT(bp != NULL);
rh = (const struct ip6_rthdr *)bp;
switch (rh->ip6r_type) {
case IPV6_RTHDR_TYPE_0:
rh0 = (const struct ip6_rthdr0 *)bp;
/*
* Validation for a type-0 routing header.
* Is this too strict?
*/
if ((rh0->ip6r0_len % 2) != 0 ||
(addrs = (rh0->ip6r0_len / 2)) < rh0->ip6r0_segleft)
return (NULL);
if (idx < 0 || addrs <= idx)
return (NULL);
return (((struct in6_addr *)(void *)__UNCONST(rh0 + 1)) + idx);
default:
return (NULL); /* unknown type */
}
}

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.9 2005/06/27 01:00:06 christos Exp $
# $NetBSD: Makefile,v 1.10 2006/05/05 00:03:22 rpaulo Exp $
PROG= ping6
MAN= ping6.8
@ -8,6 +8,7 @@ BINMODE=4555
CPPFLAGS+=-DINET6
CPPFLAGS+=-DIPSEC
CPPFLAGS+=-DUSE_RFC3542
LDADD+= -lipsec -lm
DPADD+= ${LIBIPSEC} ${LIBM}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ping6.8,v 1.25 2003/09/07 16:22:23 wiz Exp $
.\" $NetBSD: ping6.8,v 1.26 2006/05/05 00:03:22 rpaulo Exp $
.\" $KAME: ping6.8,v 1.57 2002/05/26 13:18:25 itojun Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -39,7 +39,7 @@ packets to network hosts
.Sh SYNOPSIS
.Nm ping6
.\" without IPsec, or new IPsec
.Op Fl dfHnNqRtvwW
.Op Fl dfHmnNqRtvwW
.\" old IPsec
.\" .Op Fl AdEfnNqRtvwW
.Bk -words
@ -195,6 +195,16 @@ is specified,
sends that many packets as fast as possible before falling into its normal
mode of behavior.
Only the super-user may use this option.
.It Fl m
By default,
.Nm
asks the kernel to fragment packets to fit into the minimum IPv6 MTU.
.Fl m
will suppress the behavior in the following two levels:
when the option is specified once, the behavior will be disabled for
unicast packets.
When the option is specified more than once, it will be disabled for both
unicast and multicast packets.
.It Fl n
Numeric output only.
No attempt will be made to lookup symbolic names from addresses in the reply.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ping6.c,v 1.65 2006/03/17 02:31:03 elad Exp $ */
/* $NetBSD: ping6.c,v 1.66 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: ping6.c,v 1.164 2002/11/16 14:05:37 itojun Exp $ */
/*
@ -77,7 +77,7 @@ static char sccsid[] = "@(#)ping.c 8.1 (Berkeley) 6/5/93";
#else
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: ping6.c,v 1.65 2006/03/17 02:31:03 elad Exp $");
__RCSID("$NetBSD: ping6.c,v 1.66 2006/05/05 00:03:22 rpaulo Exp $");
#endif
#endif
@ -299,7 +299,7 @@ main(int argc, char *argv[])
#endif
int usepktinfo = 0;
struct in6_pktinfo *pktinfo = NULL;
#ifdef USE_RFC2292BIS
#ifdef USE_RFC3542
struct ip6_rthdr *rthdr = NULL;
#endif
#ifdef IPSEC_POLICY_IPSEC
@ -566,7 +566,7 @@ main(int argc, char *argv[])
}
if (argc > 1) {
#ifdef IPV6_RECVRTHDR /* 2292bis */
#ifdef IPV6_RECVRTHDR /* RFC3542 */
rthlen = CMSG_SPACE(inet6_rth_space(IPV6_RTHDR_TYPE_0,
argc - 1));
#else /* RFC2292 */
@ -872,11 +872,11 @@ main(int argc, char *argv[])
if (argc > 1) { /* some intermediate addrs are specified */
int hops, error;
#ifdef USE_RFC2292BIS
#ifdef USE_RFC3542
int rthdrlen;
#endif
#ifdef USE_RFC2292BIS
#ifdef USE_RFC3542
rthdrlen = inet6_rth_space(IPV6_RTHDR_TYPE_0, argc - 1);
scmsgp->cmsg_len = CMSG_LEN(rthdrlen);
scmsgp->cmsg_level = IPPROTO_IPV6;
@ -890,7 +890,7 @@ main(int argc, char *argv[])
if ((scmsgp = (struct cmsghdr *)inet6_rthdr_init(scmsgp,
IPV6_RTHDR_TYPE_0)) == 0)
errx(1, "can't initialize rthdr");
#endif /* USE_RFC2292BIS */
#endif /* USE_RFC3542 */
for (hops = 0; hops < argc - 1; hops++) {
struct addrinfo *iaip;
@ -902,7 +902,7 @@ main(int argc, char *argv[])
errx(1,
"bad addr family of an intermediate addr");
#ifdef USE_RFC2292BIS
#ifdef USE_RFC3542
if (inet6_rth_add(rthdr,
&(SIN6(iaip->ai_addr))->sin6_addr))
errx(1, "can't add an intermediate node");
@ -911,11 +911,11 @@ main(int argc, char *argv[])
&(SIN6(iaip->ai_addr))->sin6_addr,
IPV6_RTHDR_LOOSE))
errx(1, "can't add an intermediate node");
#endif /* USE_RFC2292BIS */
#endif /* USE_RFC3542 */
freeaddrinfo(iaip);
}
#ifndef USE_RFC2292BIS
#ifndef USE_RFC3542
if (inet6_rthdr_lasthop(scmsgp, IPV6_RTHDR_LOOSE))
errx(1, "can't set the last flag");
#endif
@ -939,7 +939,7 @@ main(int argc, char *argv[])
src.sin6_port = ntohs(DUMMY_PORT);
src.sin6_scope_id = dst.sin6_scope_id;
#ifdef USE_RFC2292BIS
#ifdef USE_RFC3542
if (pktinfo &&
setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO,
(void *)pktinfo, sizeof(*pktinfo)))
@ -1728,7 +1728,7 @@ pr_exthdrs(struct msghdr *mhdr)
}
}
#ifdef USE_RFC2292BIS
#ifdef USE_RFC3542
void
pr_ip6opt(void *extbuf)
{
@ -1779,7 +1779,7 @@ pr_ip6opt(void *extbuf)
}
return;
}
#else /* !USE_RFC2292BIS */
#else /* !USE_RFC3542 */
/* ARGSUSED */
void
pr_ip6opt(void *extbuf)
@ -1787,9 +1787,9 @@ pr_ip6opt(void *extbuf)
putchar('\n');
return;
}
#endif /* USE_RFC2292BIS */
#endif /* USE_RFC3542 */
#ifdef USE_RFC2292BIS
#ifdef USE_RFC3542
void
pr_rthdr(void *extbuf)
{
@ -1823,7 +1823,7 @@ pr_rthdr(void *extbuf)
}
#else /* !USE_RFC2292BIS */
#else /* !USE_RFC3542 */
/* ARGSUSED */
void
pr_rthdr(void *extbuf)
@ -1831,7 +1831,7 @@ pr_rthdr(void *extbuf)
putchar('\n');
return;
}
#endif /* USE_RFC2292BIS */
#endif /* USE_RFC3542 */
int
pr_bitrange(u_int32_t v, int soff, int ii)

View File

@ -1,4 +1,4 @@
# $NetBSD: std,v 1.4 2005/12/11 12:20:30 christos Exp $
# $NetBSD: std,v 1.5 2006/05/05 00:03:21 rpaulo Exp $
#
# standard MI 'options'
#
@ -10,3 +10,4 @@
options VMSWAP # Swap device/file support
options BUFQ_FCFS # First-come First-serve strategy
options BUFQ_DISKSORT # Traditional min seek sort strategy
options RFC2292 # Previous version of Adv. Sockets API for IPv6

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6.h,v 1.20 2005/12/10 23:36:23 elad Exp $ */
/* $NetBSD: ip6.h,v 1.21 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: ip6.h,v 1.45 2003/06/05 04:46:38 keiichi Exp $ */
/*
@ -154,7 +154,7 @@ struct ip6_dest {
#define IP6OPT_NSAP_ADDR 0xC3 /* 11 0 00011 */
#define IP6OPT_TUNNEL_LIMIT 0x04 /* 00 0 00100 */
#define IP6OPT_RTALERT 0x05 /* 00 0 00101 (KAME definition) */
#define IP6OPT_ROUTER_ALERT 0x05 /* (2292bis def, recommended) */
#define IP6OPT_ROUTER_ALERT 0x05 /* (RFC3542 def, recommended) */
#define IP6OPT_RTALERT_LEN 4
#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */

View File

@ -1,4 +1,6 @@
# $NetBSD: files.netinet6,v 1.4 2006/01/21 00:15:36 rpaulo Exp $
# $NetBSD: files.netinet6,v 1.5 2006/05/05 00:03:22 rpaulo Exp $
defflag opt_inet6.h RFC2292
# NOTE: netinet/files.netinet must be included before this one!

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6.h,v 1.53 2006/03/29 21:29:59 dyoung Exp $ */
/* $NetBSD: in6.h,v 1.54 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */
/*
@ -68,6 +68,8 @@
#error "do not include netinet6/in6.h directly, include netinet/in.h. see RFC2553"
#endif
#include <sys/socket.h>
/*
* Identification of the network protocol stack
* for *BSD-current/release: http://www.kame.net/dev/cvsweb.cgi/kame/COVERAGE
@ -403,13 +405,16 @@ struct route_in6 {
#if defined(_NETBSD_SOURCE)
#define ICMP6_FILTER 18 /* icmp6_filter; icmp6 filter */
#endif
#define IPV6_PKTINFO 19 /* bool; send/rcv if, src/dst addr */
#define IPV6_HOPLIMIT 20 /* bool; hop limit */
#define IPV6_NEXTHOP 21 /* bool; next hop addr */
#define IPV6_HOPOPTS 22 /* bool; hop-by-hop option */
#define IPV6_DSTOPTS 23 /* bool; destination option */
#define IPV6_RTHDR 24 /* bool; routing header */
#define IPV6_PKTOPTIONS 25 /* buf/cmsghdr; set/get IPv6 options */
/* RFC2292 options */
#ifdef _KERNEL
#define IPV6_2292PKTINFO 19 /* bool; send/recv if, src/dst addr */
#define IPV6_2292HOPLIMIT 20 /* bool; hop limit */
#define IPV6_2292NEXTHOP 21 /* bool; next hop addr */
#define IPV6_2292HOPOPTS 22 /* bool; hop-by-hop option */
#define IPV6_2292DSTOPTS 23 /* bool; destinaion option */
#define IPV6_2292RTHDR 24 /* bool; routing header */
#define IPV6_2292PKTOPTIONS 25 /* buf/cmsghdr; set/get IPv6 options */
#endif
#define IPV6_CHECKSUM 26 /* int; checksum offset for raw socket */
#define IPV6_V6ONLY 27 /* bool; make AF_INET6 sockets v6 only */
@ -417,7 +422,38 @@ struct route_in6 {
#define IPV6_IPSEC_POLICY 28 /* struct; get/set security policy */
#endif
#define IPV6_FAITH 29 /* bool; accept FAITH'ed connections */
/* new socket options introduced in RFC3542 */
#define IPV6_RTHDRDSTOPTS 35 /* ip6_dest; send dst option before rthdr */
#define IPV6_RECVPKTINFO 36 /* bool; recv if, dst addr */
#define IPV6_RECVHOPLIMIT 37 /* bool; recv hop limit */
#define IPV6_RECVRTHDR 38 /* bool; recv routing header */
#define IPV6_RECVHOPOPTS 39 /* bool; recv hop-by-hop option */
#define IPV6_RECVDSTOPTS 40 /* bool; recv dst option after rthdr */
#ifdef _KERNEL
#define IPV6_RECVRTHDRDSTOPTS 41 /* bool; recv dst option before rthdr */
#endif
#define IPV6_USE_MIN_MTU 42 /* bool; send packets at the minimum MTU */
#define IPV6_RECVPATHMTU 43 /* bool; notify an according MTU */
#define IPV6_PATHMTU 44 /* mtuinfo; get the current path MTU (sopt),
4 bytes int; MTU notification (cmsg) */
/* more new socket options introduced in RFC3542 */
#define IPV6_PKTINFO 46 /* in6_pktinfo; send if, src addr */
#define IPV6_HOPLIMIT 47 /* int; send hop limit */
#define IPV6_NEXTHOP 48 /* sockaddr; next hop addr */
#define IPV6_HOPOPTS 49 /* ip6_hbh; send hop-by-hop option */
#define IPV6_DSTOPTS 50 /* ip6_dest; send dst option befor rthdr */
#define IPV6_RTHDR 51 /* ip6_rthdr; send routing header */
#define IPV6_RECVTCLASS 57 /* bool; recv traffic class values */
#ifdef _KERNEL
#define IPV6_OTCLASS 58 /* u_int8_t; send traffic class value */
#endif
#define IPV6_TCLASS 61 /* int; send traffic class value */
#define IPV6_DONTFRAG 62 /* bool; disable IPv6 fragmentation */
/* to define items, should talk with KAME guys first, for *BSD compatibility */
#define IPV6_RTHDR_LOOSE 0 /* this hop need not be a neighbor. XXX old spec */
@ -446,6 +482,14 @@ struct in6_pktinfo {
unsigned int ipi6_ifindex; /* send/recv interface index */
};
/*
* Control structure for IPV6_RECVPATHMTU socket option.
*/
struct ip6_mtuinfo {
struct sockaddr_in6 ip6m_addr; /* or sockaddr_storage? */
u_int32_t ip6m_mtu;
};
/*
* Argument for IPV6_PORTRANGE:
* - which range to search when port is unspecified at bind() or connect()
@ -708,6 +752,24 @@ extern int inet6_rthdr_reverse __P((const struct cmsghdr *, struct cmsghdr *));
extern int inet6_rthdr_segments __P((const struct cmsghdr *));
extern struct in6_addr *inet6_rthdr_getaddr __P((struct cmsghdr *, int));
extern int inet6_rthdr_getflags __P((const struct cmsghdr *, int));
extern int inet6_opt_init __P((void *, socklen_t));
extern int inet6_opt_append __P((void *, socklen_t, int, u_int8_t,
socklen_t, u_int8_t, void **));
extern int inet6_opt_finish __P((void *, socklen_t, int));
extern int inet6_opt_set_val __P((void *, int, void *, socklen_t));
extern int inet6_opt_next __P((void *, socklen_t, int, u_int8_t *,
socklen_t *, void **));
extern int inet6_opt_find __P((void *, socklen_t, int, u_int8_t,
socklen_t *, void **));
extern int inet6_opt_get_val __P((void *, int, void *, socklen_t));
extern socklen_t inet6_rth_space __P((int, int));
extern void *inet6_rth_init __P((void *, socklen_t, int, int));
extern int inet6_rth_add __P((void *, const struct in6_addr *));
extern int inet6_rth_reverse __P((const void *, void *));
extern int inet6_rth_segments __P((const void *));
extern struct in6_addr *inet6_rth_getaddr __P((const void *, int));
__END_DECLS
#endif /* _NETBSD_SOURCE */

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_pcb.c,v 1.69 2006/01/21 00:15:36 rpaulo Exp $ */
/* $NetBSD: in6_pcb.c,v 1.70 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: in6_pcb.c,v 1.84 2001/02/08 18:02:08 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.69 2006/01/21 00:15:36 rpaulo Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6_pcb.c,v 1.70 2006/05/05 00:03:22 rpaulo Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
@ -679,6 +679,22 @@ in6_pcbnotify(table, dst, fport_arg, src, lport_arg, cmd, cmdarg, notify)
goto do_notify;
}
/*
* If the error designates a new path MTU for a destination
* and the application (associated with this socket) wanted to
* know the value, notify. Note that we notify for all
* disconnected sockets if the corresponding application
* wanted. This is because some UDP applications keep sending
* sockets disconnected.
* XXX: should we avoid to notify the value to TCP sockets?
*/
if (cmd == PRC_MSGSIZE && (in6p->in6p_flags & IN6P_MTU) != 0 &&
(IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr) ||
IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &sa6_dst->sin6_addr))) {
ip6_notify_pmtu(in6p, (struct sockaddr_in6 *)dst,
(u_int32_t *)cmdarg);
}
/*
* Detect if we should notify the error. If no source and
* destination ports are specified, but non-zero flowinfo and

View File

@ -1,4 +1,4 @@
/* $NetBSD: in6_pcb.h,v 1.28 2006/01/26 18:59:18 rpaulo Exp $ */
/* $NetBSD: in6_pcb.h,v 1.29 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: in6_pcb.h,v 1.45 2001/02/09 05:59:46 itojun Exp $ */
/*
@ -123,19 +123,20 @@ struct in6pcb {
#define IN6P_DSTOPTS 0x080000 /* receive dst options after rthdr */
#define IN6P_RTHDR 0x100000 /* receive routing header */
#define IN6P_RTHDRDSTOPTS 0x200000 /* receive dstoptions before rthdr */
#define IN6P_TCLASS 0x400000 /* traffic class */
#define IN6P_HIGHPORT 0x1000000 /* user wants "high" port binding */
#define IN6P_LOWPORT 0x2000000 /* user wants "low" port binding */
#define IN6P_ANONPORT 0x4000000 /* port chosen for user */
#define IN6P_FAITH 0x8000000 /* accept FAITH'ed connections */
#if 0 /* obsoleted */
#define IN6P_BINDV6ONLY 0x10000000 /* do not grab IPv4 traffic */
#endif
#define IN6P_MINMTU 0x20000000 /* use minimum MTU */
#define IN6P_RFC2292 0x40000000 /* RFC2292 */
#define IN6P_MTU 0x80000000 /* use minimum MTU */
#define IN6P_CONTROLOPTS (IN6P_PKTINFO|IN6P_HOPLIMIT|IN6P_HOPOPTS|\
IN6P_DSTOPTS|IN6P_RTHDR|IN6P_RTHDRDSTOPTS|\
IN6P_MINMTU)
IN6P_TCLASS|IN6P_RFC2292|\
IN6P_MTU)
/* compute hash value for foreign and local in6_addr and port */
#define IN6_HASH(faddr, fport, laddr, lport) \

View File

@ -65,7 +65,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.24 2006/04/15 00:30:48 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.25 2006/05/05 00:03:22 rpaulo Exp $");
#include "opt_inet.h"
@ -639,9 +639,7 @@ selectroute(dstsock, opts, mopts, ro, retifp, retrt, clone, norouteok)
* use it as the gateway.
*/
if (opts && opts->ip6po_nexthop) {
#ifdef notyet /* until introducing RFC3542 support */
struct route_in6 *ron;
#endif
sin6_next = satosin6(opts->ip6po_nexthop);
@ -655,7 +653,6 @@ selectroute(dstsock, opts, mopts, ro, retifp, retrt, clone, norouteok)
* If the next hop is an IPv6 address, then the node identified
* by that address must be a neighbor of the sending host.
*/
#ifdef notyet /* see above */
ron = &opts->ip6po_nextroute;
if ((ron->ro_rt &&
(ron->ro_rt->rt_flags & (RTF_UP | RTF_GATEWAY)) !=
@ -696,7 +693,6 @@ selectroute(dstsock, opts, mopts, ro, retifp, retrt, clone, norouteok)
*/
if (!clone)
goto done;
#endif
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_input.c,v 1.84 2006/04/15 00:13:23 christos Exp $ */
/* $NetBSD: ip6_input.c,v 1.85 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */
/*
@ -62,9 +62,10 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.84 2006/04/15 00:13:23 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.85 2006/05/05 00:03:22 rpaulo Exp $");
#include "opt_inet.h"
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_pfil_hooks.h"
@ -1030,6 +1031,12 @@ ip6_savecontrol(in6p, mp, ip6, m)
struct ip6_hdr *ip6;
struct mbuf *m;
{
#ifdef RFC2292
#define IS2292(x, y) ((in6p->in6p_flags & IN6P_RFC2292) ? (x) : (y))
#else
#define IS2292(x, y) (y)
#endif
#ifdef SO_TIMESTAMP
if (in6p->in6p_socket->so_options & SO_TIMESTAMP) {
struct timeval tv;
@ -1041,49 +1048,51 @@ ip6_savecontrol(in6p, mp, ip6, m)
mp = &(*mp)->m_next;
}
#endif
if (in6p->in6p_flags & IN6P_RECVDSTADDR) {
*mp = sbcreatecontrol((caddr_t) &ip6->ip6_dst,
sizeof(struct in6_addr), IPV6_RECVDSTADDR, IPPROTO_IPV6);
if (*mp)
mp = &(*mp)->m_next;
}
#ifdef noyet
/* options were tossed above */
if (in6p->in6p_flags & IN6P_RECVOPTS)
/* broken */
/* ip6_srcroute doesn't do what we want here, need to fix */
if (in6p->in6p_flags & IPV6P_RECVRETOPTS)
/* broken */
#endif
/* RFC 2292 sec. 5 */
if ((in6p->in6p_flags & IN6P_PKTINFO) != 0) {
struct in6_pktinfo pi6;
bcopy(&ip6->ip6_dst, &pi6.ipi6_addr, sizeof(struct in6_addr));
in6_clearscope(&pi6.ipi6_addr); /* XXX */
pi6.ipi6_ifindex = m->m_pkthdr.rcvif ?
m->m_pkthdr.rcvif->if_index : 0;
*mp = sbcreatecontrol((caddr_t) &pi6,
sizeof(struct in6_pktinfo), IPV6_PKTINFO, IPPROTO_IPV6);
sizeof(struct in6_pktinfo),
IS2292(IPV6_2292PKTINFO, IPV6_PKTINFO), IPPROTO_IPV6);
if (*mp)
mp = &(*mp)->m_next;
}
if (in6p->in6p_flags & IN6P_HOPLIMIT) {
int hlim = ip6->ip6_hlim & 0xff;
*mp = sbcreatecontrol((caddr_t) &hlim, sizeof(int),
IPV6_HOPLIMIT, IPPROTO_IPV6);
IS2292(IPV6_2292HOPLIMIT, IPV6_HOPLIMIT), IPPROTO_IPV6);
if (*mp)
mp = &(*mp)->m_next;
}
if ((in6p->in6p_flags & IN6P_TCLASS) != 0) {
u_int32_t flowinfo;
int tclass;
flowinfo = (u_int32_t)ntohl(ip6->ip6_flow & IPV6_FLOWINFO_MASK);
flowinfo >>= 20;
tclass = flowinfo & 0xff;
*mp = sbcreatecontrol((caddr_t)&tclass, sizeof(tclass),
IPV6_TCLASS, IPPROTO_IPV6);
if (*mp)
mp = &(*mp)->m_next;
}
/* IN6P_NEXTHOP - for outgoing packet only */
/*
* IPV6_HOPOPTS socket option. Recall that we required super-user
* privilege for the option (see ip6_ctloutput), but it might be too
* strict, since there might be some hop-by-hop options which can be
* returned to normal user.
* See also RFC 2292 section 6.
* See also RFC3542 section 8 (or RFC2292 section 6).
*/
if ((in6p->in6p_flags & IN6P_HOPOPTS) != 0) {
/*
@ -1117,10 +1126,11 @@ ip6_savecontrol(in6p, mp, ip6, m)
* XXX: We copy whole the header even if a jumbo
* payload option is included, which option is to
* be removed before returning in the RFC 2292.
* But it's too painful operation...
* Note: this constraint is removed in RFC3542.
*/
*mp = sbcreatecontrol((caddr_t)hbh, hbhlen,
IPV6_HOPOPTS, IPPROTO_IPV6);
IS2292(IPV6_2292HOPOPTS, IPV6_HOPOPTS),
IPPROTO_IPV6);
if (*mp)
mp = &(*mp)->m_next;
m_freem(ext);
@ -1181,7 +1191,8 @@ ip6_savecontrol(in6p, mp, ip6, m)
break;
*mp = sbcreatecontrol((caddr_t)ip6e, elen,
IPV6_DSTOPTS, IPPROTO_IPV6);
IS2292(IPV6_2292DSTOPTS, IPV6_DSTOPTS),
IPPROTO_IPV6);
if (*mp)
mp = &(*mp)->m_next;
break;
@ -1191,7 +1202,8 @@ ip6_savecontrol(in6p, mp, ip6, m)
break;
*mp = sbcreatecontrol((caddr_t)ip6e, elen,
IPV6_RTHDR, IPPROTO_IPV6);
IS2292(IPV6_2292RTHDR, IPV6_RTHDR),
IPPROTO_IPV6);
if (*mp)
mp = &(*mp)->m_next;
break;
@ -1223,6 +1235,45 @@ ip6_savecontrol(in6p, mp, ip6, m)
;
}
}
#undef IS2292
void
ip6_notify_pmtu(struct in6pcb *in6p, struct sockaddr_in6 *dst, uint32_t *mtu)
{
struct socket *so;
struct mbuf *m_mtu;
struct ip6_mtuinfo mtuctl;
so = in6p->in6p_socket;
if (mtu == NULL)
return;
#ifdef DIAGNOSTIC
if (so == NULL) /* I believe this is impossible */
panic("ip6_notify_pmtu: socket is NULL");
#endif
memset(&mtuctl, 0, sizeof(mtuctl)); /* zero-clear for safety */
mtuctl.ip6m_mtu = *mtu;
mtuctl.ip6m_addr = *dst;
if (sa6_recoverscope(&mtuctl.ip6m_addr))
return;
if ((m_mtu = sbcreatecontrol((caddr_t)&mtuctl, sizeof(mtuctl),
IPV6_PATHMTU, IPPROTO_IPV6)) == NULL)
return;
if (sbappendaddr(&so->so_rcv, (struct sockaddr *)dst, NULL, m_mtu)
== 0) {
m_freem(m_mtu);
/* XXX: should count statistics */
} else
sorwakeup(so);
return;
}
/*
* pull single extension header from mbuf chain. returns single mbuf that
@ -1496,6 +1547,11 @@ u_char inet6ctlerrmap[PRC_NCMDS] = {
SYSCTL_SETUP(sysctl_net_inet6_ip6_setup, "sysctl net.inet6.ip6 subtree setup")
{
#ifdef RFC2292
#define IS2292(x, y) ((in6p->in6p_flags & IN6P_RFC2292) ? (x) : (y))
#else
#define IS2292(x, y) (y)
#endif
sysctl_createv(clog, 0, NULL, NULL,
CTLFLAG_PERMANENT,

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: ip6_var.h,v 1.36 2006/03/05 23:47:08 rpaulo Exp $ */
/* $NetBSD: ip6_var.h,v 1.37 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
@ -124,15 +124,34 @@ struct ip6po_rhinfo {
#define ip6po_rthdr ip6po_rhinfo.ip6po_rhi_rthdr
#define ip6po_route ip6po_rhinfo.ip6po_rhi_route
/* Nexthop related info */
struct ip6po_nhinfo {
struct sockaddr *ip6po_nhi_nexthop;
struct route_in6 ip6po_nhi_route; /* Route to the nexthop */
};
#define ip6po_nexthop ip6po_nhinfo.ip6po_nhi_nexthop
#define ip6po_nextroute ip6po_nhinfo.ip6po_nhi_route
struct ip6_pktopts {
struct mbuf *ip6po_m; /* Pointer to mbuf storing the data */
int ip6po_hlim; /* Hoplimit for outgoing packets */
struct in6_pktinfo *ip6po_pktinfo; /* Outgoing IF/address information */
struct sockaddr *ip6po_nexthop; /* Next-hop address */
struct ip6po_nhinfo ip6po_nhinfo; /* Next-hop address information */
struct ip6_hbh *ip6po_hbh; /* Hop-by-Hop options header */
struct ip6_dest *ip6po_dest1; /* Destination options header(1st part) */
struct ip6po_rhinfo ip6po_rhinfo; /* Routing header related info. */
struct ip6_dest *ip6po_dest2; /* Destination options header(2nd part) */
int ip6po_tclass; /* traffic class */
int ip6po_minmtu; /* fragment vs PMTU discovery policy */
#define IP6PO_MINMTU_MCASTONLY -1 /* default; send at min MTU for multicast*/
#define IP6PO_MINMTU_DISABLE 0 /* always perform pmtu disc */
#define IP6PO_MINMTU_ALL 1 /* always send at min MTU */
int ip6po_flags;
#if 0 /* parameters in this block is obsolete. do not reuse the values. */
#define IP6PO_REACHCONF 0x01 /* upper-layer reachability confirmation. */
#define IP6PO_MINMTU 0x02 /* use minimum MTU (IPV6_USE_MIN_MTU) */
#endif
#define IP6PO_DONTFRAG 0x04 /* disable fragmentation (IPV6_DONTFRAG) */
};
struct ip6stat {
@ -266,6 +285,7 @@ void ip6_init __P((void));
void ip6intr __P((void));
void ip6_input __P((struct mbuf *));
struct in6_ifaddr *ip6_getdstifaddr __P((struct mbuf *));
void ip6_freepcbopts __P((struct ip6_pktopts *));
void ip6_freemoptions __P((struct ip6_moptions *));
int ip6_unknown_opt __P((u_int8_t *, struct mbuf *, int));
u_int8_t *ip6_get_prevhdr __P((struct mbuf *, int));
@ -281,6 +301,8 @@ int ip6_process_hopopts __P((struct mbuf *, u_int8_t *, int, u_int32_t *,
u_int32_t *));
void ip6_savecontrol __P((struct in6pcb *, struct mbuf **, struct ip6_hdr *,
struct mbuf *));
void ip6_notify_pmtu __P((struct in6pcb *, struct sockaddr_in6 *,
u_int32_t *));
int ip6_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
void ip6_forward __P((struct mbuf *, int));
@ -292,7 +314,11 @@ int ip6_output __P((struct mbuf *, struct ip6_pktopts *,
struct ifnet **));
int ip6_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
int ip6_raw_ctloutput __P((int, struct socket *, int, int, struct mbuf **));
int ip6_setpktoptions __P((struct mbuf *, struct ip6_pktopts *, int));
void ip6_initpktopts __P((struct ip6_pktopts *));
int ip6_setpktopts __P((struct mbuf *, struct ip6_pktopts *,
struct ip6_pktopts *, int, int));
void ip6_clearpktopts __P((struct ip6_pktopts *, int));
struct ip6_pktopts *ip6_copypktopts __P((struct ip6_pktopts *, int));
int ip6_optlen __P((struct in6pcb *));
int route6_input __P((struct mbuf **, int *, int));

View File

@ -1,4 +1,4 @@
/* $NetBSD: raw_ip6.c,v 1.75 2006/01/21 00:15:37 rpaulo Exp $ */
/* $NetBSD: raw_ip6.c,v 1.76 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.75 2006/01/21 00:15:37 rpaulo Exp $");
__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.76 2006/05/05 00:03:22 rpaulo Exp $");
#include "opt_ipsec.h"
@ -350,10 +350,10 @@ rip6_ctlinput(cmd, sa, d)
/*
* regardless of if we called icmp6_mtudisc_update(),
* we need to call in6_pcbnotify(), to notify path
* MTU change to the userland (2292bis-02), because
* some unconnected sockets may share the same
* destination and want to know the path MTU.
* we need to call in6_pcbnotify(), to notify path MTU
* change to the userland (RFC3542), because some
* unconnected sockets may share the same destination
* and want to know the path MTU.
*/
}
@ -389,7 +389,6 @@ rip6_output(m, va_alist)
int scope_ambiguous = 0;
struct in6_addr *in6a;
va_list ap;
int flags;
va_start(ap, m);
so = va_arg(ap, struct socket *);
@ -405,8 +404,11 @@ rip6_output(m, va_alist)
dst = &dstsock->sin6_addr;
if (control) {
if ((error = ip6_setpktoptions(control, &opt, priv)) != 0)
if ((error = ip6_setpktopts(control, &opt,
in6p->in6p_outputopts,
priv, so->so_proto->pr_protocol)) != 0) {
goto bad;
}
optp = &opt;
} else
optp = in6p->in6p_outputopts;
@ -519,11 +521,7 @@ rip6_output(m, va_alist)
}
}
flags = 0;
if (in6p->in6p_flags & IN6P_MINMTU)
flags |= IPV6_MINMTU;
error = ip6_output(m, optp, &in6p->in6p_route, flags,
error = ip6_output(m, optp, &in6p->in6p_route, 0,
in6p->in6p_moptions, so, &oifp);
if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) {
if (oifp)
@ -539,10 +537,10 @@ rip6_output(m, va_alist)
m_freem(m);
freectl:
if (optp == &opt && optp->ip6po_rthdr && optp->ip6po_route.ro_rt)
RTFREE(optp->ip6po_route.ro_rt);
if (control)
if (control) {
ip6_clearpktopts(&opt, -1);
m_freem(control);
}
return (error);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: udp6_output.c,v 1.23 2006/01/21 00:15:37 rpaulo Exp $ */
/* $NetBSD: udp6_output.c,v 1.24 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: udp6_output.c,v 1.43 2001/10/15 09:19:52 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: udp6_output.c,v 1.23 2006/01/21 00:15:37 rpaulo Exp $");
__KERNEL_RCSID(0, "$NetBSD: udp6_output.c,v 1.24 2006/05/05 00:03:22 rpaulo Exp $");
#include "opt_inet.h"
@ -125,14 +125,14 @@ udp6_output(in6p, m, addr6, control, p)
int scope_ambiguous = 0;
u_int16_t fport;
int error = 0;
struct ip6_pktopts opt, *stickyopt = in6p->in6p_outputopts;
struct ip6_pktopts *optp, opt;
int priv;
int af = AF_INET6, hlen = sizeof(struct ip6_hdr);
#ifdef INET
struct ip *ip;
struct udpiphdr *ui;
#endif
int flags = 0;
#endif
struct sockaddr_in6 tmp;
priv = 0;
@ -169,10 +169,13 @@ udp6_output(in6p, m, addr6, control, p)
}
if (control) {
if ((error = ip6_setpktoptions(control, &opt, priv)) != 0)
if ((error = ip6_setpktopts(control, &opt,
in6p->in6p_outputopts, priv, IPPROTO_UDP)) != 0)
goto release;
in6p->in6p_outputopts = &opt;
}
optp = &opt;
} else
optp = in6p->in6p_outputopts;
if (sin6) {
faddr = &sin6->sin6_addr;
@ -232,7 +235,7 @@ udp6_output(in6p, m, addr6, control, p)
}
if (!IN6_IS_ADDR_V4MAPPED(faddr)) {
laddr = in6_selectsrc(sin6, in6p->in6p_outputopts,
laddr = in6_selectsrc(sin6, optp,
in6p->in6p_moptions, &in6p->in6p_route,
&in6p->in6p_laddr, &oifp, &error);
if (oifp && scope_ambiguous &&
@ -356,12 +359,9 @@ udp6_output(in6p, m, addr6, control, p)
m->m_pkthdr.csum_flags = M_CSUM_UDPv6;
m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
if (in6p->in6p_flags & IN6P_MINMTU)
flags |= IPV6_MINMTU;
udp6stat.udp6s_opackets++;
error = ip6_output(m, in6p->in6p_outputopts, &in6p->in6p_route,
flags, in6p->in6p_moptions, in6p->in6p_socket, NULL);
error = ip6_output(m, optp, &in6p->in6p_route, 0,
in6p->in6p_moptions, in6p->in6p_socket, NULL);
break;
case AF_INET:
#ifdef INET
@ -408,7 +408,7 @@ release:
releaseopt:
if (control) {
in6p->in6p_outputopts = stickyopt;
ip6_clearpktopts(&opt, -1);
m_freem(control);
}
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: udp6_usrreq.c,v 1.73 2006/01/21 00:15:37 rpaulo Exp $ */
/* $NetBSD: udp6_usrreq.c,v 1.74 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $ */
/*
@ -62,7 +62,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.73 2006/01/21 00:15:37 rpaulo Exp $");
__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.74 2006/05/05 00:03:22 rpaulo Exp $");
#include <sys/param.h>
#include <sys/malloc.h>
@ -236,10 +236,11 @@ udp6_ctlinput(cmd, sa, d)
icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
/*
* regardless of if we called icmp6_mtudisc_update(),
* we need to call in6_pcbnotify(), to notify path
* MTU change to the userland (2292bis-02), because
* some unconnected sockets may share the same
* regardless of if we called
* icmp6_mtudisc_update(), we need to call
* in6_pcbnotify(), to notify path MTU change
* to the userland (RFC3542), because some
* unconnected sockets may share the same
* destination and want to know the path MTU.
*/
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: commands.c,v 1.64 2006/04/04 21:35:20 christos Exp $ */
/* $NetBSD: commands.c,v 1.65 2006/05/05 00:03:22 rpaulo Exp $ */
/*
* Copyright (C) 1997 and 1998 WIDE Project.
@ -63,7 +63,7 @@
#if 0
static char sccsid[] = "@(#)commands.c 8.4 (Berkeley) 5/30/95";
#else
__RCSID("$NetBSD: commands.c,v 1.64 2006/04/04 21:35:20 christos Exp $");
__RCSID("$NetBSD: commands.c,v 1.65 2006/05/05 00:03:22 rpaulo Exp $");
#endif
#endif /* not lint */
@ -2799,6 +2799,8 @@ sourceroute(struct addrinfo *ai, char *arg, char **cpp, int *protop, int *optp)
break;
#ifdef INET6
case AF_INET6:
#ifdef IPV6_PKTOPTIONS
/* RFC2292 */
cmsg = inet6_rthdr_init(rhbuf, IPV6_RTHDR_TYPE_0);
if (*cp != '@')
return -1;
@ -2806,6 +2808,10 @@ sourceroute(struct addrinfo *ai, char *arg, char **cpp, int *protop, int *optp)
*protop = IPPROTO_IPV6;
*optp = IPV6_PKTOPTIONS;
break;
#else
/* no RFC2292 */
return -1;
#endif
#endif
default:
return -1;

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.5 2000/10/08 06:40:42 itojun Exp $
# $NetBSD: Makefile,v 1.6 2006/05/05 00:03:22 rpaulo Exp $
PROG= traceroute6
MAN= traceroute6.8
@ -7,6 +7,7 @@ BINMODE=4555
BINOWN= root
CPPFLAGS+=-DINET6 -DIPSEC
CPPFLAGS+=-DUSE_RFC3542
LDADD+= -lipsec
DPADD+= ${LIBIPSEC}

View File

@ -1,4 +1,4 @@
/* $NetBSD: traceroute6.c,v 1.35 2004/04/22 01:41:22 itojun Exp $ */
/* $NetBSD: traceroute6.c,v 1.36 2006/05/05 00:03:22 rpaulo Exp $ */
/* $KAME: traceroute6.c,v 1.67 2004/01/25 03:24:39 itojun Exp $ */
/*
@ -75,7 +75,7 @@ static char sccsid[] = "@(#)traceroute.c 8.1 (Berkeley) 6/6/93";
#else
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: traceroute6.c,v 1.35 2004/04/22 01:41:22 itojun Exp $");
__RCSID("$NetBSD: traceroute6.c,v 1.36 2006/05/05 00:03:22 rpaulo Exp $");
#endif
#endif
@ -339,7 +339,7 @@ u_long datalen; /* How much data */
#define ICMP6ECHOLEN 8
/* XXX: 2064 = 127(max hops in type 0 rthdr) * sizeof(ip6_hdr) + 16(margin) */
char rtbuf[2064];
#ifdef USE_RFC2292BIS
#ifdef USE_RFC3542
struct ip6_rthdr *rth;
#endif
struct cmsghdr *cmsg;
@ -436,7 +436,7 @@ main(argc, argv)
"traceroute6: unknown host %s\n", optarg);
exit(1);
}
#ifdef USE_RFC2292BIS
#ifdef USE_RFC3542
if (rth == NULL) {
/*
* XXX: We can't detect the number of
@ -704,7 +704,7 @@ main(argc, argv)
if (options & SO_DONTROUTE)
(void) setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE,
(char *)&on, sizeof(on));
#ifdef USE_RFC2292BIS
#ifdef USE_RFC3542
if (rth) {/* XXX: there is no library to finalize the header... */
rth->ip6r_len = rth->ip6r_segleft * 2;
if (setsockopt(sndsock, IPPROTO_IPV6, IPV6_RTHDR,
@ -724,7 +724,7 @@ main(argc, argv)
exit(1);
}
}
#endif /* USE_RFC2292BIS */
#endif /* USE_RFC3542 */
#ifdef IPSEC
#ifdef IPSEC_POLICY_IPSEC
/*