mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-21 01:12:26 +08:00
[BZ #2693]
* inet/Makefile (routines): Add inet6_opt and inet6_rth. * inet/Versions (libc, GLIBC_2.5): Add inet6_opt_init, inet6_opt_append, inet6_opt_finish, inet6_opt_set_val, inet6_opt_next, inet6_opt_find, inet6_opt_get_val, inet6_rth_space, inet6_rth_init, inet6_rth_add, inet6_rth_reverse, inet6_rth_segments, and inet6_rth_getaddr. * inet/netinet/ip6.h (struct ip6_rthdr0): Make ip6r0_addr a flexible array. * inet/netinet/in.h (struct ip6_mtuinfo): Define. Mark inet6_option_* interfaces as deprecated. Declare inet6_opt_init, inet6_opt_append, inet6_opt_finish, inet6_opt_set_val, inet6_opt_next, inet6_opt_find, inet6_opt_get_val, inet6_rth_space, inet6_rth_init, inet6_rth_add, inet6_rth_reverse, inet6_rth_segments, and inet6_rth_getaddr. * inet/inet6_opt.c: New file. * inet/inet6_rth.c: New file. * inet/netinet/icmp6.h: Pretty printing.
This commit is contained in:
parent
aec6b246ee
commit
07bfff20c7
20
ChangeLog
20
ChangeLog
@ -1,5 +1,25 @@
|
||||
2006-05-24 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
[BZ #2693]
|
||||
* inet/Makefile (routines): Add inet6_opt and inet6_rth.
|
||||
* inet/Versions (libc, GLIBC_2.5): Add inet6_opt_init,
|
||||
inet6_opt_append, inet6_opt_finish, inet6_opt_set_val, inet6_opt_next,
|
||||
inet6_opt_find, inet6_opt_get_val, inet6_rth_space, inet6_rth_init,
|
||||
inet6_rth_add, inet6_rth_reverse, inet6_rth_segments,
|
||||
and inet6_rth_getaddr.
|
||||
* inet/netinet/ip6.h (struct ip6_rthdr0): Make ip6r0_addr a flexible
|
||||
array.
|
||||
* inet/netinet/in.h (struct ip6_mtuinfo): Define.
|
||||
Mark inet6_option_* interfaces as deprecated.
|
||||
Declare inet6_opt_init, inet6_opt_append, inet6_opt_finish,
|
||||
inet6_opt_set_val, inet6_opt_next, inet6_opt_find, inet6_opt_get_val,
|
||||
inet6_rth_space, inet6_rth_init, inet6_rth_add, inet6_rth_reverse,
|
||||
inet6_rth_segments, and inet6_rth_getaddr.
|
||||
* inet/inet6_opt.c: New file.
|
||||
* inet/inet6_rth.c: New file.
|
||||
|
||||
* inet/netinet/icmp6.h: Pretty printing.
|
||||
|
||||
[BZ #2683]
|
||||
* elf/dl-addr.c (_dl_addr): Don't match undefined references.
|
||||
|
||||
|
7
NEWS
7
NEWS
@ -1,4 +1,4 @@
|
||||
GNU C Library NEWS -- history of user-visible changes. 2006-05-07
|
||||
GNU C Library NEWS -- history of user-visible changes. 2006-05-24
|
||||
Copyright (C) 1992-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
|
||||
See the end for copying conditions.
|
||||
|
||||
@ -23,11 +23,14 @@ Version 2.5
|
||||
site might have problems with default behavior.
|
||||
Implemented by Ulrich Drepper.
|
||||
|
||||
* Iterating over entire database in NIS and NIS+ can be slow. With the
|
||||
* Iterating over entire database in NIS can be slow. With the
|
||||
SETENT_BATCH_READ option in /etc/default/nss a system admin can decide
|
||||
to trade time for memory. The entire database will be read at once.
|
||||
Implemented by Ulrich Drepper.
|
||||
|
||||
* The interfaces introduced in RFC 3542 have been implemented by
|
||||
Ulrich Drepper.
|
||||
|
||||
|
||||
Version 2.4
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Copyright (C) 1991-2002, 2003, 2004 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1991-2002, 2003, 2004, 2006 Free Software Foundation, Inc.
|
||||
# This file is part of the GNU C Library.
|
||||
|
||||
# The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -47,7 +47,7 @@ routines := htonl htons \
|
||||
getaliasent_r getaliasent getaliasname getaliasname_r \
|
||||
in6_addr getnameinfo if_index ifaddrs inet6_option \
|
||||
getipv4sourcefilter setipv4sourcefilter \
|
||||
getsourcefilter setsourcefilter
|
||||
getsourcefilter setsourcefilter inet6_opt inet6_rth
|
||||
|
||||
aux := check_pf ifreq
|
||||
|
||||
|
@ -78,6 +78,12 @@ libc {
|
||||
getipv4sourcefilter; setipv4sourcefilter;
|
||||
getsourcefilter; setsourcefilter;
|
||||
}
|
||||
GLIBC_2.5 {
|
||||
inet6_opt_init; inet6_opt_append; inet6_opt_finish; inet6_opt_set_val;
|
||||
inet6_opt_next; inet6_opt_find; inet6_opt_get_val;
|
||||
inet6_rth_space; inet6_rth_init; inet6_rth_add; inet6_rth_reverse;
|
||||
inet6_rth_segments; inet6_rth_getaddr;
|
||||
}
|
||||
GLIBC_PRIVATE {
|
||||
# functions used in other libraries
|
||||
__internal_endnetgrent; __internal_getnetgrent_r;
|
||||
|
278
inet/inet6_opt.c
Normal file
278
inet/inet6_opt.c
Normal file
@ -0,0 +1,278 @@
|
||||
/* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip6.h>
|
||||
|
||||
|
||||
/* RFC 3542, 10.1
|
||||
|
||||
This function returns the number of bytes needed for the empty
|
||||
extension header i.e., without any options. If EXTBUF is not NULL it
|
||||
also initializes the extension header to have the correct length
|
||||
field. In that case if the EXTLEN value is not a positive (i.e.,
|
||||
non-zero) multiple of 8 the function fails and returns -1. */
|
||||
int
|
||||
inet6_opt_init (void *extbuf, socklen_t extlen)
|
||||
{
|
||||
if (extbuf != NULL)
|
||||
{
|
||||
if (extlen <= 0 || (extlen % 8) != 0)
|
||||
return -1;
|
||||
|
||||
/* Fill in the length in units of 8 octets. */
|
||||
struct ip6_hbh *extp = (struct ip6_hbh *) extbuf;
|
||||
extp->ip6h_len = extlen / 8;
|
||||
}
|
||||
|
||||
return sizeof (struct ip6_hbh);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_padding (uint8_t *extbuf, int offset, int npad)
|
||||
{
|
||||
if (npad == 1)
|
||||
extbuf[offset] = IP6OPT_PAD1;
|
||||
else
|
||||
{
|
||||
struct ip6_opt *pad_opt = (struct ip6_opt *) (extbuf + offset);
|
||||
|
||||
pad_opt->ip6o_type = IP6OPT_PADN;
|
||||
pad_opt->ip6o_len = npad - sizeof (struct ip6_opt);
|
||||
/* Clear the memory used by the padding. */
|
||||
memset (pad_opt + 1, '\0', pad_opt->ip6o_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* RFC 3542, 10.2
|
||||
|
||||
This function returns the updated total length taking into account
|
||||
adding an option with length 'len' and alignment 'align'. If
|
||||
EXTBUF is not NULL then, in addition to returning the length, the
|
||||
function inserts any needed pad option, initializes the option
|
||||
(setting the type and length fields) and returns a pointer to the
|
||||
location for the option content in databufp. If the option does
|
||||
not fit in the extension header buffer the function returns -1. */
|
||||
int
|
||||
inet6_opt_append (void *extbuf, socklen_t extlen, int offset, uint8_t type,
|
||||
socklen_t len, uint8_t align, void **databufp)
|
||||
{
|
||||
/* Check minimum offset. */
|
||||
if (offset < sizeof (struct ip6_hbh))
|
||||
return -1;
|
||||
|
||||
/* One cannot add padding options. */
|
||||
if (type == IP6OPT_PAD1 || type == IP6OPT_PADN)
|
||||
return -1;
|
||||
|
||||
/* The option length must fit in one octet. */
|
||||
if (len > 255)
|
||||
return -1;
|
||||
|
||||
/* The alignment can only by 1, 2, 4, or 8 and must not exceed the
|
||||
option length. */
|
||||
if (align == 0 || align > 8 || (align & (align - 1)) != 0 || align > len)
|
||||
return -1;
|
||||
|
||||
/* Determine the needed padding for alignment. Following the
|
||||
current content of the buffer we have the is the IPv6 option type
|
||||
and length, followed immediately by the data. The data has the
|
||||
alignment constraints. Therefore padding must be inserted in the
|
||||
form of padding options before the new option. */
|
||||
int data_offset = offset + sizeof (struct ip6_opt);
|
||||
int npad = (align - data_offset % align) & (align - 1);
|
||||
|
||||
/* Now we can check whether the buffer is large enough. */
|
||||
if (data_offset + npad + len > extlen)
|
||||
return -1;
|
||||
|
||||
if (npad != 0)
|
||||
{
|
||||
if (extbuf != NULL)
|
||||
add_padding (extbuf, offset, npad);
|
||||
|
||||
offset += npad;
|
||||
}
|
||||
|
||||
/* Now prepare the option itself. */
|
||||
if (extbuf != NULL)
|
||||
{
|
||||
struct ip6_opt *opt = (struct ip6_opt *) ((uint8_t *) extbuf + offset);
|
||||
|
||||
opt->ip6o_type = type;
|
||||
opt->ip6o_len = len;
|
||||
|
||||
*databufp = opt + 1;
|
||||
}
|
||||
|
||||
return offset + sizeof (struct ip6_opt) + len;
|
||||
}
|
||||
|
||||
|
||||
/* RFC 3542, 10.3
|
||||
|
||||
This function returns the updated total length taking into account
|
||||
the final padding of the extension header to make it a multiple of
|
||||
8 bytes. If EXTBUF is not NULL the function also initializes the
|
||||
option by inserting a Pad1 or PadN option of the proper length. */
|
||||
int
|
||||
inet6_opt_finish (void *extbuf, socklen_t extlen, int offset)
|
||||
{
|
||||
/* Check minimum offset. */
|
||||
if (offset < sizeof (struct ip6_hbh))
|
||||
return -1;
|
||||
|
||||
/* Required padding at the end. */
|
||||
int npad = (8 - (offset & 7)) & 7;
|
||||
|
||||
/* Make sure the buffer is large enough. */
|
||||
if (offset + npad > extlen)
|
||||
return -1;
|
||||
|
||||
if (extbuf != NULL)
|
||||
add_padding (extbuf, offset, npad);
|
||||
|
||||
return offset + npad;
|
||||
}
|
||||
|
||||
|
||||
/* RFC 3542, 10.4
|
||||
|
||||
This function inserts data items of various sizes in the data
|
||||
portion of the option. VAL should point to the data to be
|
||||
inserted. OFFSET specifies where in the data portion of the option
|
||||
the value should be inserted; the first byte after the option type
|
||||
and length is accessed by specifying an offset of zero. */
|
||||
int
|
||||
inet6_opt_set_val (void *databuf, int offset, void *val, socklen_t vallen)
|
||||
{
|
||||
memcpy ((uint8_t *) databuf + offset, val, vallen);
|
||||
|
||||
return offset + vallen;
|
||||
}
|
||||
|
||||
|
||||
/* RFC 3542, 10.5
|
||||
|
||||
This function parses received option extension headers returning
|
||||
the next option. EXTBUF and EXTLEN specifies the extension header.
|
||||
OFFSET should either be zero (for the first option) or the length
|
||||
returned by a previous call to 'inet6_opt_next' or
|
||||
'inet6_opt_find'. It specifies the position where to continue
|
||||
scanning the extension buffer. */
|
||||
int
|
||||
inet6_opt_next (void *extbuf, socklen_t extlen, int offset, uint8_t *typep,
|
||||
socklen_t *lenp, void **databufp)
|
||||
{
|
||||
if (offset == 0)
|
||||
offset = sizeof (struct ip6_hbh);
|
||||
else if (offset < sizeof (struct ip6_hbh))
|
||||
return -1;
|
||||
|
||||
while (offset < extlen)
|
||||
{
|
||||
struct ip6_opt *opt = (struct ip6_opt *) ((uint8_t *) extbuf + offset);
|
||||
|
||||
if (opt->ip6o_type == IP6OPT_PAD1)
|
||||
/* Single byte padding. */
|
||||
++offset;
|
||||
else if (opt->ip6o_type == IP6OPT_PADN)
|
||||
offset += sizeof (struct ip6_opt) + opt->ip6o_len;
|
||||
else
|
||||
{
|
||||
/* Check whether the option is valid. */
|
||||
offset += sizeof (struct ip6_opt) + opt->ip6o_len;
|
||||
if (offset > extlen)
|
||||
return -1;
|
||||
|
||||
*typep = opt->ip6o_type;
|
||||
*lenp = opt->ip6o_len;
|
||||
*databufp = opt + 1;
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* RFC 3542, 10.6
|
||||
|
||||
This function is similar to the previously described
|
||||
'inet6_opt_next' function, except this function lets the caller
|
||||
specify the option type to be searched for, instead of always
|
||||
returning the next option in the extension header. */
|
||||
int
|
||||
inet6_opt_find (void *extbuf, socklen_t extlen, int offset, uint8_t type,
|
||||
socklen_t *lenp, void **databufp)
|
||||
{
|
||||
if (offset == 0)
|
||||
offset = sizeof (struct ip6_hbh);
|
||||
else if (offset < sizeof (struct ip6_hbh))
|
||||
return -1;
|
||||
|
||||
while (offset < extlen)
|
||||
{
|
||||
struct ip6_opt *opt = (struct ip6_opt *) ((uint8_t *) extbuf + offset);
|
||||
|
||||
if (opt->ip6o_type == IP6OPT_PAD1)
|
||||
{
|
||||
/* Single byte padding. */
|
||||
++offset;
|
||||
if (type == IP6OPT_PAD1)
|
||||
{
|
||||
*lenp = 0;
|
||||
*databufp = (uint8_t *) extbuf + offset;
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
else if (opt->ip6o_type != type)
|
||||
offset += sizeof (struct ip6_opt) + opt->ip6o_len;
|
||||
else
|
||||
{
|
||||
/* Check whether the option is valid. */
|
||||
offset += sizeof (struct ip6_opt) + opt->ip6o_len;
|
||||
if (offset > extlen)
|
||||
return -1;
|
||||
|
||||
*lenp = opt->ip6o_len;
|
||||
*databufp = opt + 1;
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* RFC 3542, 10.7
|
||||
|
||||
This function extracts data items of various sizes in the data
|
||||
portion of the option. */
|
||||
int
|
||||
inet6_opt_get_val (void *databuf, int offset, void *val, socklen_t vallen)
|
||||
{
|
||||
memcpy (val, (uint8_t *) databuf + offset, vallen);
|
||||
|
||||
return offset + vallen;
|
||||
}
|
192
inet/inet6_rth.c
Normal file
192
inet/inet6_rth.c
Normal file
@ -0,0 +1,192 @@
|
||||
/* Copyright (C) 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the GNU C Library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip6.h>
|
||||
|
||||
|
||||
/* RFC 3542, 7.1
|
||||
|
||||
This function returns the number of bytes required to hold a
|
||||
Routing header of the specified type containing the specified
|
||||
number of segments (addresses). For an IPv6 Type 0 Routing header,
|
||||
the number of segments must be between 0 and 127, inclusive. */
|
||||
socklen_t
|
||||
inet6_rth_space (int type, int segments)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case IPV6_RTHDR_TYPE_0:
|
||||
if (segments < 0 || segments > 127)
|
||||
return 0;
|
||||
|
||||
return sizeof (struct ip6_rthdr0) + segments * sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* RFC 3542, 7.2
|
||||
|
||||
This function initializes the buffer pointed to by BP to contain a
|
||||
Routing header of the specified type and sets ip6r_len based on the
|
||||
segments parameter. */
|
||||
void *
|
||||
inet6_rth_init (void *bp, socklen_t bp_len, int type, int segments)
|
||||
{
|
||||
struct ip6_rthdr *rthdr = (struct ip6_rthdr *) bp;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case IPV6_RTHDR_TYPE_0:
|
||||
/* Make sure the parameters are valid and the buffer is large enough. */
|
||||
if (segments < 0 || segments > 127)
|
||||
break;
|
||||
|
||||
socklen_t len = (sizeof (struct ip6_rthdr0)
|
||||
+ segments * sizeof (struct in6_addr));
|
||||
if (len > bp_len)
|
||||
break;
|
||||
|
||||
/* Some implementations seem to initialize the whole memory area. */
|
||||
memset (bp, '\0', len);
|
||||
|
||||
/* Length in units of 8 octets. */
|
||||
rthdr->ip6r_len = segments * sizeof (struct in6_addr) / 8;
|
||||
rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
|
||||
return bp;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* RFC 3542, 7.3
|
||||
|
||||
This function adds the IPv6 address pointed to by addr to the end of
|
||||
the Routing header being constructed. */
|
||||
int
|
||||
inet6_rth_add (void *bp, const struct in6_addr *addr)
|
||||
{
|
||||
struct ip6_rthdr *rthdr = (struct ip6_rthdr *) bp;
|
||||
|
||||
switch (rthdr->ip6r_type)
|
||||
{
|
||||
struct ip6_rthdr0 *rthdr0;
|
||||
case IPV6_RTHDR_TYPE_0:
|
||||
rthdr0 = (struct ip6_rthdr0 *) rthdr;
|
||||
|
||||
memcpy (&rthdr0->ip6r0_addr[rthdr0->ip6r0_segleft++],
|
||||
addr, sizeof (struct in6_addr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* RFC 3542, 7.4
|
||||
|
||||
This function takes a Routing header extension header (pointed to by
|
||||
the first argument) and writes a new Routing header that sends
|
||||
datagrams along the reverse of that route. The function reverses the
|
||||
order of the addresses and sets the segleft member in the new Routing
|
||||
header to the number of segments. */
|
||||
int
|
||||
inet6_rth_reverse (const void *in, void *out)
|
||||
{
|
||||
struct ip6_rthdr *in_rthdr = (struct ip6_rthdr *) in;
|
||||
|
||||
switch (in_rthdr->ip6r_type)
|
||||
{
|
||||
struct ip6_rthdr0 *in_rthdr0;
|
||||
struct ip6_rthdr0 *out_rthdr0;
|
||||
case IPV6_RTHDR_TYPE_0:
|
||||
in_rthdr0 = (struct ip6_rthdr0 *) in;
|
||||
out_rthdr0 = (struct ip6_rthdr0 *) out;
|
||||
|
||||
/* Copy header, not the addresses. The memory regions can overlap. */
|
||||
memmove (out_rthdr0, in_rthdr0, sizeof (struct ip6_rthdr0));
|
||||
|
||||
int total = in_rthdr0->ip6r0_segleft * 8 / sizeof (struct in6_addr);
|
||||
for (int i = 0; i < total / 2; ++i)
|
||||
{
|
||||
/* Remember, IN_RTHDR0 and OUT_RTHDR0 might overlap. */
|
||||
struct in6_addr temp = in_rthdr0->ip6r0_addr[i];
|
||||
out_rthdr0->ip6r0_addr[i] = in_rthdr0->ip6r0_addr[total - 1 - i];
|
||||
out_rthdr0->ip6r0_addr[total - 1 - i] = temp;
|
||||
}
|
||||
if (total % 2 != 0 && in != out)
|
||||
out_rthdr0->ip6r0_addr[total / 2] = in_rthdr0->ip6r0_addr[total / 2];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* RFC 3542, 7.5
|
||||
|
||||
This function returns the number of segments (addresses) contained in
|
||||
the Routing header described by BP. */
|
||||
int
|
||||
inet6_rth_segments (const void *bp)
|
||||
{
|
||||
struct ip6_rthdr *rthdr = (struct ip6_rthdr *) bp;
|
||||
|
||||
switch (rthdr->ip6r_type)
|
||||
{
|
||||
case IPV6_RTHDR_TYPE_0:
|
||||
|
||||
return rthdr->ip6r_len * 8 / sizeof (struct in6_addr);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* RFC 3542, 7.6
|
||||
|
||||
This function returns a pointer to the IPv6 address specified by
|
||||
index (which must have a value between 0 and one less than the
|
||||
value returned by 'inet6_rth_segments') in the Routing header
|
||||
described by BP. */
|
||||
struct in6_addr *
|
||||
inet6_rth_getaddr (const void *bp, int index)
|
||||
{
|
||||
struct ip6_rthdr *rthdr = (struct ip6_rthdr *) bp;
|
||||
|
||||
switch (rthdr->ip6r_type)
|
||||
{
|
||||
struct ip6_rthdr0 *rthdr0;
|
||||
case IPV6_RTHDR_TYPE_0:
|
||||
rthdr0 = (struct ip6_rthdr0 *) rthdr;
|
||||
|
||||
if (index >= rthdr0->ip6r0_len * 8 / sizeof (struct in6_addr))
|
||||
break;
|
||||
|
||||
return &rthdr0->ip6r0_addr[index];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991,92,93,94,95,96,97,2000 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-1997,2000,2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -191,13 +191,13 @@ struct nd_opt_hdr /* Neighbor discovery option header */
|
||||
/* followed by option specific data */
|
||||
};
|
||||
|
||||
#define ND_OPT_SOURCE_LINKADDR 1
|
||||
#define ND_OPT_TARGET_LINKADDR 2
|
||||
#define ND_OPT_PREFIX_INFORMATION 3
|
||||
#define ND_OPT_REDIRECTED_HEADER 4
|
||||
#define ND_OPT_MTU 5
|
||||
#define ND_OPT_RTR_ADV_INTERVAL 7
|
||||
#define ND_OPT_HOME_AGENT_INFO 8
|
||||
#define ND_OPT_SOURCE_LINKADDR 1
|
||||
#define ND_OPT_TARGET_LINKADDR 2
|
||||
#define ND_OPT_PREFIX_INFORMATION 3
|
||||
#define ND_OPT_REDIRECTED_HEADER 4
|
||||
#define ND_OPT_MTU 5
|
||||
#define ND_OPT_RTR_ADV_INTERVAL 7
|
||||
#define ND_OPT_HOME_AGENT_INFO 8
|
||||
|
||||
struct nd_opt_prefix_info /* prefix information */
|
||||
{
|
||||
@ -211,9 +211,9 @@ struct nd_opt_prefix_info /* prefix information */
|
||||
struct in6_addr nd_opt_pi_prefix;
|
||||
};
|
||||
|
||||
#define ND_OPT_PI_FLAG_ONLINK 0x80
|
||||
#define ND_OPT_PI_FLAG_AUTO 0x40
|
||||
#define ND_OPT_PI_FLAG_RADDR 0x20
|
||||
#define ND_OPT_PI_FLAG_ONLINK 0x80
|
||||
#define ND_OPT_PI_FLAG_AUTO 0x40
|
||||
#define ND_OPT_PI_FLAG_RADDR 0x20
|
||||
|
||||
struct nd_opt_rd_hdr /* redirected header */
|
||||
{
|
||||
@ -300,11 +300,11 @@ struct rr_pco_use /* use prefix part */
|
||||
#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
# define ICMP6_RR_PCOUSE_DECRVLTIME 0x80000000
|
||||
# define ICMP6_RR_PCOUSE_DECRPLTIME 0x40000000
|
||||
# define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000
|
||||
# define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000
|
||||
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define ICMP6_RR_PCOUSE_DECRVLTIME 0x80
|
||||
# define ICMP6_RR_PCOUSE_DECRPLTIME 0x40
|
||||
# define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80
|
||||
# define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40
|
||||
#endif
|
||||
|
||||
struct rr_result /* router renumbering result message */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991-2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-2001, 2003, 2004, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -455,25 +455,66 @@ extern int bindresvport6 (int __sockfd, struct sockaddr_in6 *__sock_in)
|
||||
/* IPv6 packet information. */
|
||||
struct in6_pktinfo
|
||||
{
|
||||
struct in6_addr ipi6_addr; /* src/dst IPv6 address */
|
||||
unsigned int ipi6_ifindex; /* send/recv interface index */
|
||||
struct in6_addr ipi6_addr; /* src/dst IPv6 address */
|
||||
unsigned int ipi6_ifindex; /* send/recv interface index */
|
||||
};
|
||||
|
||||
/* IPv6 MTU information. */
|
||||
struct ip6_mtuinfo
|
||||
{
|
||||
struct sockaddr_in6 ip6m_addr; /* dst address including zone ID */
|
||||
uint32_t ip6m_mtu; /* path MTU in host byte order */
|
||||
};
|
||||
|
||||
|
||||
#ifdef __USE_GNU
|
||||
/* Hop-by-Hop and Destination Options Processing. */
|
||||
extern int inet6_option_space (int __nbytes) __THROW;
|
||||
/* Obsolete hop-by-hop and Destination Options Processing (RFC 2292). */
|
||||
extern int inet6_option_space (int __nbytes)
|
||||
__THROW __attribute_deprecated__;
|
||||
extern int inet6_option_init (void *__bp, struct cmsghdr **__cmsgp,
|
||||
int __type) __THROW;
|
||||
int __type) __THROW __attribute_deprecated__;
|
||||
extern int inet6_option_append (struct cmsghdr *__cmsg,
|
||||
__const uint8_t *__typep, int __multx,
|
||||
int __plusy) __THROW;
|
||||
int __plusy) __THROW __attribute_deprecated__;
|
||||
extern uint8_t *inet6_option_alloc (struct cmsghdr *__cmsg, int __datalen,
|
||||
int __multx, int __plusy) __THROW;
|
||||
int __multx, int __plusy)
|
||||
__THROW __attribute_deprecated__;
|
||||
extern int inet6_option_next (__const struct cmsghdr *__cmsg,
|
||||
uint8_t **__tptrp) __THROW;
|
||||
uint8_t **__tptrp)
|
||||
__THROW __attribute_deprecated__;
|
||||
extern int inet6_option_find (__const struct cmsghdr *__cmsg,
|
||||
uint8_t **__tptrp, int __type) __THROW;
|
||||
uint8_t **__tptrp, int __type)
|
||||
__THROW __attribute_deprecated__;
|
||||
|
||||
|
||||
/* Hop-by-Hop and Destination Options Processing (RFC 3542). */
|
||||
extern int inet6_opt_init (void *__extbuf, socklen_t __extlen) __THROW;
|
||||
extern int inet6_opt_append (void *__extbuf, socklen_t __extlen, int __offset,
|
||||
uint8_t __type, socklen_t __len, uint8_t __align,
|
||||
void **__databufp) __THROW;
|
||||
extern int inet6_opt_finish (void *__extbuf, socklen_t __extlen, int __offset)
|
||||
__THROW;
|
||||
extern int inet6_opt_set_val (void *__databuf, int __offset, void *__val,
|
||||
socklen_t __vallen) __THROW;
|
||||
extern int inet6_opt_next (void *__extbuf, socklen_t __extlen, int __offset,
|
||||
uint8_t *__typep, socklen_t *__lenp,
|
||||
void **__databufp) __THROW;
|
||||
extern int inet6_opt_find (void *__extbuf, socklen_t __extlen, int __offset,
|
||||
uint8_t __type, socklen_t *__lenp,
|
||||
void **__databufp) __THROW;
|
||||
extern int inet6_opt_get_val (void *__databuf, int __offset, void *__val,
|
||||
socklen_t __vallen) __THROW;
|
||||
|
||||
|
||||
/* Routing Header Option (RFC 3542). */
|
||||
extern socklen_t inet6_rth_space (int __type, int __segments) __THROW;
|
||||
extern void *inet6_rth_init (void *__bp, socklen_t __bp_len, int __type,
|
||||
int __segments) __THROW;
|
||||
extern int inet6_rth_add (void *__bp, __const struct in6_addr *__addr) __THROW;
|
||||
extern int inet6_rth_reverse (__const void *__in, void *__out) __THROW;
|
||||
extern int inet6_rth_segments (__const void *__bp) __THROW;
|
||||
extern struct in6_addr *inet6_rth_getaddr (__const void *__bp, int __index)
|
||||
__THROW;
|
||||
|
||||
|
||||
/* Multicast source filter support. */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1991-1997, 2001, 2003 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1991-1997, 2001, 2003, 2006 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -89,7 +89,8 @@ struct ip6_rthdr0
|
||||
uint8_t ip6r0_segleft; /* segments left */
|
||||
uint8_t ip6r0_reserved; /* reserved field */
|
||||
uint8_t ip6r0_slmap[3]; /* strict/loose bit map */
|
||||
struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */
|
||||
/* followed by up to 127 struct in6_addr */
|
||||
struct in6_addr ip6r0_addr[0];
|
||||
};
|
||||
|
||||
/* Fragment header */
|
||||
@ -101,14 +102,14 @@ struct ip6_frag
|
||||
uint32_t ip6f_ident; /* identification */
|
||||
};
|
||||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */
|
||||
#define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */
|
||||
#define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
# define IP6F_OFF_MASK 0xfff8 /* mask out offset from _offlg */
|
||||
# define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */
|
||||
# define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */
|
||||
#else /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
#define IP6F_OFF_MASK 0xf8ff /* mask out offset from _offlg */
|
||||
#define IP6F_RESERVED_MASK 0x0600 /* reserved bits in ip6f_offlg */
|
||||
#define IP6F_MORE_FRAG 0x0100 /* more-fragments flag */
|
||||
# define IP6F_OFF_MASK 0xf8ff /* mask out offset from _offlg */
|
||||
# define IP6F_RESERVED_MASK 0x0600 /* reserved bits in ip6f_offlg */
|
||||
# define IP6F_MORE_FRAG 0x0100 /* more-fragments flag */
|
||||
#endif
|
||||
|
||||
/* IPv6 options */
|
||||
@ -175,7 +176,7 @@ struct ip6_opt_router
|
||||
};
|
||||
|
||||
/* Router alert values (in network byte order) */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
# define IP6_ALERT_MLD 0x0000
|
||||
# define IP6_ALERT_RSVP 0x0001
|
||||
# define IP6_ALERT_AN 0x0002
|
||||
|
Loading…
Reference in New Issue
Block a user