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:
parent
e48c097471
commit
de8db47547
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 .
|
||||
.\"
|
|
@ -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.
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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!
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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}
|
||||
|
||||
|
|
|
@ -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
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue