diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 18:26:36 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 18:26:36 +0000 |
commit | 0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch) | |
tree | 2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /inet | |
parent | 7d58530341304d403a6626d7f7a1913165fe2f32 (diff) | |
download | glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.gz glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.xz glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.zip |
2.5-18.1
Diffstat (limited to 'inet')
-rw-r--r-- | inet/Makefile | 6 | ||||
-rw-r--r-- | inet/Versions | 6 | ||||
-rw-r--r-- | inet/check_pf.c | 56 | ||||
-rw-r--r-- | inet/getipv4sourcefilter.c | 32 | ||||
-rw-r--r-- | inet/getnameinfo.c | 96 | ||||
-rw-r--r-- | inet/getnetgrent_r.c | 133 | ||||
-rw-r--r-- | inet/getsourcefilter.c | 33 | ||||
-rw-r--r-- | inet/herrno-loc.c | 34 | ||||
-rw-r--r-- | inet/htonl.c | 36 | ||||
-rw-r--r-- | inet/htons.c | 36 | ||||
-rw-r--r-- | inet/if_index.c | 65 | ||||
-rw-r--r-- | inet/ifaddrs.c | 46 | ||||
-rw-r--r-- | inet/ifreq.c | 80 | ||||
-rw-r--r-- | inet/inet6_opt.c | 278 | ||||
-rw-r--r-- | inet/inet6_option.c | 44 | ||||
-rw-r--r-- | inet/inet6_rth.c | 192 | ||||
-rw-r--r-- | inet/inet_ntoa.c | 69 | ||||
-rw-r--r-- | inet/netinet/icmp6.h | 132 | ||||
-rw-r--r-- | inet/netinet/in.h | 61 | ||||
-rw-r--r-- | inet/netinet/ip6.h | 89 | ||||
-rw-r--r-- | inet/rcmd.c | 100 | ||||
-rw-r--r-- | inet/rexec.c | 10 | ||||
-rw-r--r-- | inet/setipv4sourcefilter.c | 33 | ||||
-rw-r--r-- | inet/setsourcefilter.c | 33 | ||||
-rw-r--r-- | inet/test-ifaddrs.c | 9 | ||||
-rw-r--r-- | inet/test-inet6_opt.c | 207 | ||||
-rw-r--r-- | inet/test_ifindex.c | 9 |
27 files changed, 1602 insertions, 323 deletions
diff --git a/inet/Makefile b/inet/Makefile index 0fdf9e33e4..3f796e4487 100644 --- a/inet/Makefile +++ b/inet/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-2002, 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 1991-2006, 2007 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,12 +47,12 @@ 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 tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \ - tst-gethnm test-ifaddrs bug-if1 + tst-gethnm test-ifaddrs bug-if1 test-inet6_opt include ../Rules diff --git a/inet/Versions b/inet/Versions index 2b7ec901ff..06507199a9 100644 --- a/inet/Versions +++ b/inet/Versions @@ -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; diff --git a/inet/check_pf.c b/inet/check_pf.c new file mode 100644 index 0000000000..b015432659 --- /dev/null +++ b/inet/check_pf.c @@ -0,0 +1,56 @@ +/* Determine protocol families for which interfaces exist. Generic version. + Copyright (C) 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 + 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 <ifaddrs.h> +#include <netdb.h> + + +void +attribute_hidden +__check_pf (bool *seen_ipv4, bool *seen_ipv6, + struct in6addrinfo **in6ai, size_t *in6ailen) +{ + /* By default we have no way to determine information about + deprecated and temporary addresses. */ + *in6ai = NULL; + *in6ailen = 0; + + /* Get the interface list via getifaddrs. */ + struct ifaddrs *ifa = NULL; + if (getifaddrs (&ifa) != 0) + { + /* We cannot determine what interfaces are available. Be + pessimistic. */ + *seen_ipv4 = true; + *seen_ipv6 = true; + return; + } + + *seen_ipv4 = false; + *seen_ipv6 = false; + + struct ifaddrs *runp; + for (runp = ifa; runp != NULL; runp = runp->ifa_next) + if (runp->ifa_addr->sa_family == PF_INET) + *seen_ipv4 = true; + else if (runp->ifa_addr->sa_family == PF_INET6) + *seen_ipv6 = true; + + (void) freeifaddrs (ifa); +} diff --git a/inet/getipv4sourcefilter.c b/inet/getipv4sourcefilter.c new file mode 100644 index 0000000000..e95697778a --- /dev/null +++ b/inet/getipv4sourcefilter.c @@ -0,0 +1,32 @@ +/* Get source filter. Stub version. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 <errno.h> +#include <netinet/in.h> + + +int +getipv4sourcefilter (int s, struct in_addr interface, struct in_addr group, + uint32_t *fmode, uint32_t *numsrc, struct in_addr *slist) +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (getipv4sourcefilter) diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c index 493a423c10..b7b2b151b2 100644 --- a/inet/getnameinfo.c +++ b/inet/getnameinfo.c @@ -203,48 +203,40 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, if (!(flags & NI_NUMERICHOST)) { struct hostent *h = NULL; + if (sa->sa_family == AF_INET6) + { + while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in6 *) sa)->sin6_addr), + sizeof(struct in6_addr), + AF_INET6, &th, tmpbuf, tmpbuflen, + &h, &herrno)) + if (herrno == NETDB_INTERNAL && errno == ERANGE) + tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); + else + break; + } + else + { + while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr), + sizeof(struct in_addr), AF_INET, + &th, tmpbuf, tmpbuflen, + &h, &herrno)) + if (herrno == NETDB_INTERNAL && errno == ERANGE) + tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); + else + break; + } + if (h == NULL) { - if (sa->sa_family == AF_INET6) + if (herrno == NETDB_INTERNAL) { - while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in6 *) sa)->sin6_addr), - sizeof(struct in6_addr), - AF_INET6, &th, tmpbuf, tmpbuflen, - &h, &herrno)) - { - if (herrno == NETDB_INTERNAL) - { - if (errno == ERANGE) - tmpbuf = extend_alloca (tmpbuf, tmpbuflen, - 2 * tmpbuflen); - else - { - __set_h_errno (herrno); - __set_errno (serrno); - return EAI_SYSTEM; - } - } - else - { - break; - } - } + __set_h_errno (herrno); + return EAI_SYSTEM; } - else + if (herrno == TRY_AGAIN) { - while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr), - sizeof(struct in_addr), AF_INET, - &th, tmpbuf, tmpbuflen, - &h, &herrno)) - { - if (errno == ERANGE) - tmpbuf = extend_alloca (tmpbuf, tmpbuflen, - 2 * tmpbuflen); - else - { - break; - } - } + __set_h_errno (herrno); + return EAI_AGAIN; } } @@ -361,10 +353,7 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, (const void *) &(((const struct sockaddr_in *) sa)->sin_addr), host, hostlen); if (c == NULL) - { - __set_errno (serrno); - return EAI_SYSTEM; - } + return EAI_SYSTEM; } ok = 1; } @@ -403,25 +392,16 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, if (!(flags & NI_NUMERICSERV)) { struct servent *s, ts; - while (__getservbyport_r (((const struct sockaddr_in *) sa)->sin_port, - ((flags & NI_DGRAM) ? "udp" : "tcp"), - &ts, tmpbuf, tmpbuflen, &s)) + int e; + while ((e = __getservbyport_r (((const struct sockaddr_in *) sa)->sin_port, + ((flags & NI_DGRAM) + ? "udp" : "tcp"), + &ts, tmpbuf, tmpbuflen, &s))) { - if (herrno == NETDB_INTERNAL) - { - if (errno == ERANGE) - tmpbuf = extend_alloca (tmpbuf, tmpbuflen, - 2 * tmpbuflen); - else - { - __set_errno (serrno); - return EAI_SYSTEM; - } - } + if (e == ERANGE) + tmpbuf = extend_alloca (tmpbuf, tmpbuflen, 2 * tmpbuflen); else - { - break; - } + break; } if (s) { diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c index 640210ab2e..97b2b809f0 100644 --- a/inet/getnetgrent_r.c +++ b/inet/getnetgrent_r.c @@ -1,4 +1,5 @@ -/* Copyright (C) 1996,1997,1998,1999,2002,2004 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997, 1998, 1999, 2002, 2004, 2005 + 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 @@ -16,6 +17,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <assert.h> #include <bits/libc-lock.h> #include <errno.h> #include <netdb.h> @@ -33,15 +35,13 @@ __libc_lock_define_initialized (static, lock) static struct __netgrent dataset; /* The lookup function for the first entry of this service. */ -extern int __nss_netgroup_lookup (service_user **nip, const char *name, +extern int __nss_netgroup_lookup (service_user **nipp, const char *name, void **fctp) internal_function; - -/* Set up NIP to run through the services. If ALL is zero, use NIP's - current location if it's not nil. Return nonzero if there are no +/* Set up NIP to run through the services. Return nonzero if there are no services (left). */ -static enum nss_status -setup (void **fctp, const char *func_name, int all, service_user **nipp) +static int +setup (void **fctp, service_user **nipp) { /* Remember the first service_entry, it's always the same. */ static service_user *startp; @@ -51,7 +51,7 @@ setup (void **fctp, const char *func_name, int all, service_user **nipp) { /* Executing this more than once at the same time must yield the same result every time. So we need no locking. */ - no_more = __nss_netgroup_lookup (nipp, func_name, fctp); + no_more = __nss_netgroup_lookup (nipp, "setnetgrent", fctp); startp = no_more ? (service_user *) -1 : *nipp; } else if (startp == (service_user *) -1) @@ -59,11 +59,10 @@ setup (void **fctp, const char *func_name, int all, service_user **nipp) return 1; else { - if (all || *nipp == NULL) - /* Reset to the beginning of the service list. */ - *nipp = startp; + /* Reset to the beginning of the service list. */ + *nipp = startp; /* Look up the first function. */ - no_more = __nss_lookup (nipp, func_name, fctp); + no_more = __nss_lookup (nipp, "setnetgrent", fctp); } return no_more; } @@ -87,6 +86,20 @@ free_memory (struct __netgrent *data) } } +static void +endnetgrent_hook (struct __netgrent *datap) +{ + enum nss_status (*endfct) (struct __netgrent *); + + if (datap->nip == NULL) + return; + + endfct = __nss_lookup_function (datap->nip, "endnetgrent"); + if (endfct != NULL) + (void) (*endfct) (datap); + datap->nip = NULL; +} + static int internal_function __internal_setnetgrent_reuse (const char *group, struct __netgrent *datap, @@ -100,14 +113,29 @@ __internal_setnetgrent_reuse (const char *group, struct __netgrent *datap, enum nss_status status = NSS_STATUS_UNAVAIL; struct name_list *new_elem; + /* Free data from previous service. */ + endnetgrent_hook (datap); + /* Cycle through all the services and run their setnetgrent functions. */ - int no_more = setup (&fct.ptr, "setnetgrent", 1, &datap->nip); + int no_more = setup (&fct.ptr, &datap->nip); while (! no_more) { + assert (datap->data == NULL); + /* Ignore status, we force check in `__nss_next'. */ status = (*fct.f) (group, datap); + service_user *old_nip = datap->nip; no_more = __nss_next (&datap->nip, "setnetgrent", &fct.ptr, status, 0); + + if (status == NSS_STATUS_SUCCESS && ! no_more) + { + enum nss_status (*endfct) (struct __netgrent *); + + endfct = __nss_lookup_function (old_nip, "endnetgrent"); + if (endfct != NULL) + (void) (*endfct) (datap); + } } /* Add the current group to the list of known groups. */ @@ -157,34 +185,13 @@ setnetgrent (const char *group) return result; } - void internal_endnetgrent (struct __netgrent *datap); libc_hidden_proto (internal_endnetgrent) void internal_endnetgrent (struct __netgrent *datap) { - service_user *old_nip; - union - { - enum nss_status (*f) (struct __netgrent *); - void *ptr; - } fct; - - /* Remember which was the last used service. */ - old_nip = datap->nip; - - /* Cycle through all the services and run their endnetgrent functions. */ - int no_more = setup (&fct.ptr, "endnetgrent", 1, &datap->nip); - while (! no_more) - { - /* Ignore status, we force check in `__nss_next'. */ - (void) (*fct.f) (datap); - - no_more = (datap->nip == old_nip - || __nss_next (&datap->nip, "endnetgrent", &fct.ptr, 0, 1)); - } - + endnetgrent_hook (datap); /* Now free list of all netgroup names from last run. */ free_memory (datap); } @@ -213,11 +220,7 @@ internal_getnetgrent_r (char **hostp, char **userp, char **domainp, struct __netgrent *datap, char *buffer, size_t buflen, int *errnop) { - union - { - enum nss_status (*f) (struct __netgrent *, char *, size_t, int *); - void *ptr; - } fct; + enum nss_status (*fct) (struct __netgrent *, char *, size_t, int *); /* Initialize status to return if no more functions are found. */ enum nss_status status = NSS_STATUS_NOTFOUND; @@ -225,10 +228,12 @@ internal_getnetgrent_r (char **hostp, char **userp, char **domainp, /* Run through available functions, starting with the same function last run. We will repeat each function as long as it succeeds, and then go on to the next service action. */ - int no_more = setup (&fct.ptr, "getnetgrent_r", 0, &datap->nip); + int no_more = (datap->nip == NULL + || (fct = __nss_lookup_function (datap->nip, "getnetgrent_r")) + == NULL); while (! no_more) { - status = (*fct.f) (datap, buffer, buflen, &errno); + status = (*fct) (datap, buffer, buflen, &errno); if (status == NSS_STATUS_RETURN) { @@ -246,8 +251,12 @@ internal_getnetgrent_r (char **hostp, char **userp, char **domainp, datap, errnop); } - if (found) - continue; + if (found && datap->nip != NULL) + { + fct = __nss_lookup_function (datap->nip, "getnetgrent_r"); + if (fct != NULL) + continue; + } } else if (status == NSS_STATUS_SUCCESS && datap->type == group_val) { @@ -279,7 +288,7 @@ internal_getnetgrent_r (char **hostp, char **userp, char **domainp, } } - no_more = __nss_next (&datap->nip, "getnetgrent_r", &fct.ptr, status, 0); + break; } if (status == NSS_STATUS_SUCCESS) @@ -322,16 +331,8 @@ innetgr (const char *netgroup, const char *host, const char *user, int (*f) (const char *, struct __netgrent *); void *ptr; } setfct; - union - { - void (*f) (struct __netgrent *); - void *ptr; - } endfct; - union - { - int (*f) (struct __netgrent *, char *, size_t, int *); - void *ptr; - } getfct; + void (*endfct) (struct __netgrent *); + int (*getfct) (struct __netgrent *, char *, size_t, int *); struct __netgrent entry; int result = 0; const char *current_group = netgroup; @@ -345,18 +346,21 @@ innetgr (const char *netgroup, const char *host, const char *user, the work during one walk through the service list. */ while (1) { - int no_more = setup (&setfct.ptr, "setnetgrent", 1, &entry.nip); + int no_more = setup (&setfct.ptr, &entry.nip); while (! no_more) { + assert (entry.data == NULL); + /* Open netgroup. */ enum nss_status status = (*setfct.f) (current_group, &entry); if (status == NSS_STATUS_SUCCESS - && __nss_lookup (&entry.nip, "getnetgrent_r", &getfct.ptr) == 0) + && (getfct = __nss_lookup_function (entry.nip, "getnetgrent_r")) + != NULL) { char buffer[1024]; - while ((*getfct.f) (&entry, buffer, sizeof buffer, &errno) + while ((*getfct) (&entry, buffer, sizeof buffer, &errno) == NSS_STATUS_SUCCESS) { if (entry.type == group_val) @@ -405,17 +409,18 @@ innetgr (const char *netgroup, const char *host, const char *user, } } - if (result != 0) - break; - /* If we found one service which does know the given netgroup we don't try further. */ status = NSS_STATUS_RETURN; } /* Free all resources of the service. */ - if (__nss_lookup (&entry.nip, "endnetgrent", &endfct.ptr) == 0) - (*endfct.f) (&entry); + endfct = __nss_lookup_function (entry.nip, "endnetgrent"); + if (endfct != NULL) + (*endfct) (&entry); + + if (result != 0) + break; /* Look for the next service. */ no_more = __nss_next (&entry.nip, "setnetgrent", @@ -439,6 +444,6 @@ innetgr (const char *netgroup, const char *host, const char *user, /* Free the memory. */ free_memory (&entry); - return result; + return result == 1; } libc_hidden_def (innetgr) diff --git a/inet/getsourcefilter.c b/inet/getsourcefilter.c new file mode 100644 index 0000000000..373550beb3 --- /dev/null +++ b/inet/getsourcefilter.c @@ -0,0 +1,33 @@ +/* Get source filter. Stub version. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 <errno.h> +#include <netinet/in.h> + + +int +getsourcefilter (int s, uint32_t interface, const struct sockaddr *group, + socklen_t grouplen, uint32_t *fmode, uint32_t *numsrc, + struct sockaddr_storage *slist) +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (getsourcefilter) diff --git a/inet/herrno-loc.c b/inet/herrno-loc.c new file mode 100644 index 0000000000..fd6deeb330 --- /dev/null +++ b/inet/herrno-loc.c @@ -0,0 +1,34 @@ +/* Copyright (C) 1996, 97, 98, 2002 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 + 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 <netdb.h> +#include <tls.h> + +#if ! USE___THREAD +# undef h_errno +extern int h_errno; +#endif + +/* When threaded, h_errno may be a per-thread variable. */ +int * +weak_const_function +__h_errno_location (void) +{ + return &h_errno; +} +libc_hidden_def (__h_errno_location) diff --git a/inet/htonl.c b/inet/htonl.c new file mode 100644 index 0000000000..dfee1b0545 --- /dev/null +++ b/inet/htonl.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1993,97,2002 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 + 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 <netinet/in.h> + +#undef htonl +#undef ntohl + +uint32_t +htonl (x) + uint32_t x; +{ +#if BYTE_ORDER == BIG_ENDIAN + return x; +#elif BYTE_ORDER == LITTLE_ENDIAN + return __bswap_32 (x); +#else +# error "What kind of system is this?" +#endif +} +weak_alias (htonl, ntohl) diff --git a/inet/htons.c b/inet/htons.c new file mode 100644 index 0000000000..95c94de8a3 --- /dev/null +++ b/inet/htons.c @@ -0,0 +1,36 @@ +/* Copyright (C) 1993,97,2002 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 + 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 <netinet/in.h> + +#undef htons +#undef ntohs + +uint16_t +htons (x) + uint16_t x; +{ +#if BYTE_ORDER == BIG_ENDIAN + return x; +#elif BYTE_ORDER == LITTLE_ENDIAN + return __bswap_16 (x); +#else +# error "What kind of system is this?" +#endif +} +weak_alias (htons, ntohs) diff --git a/inet/if_index.c b/inet/if_index.c new file mode 100644 index 0000000000..f217f37642 --- /dev/null +++ b/inet/if_index.c @@ -0,0 +1,65 @@ +/* Copyright (C) 1997,98,99,2000,02 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 + 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 <net/if.h> +#include <errno.h> +#include <stddef.h> + +unsigned int +if_nametoindex (const char *ifname) +{ + __set_errno (ENOSYS); + return 0; +} +libc_hidden_def (if_nametoindex) +stub_warning (if_nametoindex) + +char * +if_indextoname (unsigned int ifindex, char *ifname) +{ + __set_errno (ENOSYS); + return NULL; +} +libc_hidden_def (if_indextoname) +stub_warning (if_indextoname) + +void +if_freenameindex (struct if_nameindex *ifn) +{ +} +stub_warning (if_freenameindex) + +struct if_nameindex * +if_nameindex (void) +{ + __set_errno (ENOSYS); + return NULL; +} +stub_warning (if_nameindex) +#include <stub-tag.h> + +#if 0 +void +internal_function +__protocol_available (int *have_inet, int *have_inet6) +{ + /* By default we assume that IPv4 is available, IPv6 not. */ + *have_inet = 1; + *have_inet6 = 0; +} +#endif diff --git a/inet/ifaddrs.c b/inet/ifaddrs.c new file mode 100644 index 0000000000..330aae3b39 --- /dev/null +++ b/inet/ifaddrs.c @@ -0,0 +1,46 @@ +/* getifaddrs -- get names and addresses of all network interfaces + Copyright (C) 2002, 2003 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 + 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 <ifaddrs.h> +#include <errno.h> +#include <stdlib.h> + +/* Create a linked list of `struct ifaddrs' structures, one for each + network interface on the host machine. If successful, store the + list in *IFAP and return 0. On errors, return -1 and set `errno'. */ +int +getifaddrs (struct ifaddrs **ifap) +{ + __set_errno (ENOSYS); + return -1; +} +libc_hidden_def (getifaddrs) +stub_warning (getifaddrs) + +void +freeifaddrs (struct ifaddrs *ifa) +{ + if (ifa == NULL) + return; /* a la free, why not? */ + + /* Can't be called properly if getifaddrs never succeeded. */ + abort (); +} +libc_hidden_def (freeifaddrs) +stub_warning (freeifaddrs) diff --git a/inet/ifreq.c b/inet/ifreq.c new file mode 100644 index 0000000000..55e833bdb3 --- /dev/null +++ b/inet/ifreq.c @@ -0,0 +1,80 @@ +/* Copyright (C) 1999, 2002, 2003, 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Andreas Jaeger <aj@suse.de>. + + 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 "ifreq.h" + + +void +__ifreq (struct ifreq **ifreqs, int *num_ifs, int sockfd) +{ + int fd = sockfd; + struct ifconf ifc; + int rq_len; + int nifs; +# define RQ_IFS 4 + + if (fd < 0) + fd = __opensock (); + if (fd < 0) + { + *num_ifs = 0; + *ifreqs = NULL; + return; + } + + ifc.ifc_buf = NULL; + rq_len = RQ_IFS * sizeof (struct ifreq) / 2; /* Doubled in the loop. */ + do + { + ifc.ifc_len = rq_len *= 2; + void *newp = realloc (ifc.ifc_buf, ifc.ifc_len); + if (newp == NULL || __ioctl (fd, SIOCGIFCONF, &ifc) < 0) + { + free (ifc.ifc_buf); + + if (fd != sockfd) + __close (fd); + *num_ifs = 0; + *ifreqs = NULL; + return; + } + ifc.ifc_buf = newp; + } + while (rq_len < sizeof (struct ifreq) + ifc.ifc_len); + + if (fd != sockfd) + __close (fd); + +#ifdef _HAVE_SA_LEN + struct ifreq *ifr = *ifreqs; + nifs = 0; + while ((char *) ifr < ifc.ifc_buf + ifc.ifc_len) + { + ++nifs; + ifr = __if_nextreq (ifr); + if (ifr == NULL) + break; + } +#else + nifs = ifc.ifc_len / sizeof (struct ifreq); +#endif + + *num_ifs = nifs; + *ifreqs = realloc (ifc.ifc_buf, nifs * sizeof (struct ifreq)); +} diff --git a/inet/inet6_opt.c b/inet/inet6_opt.c new file mode 100644 index 0000000000..17d3fee213 --- /dev/null +++ b/inet/inet6_opt.c @@ -0,0 +1,278 @@ +/* Copyright (C) 2006, 2007 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 if (npad > 0) + { + 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); + + if (extbuf != NULL) + { + /* Now we can check whether the buffer is large enough. */ + if (data_offset + npad + len > extlen) + return -1; + + add_padding (extbuf, offset, npad); + + offset += npad; + + /* Now prepare the option itself. */ + struct ip6_opt *opt = (struct ip6_opt *) ((uint8_t *) extbuf + offset); + + opt->ip6o_type = type; + opt->ip6o_len = len; + + *databufp = opt + 1; + } + else + offset += npad; + + 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; + + if (extbuf != NULL) + { + /* Make sure the buffer is large enough. */ + if (offset + npad > extlen) + return -1; + + 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; +} diff --git a/inet/inet6_option.c b/inet/inet6_option.c index 2e0fed8a30..b34eb22b7d 100644 --- a/inet/inet6_option.c +++ b/inet/inet6_option.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 Free Software Foundation, Inc. +/* Copyright (C) 2003, 2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. @@ -75,6 +75,10 @@ get_opt_end (const uint8_t **result, const uint8_t *startp, } +static uint8_t *option_alloc (struct cmsghdr *cmsg, int datalen, int multx, + int plusy); + + /* RFC 2292, 6.3.1 This function returns the number of bytes required to hold an option @@ -93,6 +97,8 @@ inet6_option_space (nbytes) return CMSG_SPACE (roundup (nbytes, 8)); } +link_warning (inet6_option_space, + "inet6_option_space is obsolete, use the RFC 3542 interfaces") /* RFC 2292, 6.3.2 @@ -127,6 +133,8 @@ inet6_option_init (bp, cmsgp, type) return 0; } +link_warning (inet6_option_init, + "inet6_option_init is obsolete, use the RFC 3542 interfaces") /* RFC 2292, 6.3.3 @@ -150,7 +158,7 @@ inet6_option_append (cmsg, typep, multx, plusy) int len = typep[0] == IP6OPT_PAD1 ? 1 : typep[1] + 2; /* Get the pointer to the space in the message. */ - uint8_t *ptr = inet6_option_alloc (cmsg, len, multx, plusy); + uint8_t *ptr = option_alloc (cmsg, len, multx, plusy); if (ptr == NULL) /* Some problem with the parameters. */ return -1; @@ -160,6 +168,8 @@ inet6_option_append (cmsg, typep, multx, plusy) return 0; } +link_warning (inet6_option_append, + "inet6_option_append is obsolete, use the RFC 3542 interfaces") /* RFC 2292, 6.3.4 @@ -169,12 +179,8 @@ inet6_option_append (cmsg, typep, multx, plusy) inet6_option_init(). This function returns a pointer to the 8-bit option type field that starts the option on success, or NULL on an error. */ -uint8_t * -inet6_option_alloc (cmsg, datalen, multx, plusy) - struct cmsghdr *cmsg; - int datalen; - int multx; - int plusy; +static uint8_t * +option_alloc (struct cmsghdr *cmsg, int datalen, int multx, int plusy) { /* The RFC limits the value of the alignment values. */ if ((multx != 1 && multx != 2 && multx != 4 && multx != 8) @@ -214,7 +220,19 @@ inet6_option_alloc (cmsg, datalen, multx, plusy) return result; } -libc_hidden_def (inet6_option_alloc) + + +uint8_t * +inet6_option_alloc (cmsg, datalen, multx, plusy) + struct cmsghdr *cmsg; + int datalen; + int multx; + int plusy; +{ + return option_alloc (cmsg, datalen, multx, plusy); +} +link_warning (inet6_option_alloc, + "inet6_option_alloc is obsolete, use the RFC 3542 interfaces") /* RFC 2292, 6.3.5 @@ -251,7 +269,7 @@ inet6_option_next (cmsg, tptrp) const uint8_t *endp = CMSG_DATA (cmsg) + (ip6e->ip6e_len + 1) * 8; const uint8_t *result; - if (tptrp == NULL) + if (*tptrp == NULL) /* This is the first call, return the first option if there is one. */ result = (const uint8_t *) (ip6e + 1); else @@ -272,6 +290,8 @@ inet6_option_next (cmsg, tptrp) /* Check the option is fully represented in the message. */ return get_opt_end (&result, result, endp); } +link_warning (inet6_option_next, + "inet6_option_next is obsolete, use the RFC 3542 interfaces") /* RFC 2292, 6.3.6 @@ -308,7 +328,7 @@ inet6_option_find (cmsg, tptrp, type) const uint8_t *endp = CMSG_DATA (cmsg) + (ip6e->ip6e_len + 1) * 8; const uint8_t *next; - if (tptrp == NULL) + if (*tptrp == NULL) /* This is the first call, return the first option if there is one. */ next = (const uint8_t *) (ip6e + 1); else @@ -341,3 +361,5 @@ inet6_option_find (cmsg, tptrp, type) /* Success. */ return 0; } +link_warning (inet6_option_find, + "inet6_option_find is obsolete, use the RFC 3542 interfaces") diff --git a/inet/inet6_rth.c b/inet/inet6_rth.c new file mode 100644 index 0000000000..15f8240909 --- /dev/null +++ b/inet/inet6_rth.c @@ -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; +} diff --git a/inet/inet_ntoa.c b/inet/inet_ntoa.c index 889435dd10..38794957c2 100644 --- a/inet/inet_ntoa.c +++ b/inet/inet_ntoa.c @@ -21,78 +21,19 @@ #include <stdio.h> #include <stdlib.h> #include <arpa/inet.h> -#include <bits/libc-lock.h> /* The interface of this function is completely stupid, it requires a - static buffer. We relax this a bit in that we allow at least one - buffer for each thread. */ - -/* This is the key for the thread specific memory. */ -static __libc_key_t key; - -/* If nonzero the key allocation failed and we should better use a - static buffer than fail. */ -static char local_buf[18]; -static char *static_buf; - -/* Destructor for the thread-specific data. */ -static void init (void); -static void free_key_mem (void *mem); + static buffer. We relax this a bit in that we allow one buffer for + each thread. */ +static __thread char buffer[18]; char * inet_ntoa (struct in_addr in) { - __libc_once_define (static, once); - char *buffer; - unsigned char *bytes; - - /* If we have not yet initialized the buffer do it now. */ - __libc_once (once, init); - - if (static_buf != NULL) - buffer = static_buf; - else - { - /* We don't use the static buffer and so we have a key. Use it - to get the thread-specific buffer. */ - buffer = __libc_getspecific (key); - if (buffer == NULL) - { - /* No buffer allocated so far. */ - buffer = malloc (18); - if (buffer == NULL) - /* No more memory available. We use the static buffer. */ - buffer = local_buf; - else - __libc_setspecific (key, buffer); - } - } - - bytes = (unsigned char *) ∈ - __snprintf (buffer, 18, "%d.%d.%d.%d", + unsigned char *bytes = (unsigned char *) ∈ + __snprintf (buffer, sizeof (buffer), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]); return buffer; } - - -/* Initialize buffer. */ -static void -init (void) -{ - if (__libc_key_create (&key, free_key_mem)) - /* Creating the key failed. This means something really went - wrong. In any case use a static buffer which is better than - nothing. */ - static_buf = local_buf; -} - - -/* Free the thread specific data, this is done if a thread terminates. */ -static void -free_key_mem (void *mem) -{ - free (mem); - __libc_setspecific (key, NULL); -} diff --git a/inet/netinet/icmp6.h b/inet/netinet/icmp6.h index 4b17d9cd93..0cb1aa6a6c 100644 --- a/inet/netinet/icmp6.h +++ b/inet/netinet/icmp6.h @@ -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 @@ -33,7 +33,7 @@ struct icmp6_filter { - uint32_t data[8]; + uint32_t icmp6_filt[8]; }; struct icmp6_hdr @@ -67,14 +67,14 @@ struct icmp6_hdr #define ICMP6_ECHO_REQUEST 128 #define ICMP6_ECHO_REPLY 129 -#define ICMP6_MEMBERSHIP_QUERY 130 -#define ICMP6_MEMBERSHIP_REPORT 131 -#define ICMP6_MEMBERSHIP_REDUCTION 132 +#define MLD_LISTENER_QUERY 130 +#define MLD_LISTENER_REPORT 131 +#define MLD_LISTENER_REDUCTION 132 #define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */ #define ICMP6_DST_UNREACH_ADMIN 1 /* communication with destination */ /* administratively prohibited */ -#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor */ +#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */ #define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */ #define ICMP6_DST_UNREACH_NOPORT 4 /* bad port */ @@ -86,16 +86,16 @@ struct icmp6_hdr #define ICMP6_PARAMPROB_OPTION 2 /* unrecognized IPv6 option */ #define ICMP6_FILTER_WILLPASS(type, filterp) \ - ((((filterp)->data[(type) >> 5]) & (1 << ((type) & 31))) == 0) + ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) == 0) #define ICMP6_FILTER_WILLBLOCK(type, filterp) \ - ((((filterp)->data[(type) >> 5]) & (1 << ((type) & 31))) != 0) + ((((filterp)->icmp6_filt[(type) >> 5]) & (1 << ((type) & 31))) != 0) #define ICMP6_FILTER_SETPASS(type, filterp) \ - ((((filterp)->data[(type) >> 5]) &= ~(1 << ((type) & 31)))) + ((((filterp)->icmp6_filt[(type) >> 5]) &= ~(1 << ((type) & 31)))) #define ICMP6_FILTER_SETBLOCK(type, filterp) \ - ((((filterp)->data[(type) >> 5]) |= (1 << ((type) & 31)))) + ((((filterp)->icmp6_filt[(type) >> 5]) |= (1 << ((type) & 31)))) #define ICMP6_FILTER_SETPASSALL(filterp) \ memset (filterp, 0, sizeof (struct icmp6_filter)); @@ -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 */ { @@ -232,6 +232,98 @@ struct nd_opt_mtu /* MTU option */ uint32_t nd_opt_mtu_mtu; }; +struct mld_hdr + { + struct icmp6_hdr mld_icmp6_hdr; + struct in6_addr mld_addr; /* multicast address */ + }; + +#define mld_type mld_icmp6_hdr.icmp6_type +#define mld_code mld_icmp6_hdr.icmp6_code +#define mld_cksum mld_icmp6_hdr.icmp6_cksum +#define mld_maxdelay mld_icmp6_hdr.icmp6_data16[0] +#define mld_reserved mld_icmp6_hdr.icmp6_data16[1] + +#define ICMP6_ROUTER_RENUMBERING 138 + +struct icmp6_router_renum /* router renumbering header */ + { + struct icmp6_hdr rr_hdr; + uint8_t rr_segnum; + uint8_t rr_flags; + uint16_t rr_maxdelay; + uint32_t rr_reserved; + }; + +#define rr_type rr_hdr.icmp6_type +#define rr_code rr_hdr.icmp6_code +#define rr_cksum rr_hdr.icmp6_cksum +#define rr_seqnum rr_hdr.icmp6_data32[0] + +/* Router renumbering flags */ +#define ICMP6_RR_FLAGS_TEST 0x80 +#define ICMP6_RR_FLAGS_REQRESULT 0x40 +#define ICMP6_RR_FLAGS_FORCEAPPLY 0x20 +#define ICMP6_RR_FLAGS_SPECSITE 0x10 +#define ICMP6_RR_FLAGS_PREVDONE 0x08 + +struct rr_pco_match /* match prefix part */ + { + uint8_t rpm_code; + uint8_t rpm_len; + uint8_t rpm_ordinal; + uint8_t rpm_matchlen; + uint8_t rpm_minlen; + uint8_t rpm_maxlen; + uint16_t rpm_reserved; + struct in6_addr rpm_prefix; + }; + +/* PCO code values */ +#define RPM_PCO_ADD 1 +#define RPM_PCO_CHANGE 2 +#define RPM_PCO_SETGLOBAL 3 + +struct rr_pco_use /* use prefix part */ + { + uint8_t rpu_uselen; + uint8_t rpu_keeplen; + uint8_t rpu_ramask; + uint8_t rpu_raflags; + uint32_t rpu_vltime; + uint32_t rpu_pltime; + uint32_t rpu_flags; + struct in6_addr rpu_prefix; + }; + +#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20 +#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10 + +#if BYTE_ORDER == BIG_ENDIAN +# define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000 +# define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000 +#elif BYTE_ORDER == LITTLE_ENDIAN +# define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80 +# define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40 +#endif + +struct rr_result /* router renumbering result message */ + { + uint16_t rrr_flags; + uint8_t rrr_ordinal; + uint8_t rrr_matchedlen; + uint32_t rrr_ifid; + struct in6_addr rrr_prefix; + }; + +#if BYTE_ORDER == BIG_ENDIAN +# define ICMP6_RR_RESULT_FLAGS_OOB 0x0002 +# define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001 +#elif BYTE_ORDER == LITTLE_ENDIAN +# define ICMP6_RR_RESULT_FLAGS_OOB 0x0200 +# define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100 +#endif + /* Mobile IPv6 extension: Advertisement Interval. */ struct nd_opt_adv_interval { diff --git a/inet/netinet/in.h b/inet/netinet/in.h index 8898be3664..4fdc0fadf1 100644 --- a/inet/netinet/in.h +++ b/inet/netinet/in.h @@ -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. */ diff --git a/inet/netinet/ip6.h b/inet/netinet/ip6.h index 7045836df6..bef2af2f5a 100644 --- a/inet/netinet/ip6.h +++ b/inet/netinet/ip6.h @@ -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,18 +102,88 @@ 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 */ +struct ip6_opt + { + uint8_t ip6o_type; + uint8_t ip6o_len; + }; + +/* The high-order 3 bits of the option type define the behavior + * when processing an unknown option and whether or not the option + * content changes in flight. + */ +#define IP6OPT_TYPE(o) ((o) & 0xc0) +#define IP6OPT_TYPE_SKIP 0x00 +#define IP6OPT_TYPE_DISCARD 0x40 +#define IP6OPT_TYPE_FORCEICMP 0x80 +#define IP6OPT_TYPE_ICMP 0xc0 +#define IP6OPT_TYPE_MUTABLE 0x20 + /* Special option types for padding. */ #define IP6OPT_PAD1 0 #define IP6OPT_PADN 1 +#define IP6OPT_JUMBO 0xc2 +#define IP6OPT_NSAP_ADDR 0xc3 +#define IP6OPT_TUNNEL_LIMIT 0x04 +#define IP6OPT_ROUTER_ALERT 0x05 + +/* Jumbo Payload Option */ +struct ip6_opt_jumbo + { + uint8_t ip6oj_type; + uint8_t ip6oj_len; + uint8_t ip6oj_jumbo_len[4]; + }; +#define IP6OPT_JUMBO_LEN 6 + +/* NSAP Address Option */ +struct ip6_opt_nsap + { + uint8_t ip6on_type; + uint8_t ip6on_len; + uint8_t ip6on_src_nsap_len; + uint8_t ip6on_dst_nsap_len; + /* followed by source NSAP */ + /* followed by destination NSAP */ + }; + +/* Tunnel Limit Option */ +struct ip6_opt_tunnel + { + uint8_t ip6ot_type; + uint8_t ip6ot_len; + uint8_t ip6ot_encap_limit; + }; + +/* Router Alert Option */ +struct ip6_opt_router + { + uint8_t ip6or_type; + uint8_t ip6or_len; + uint8_t ip6or_value[2]; + }; + +/* Router alert values (in network byte order) */ +#if BYTE_ORDER == BIG_ENDIAN +# define IP6_ALERT_MLD 0x0000 +# define IP6_ALERT_RSVP 0x0001 +# define IP6_ALERT_AN 0x0002 +#else /* BYTE_ORDER == LITTLE_ENDING */ +# define IP6_ALERT_MLD 0x0000 +# define IP6_ALERT_RSVP 0x0100 +# define IP6_ALERT_AN 0x0200 +#endif + #endif /* netinet/ip6.h */ diff --git a/inet/rcmd.c b/inet/rcmd.c index 0bcb731a16..341304acd5 100644 --- a/inet/rcmd.c +++ b/inet/rcmd.c @@ -137,21 +137,13 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) (void)__snprintf(num, sizeof(num), "%d", ntohs(rport)); error = getaddrinfo(*ahost, num, &hints, &res); if (error) { - if (error == EAI_NONAME && *ahost != NULL) { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf(stderr, L"%s: Unknown host\n", - *ahost); - else - fprintf(stderr, "%s: Unknown host\n", *ahost); - } else { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf(stderr, L"rcmd: getaddrinfo: %s\n", - gai_strerror(error)); - else - fprintf(stderr, "rcmd: getaddrinfo: %s\n", - gai_strerror(error)); - } - return (-1); + if (error == EAI_NONAME && *ahost != NULL) + __fxprintf(NULL, "%s: Unknown host\n", *ahost); + else + __fxprintf(NULL, "rcmd: getaddrinfo: %s\n", + gai_strerror(error)); + + return -1; } pfd[0].events = POLLIN; @@ -161,13 +153,9 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) free (ahostbuf); ahostbuf = strdup (res->ai_canonname); if (ahostbuf == NULL) { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf(stderr, L"%s", - _("rcmd: Cannot allocate memory\n")); - else - fputs(_("rcmd: Cannot allocate memory\n"), - stderr); - return (-1); + __fxprintf(NULL, "%s", + _("rcmd: Cannot allocate memory\n")); + return -1; } *ahost = ahostbuf; } else @@ -180,20 +168,12 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) s = rresvport_af(&lport, ai->ai_family); if (s < 0) { - if (errno == EAGAIN) { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf(stderr, L"%s", - _("rcmd: socket: All ports in use\n")); - else - fputs(_("rcmd: socket: All ports in use\n"), - stderr); - } else { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf(stderr, - L"rcmd: socket: %m\n"); - else - fprintf(stderr, "rcmd: socket: %m\n"); - } + if (errno == EAGAIN) + __fxprintf(NULL, "%s", _("\ +rcmd: socket: All ports in use\n")); + else + __fxprintf(NULL, "rcmd: socket: %m\n"); + __sigsetmask(oldmask); freeaddrinfo(res); return -1; @@ -220,10 +200,7 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) if (__asprintf (&buf, _("connect to address %s: "), paddr) >= 0) { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf(stderr, L"%s", buf); - else - fputs (buf, stderr); + __fxprintf(NULL, "%s", buf); free (buf); } __set_errno (oerrno); @@ -235,10 +212,7 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) NI_NUMERICHOST); if (__asprintf (&buf, _("Trying %s...\n"), paddr) >= 0) { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s", buf); - else - fputs (buf, stderr); + __fxprintf (NULL, "%s", buf); free (buf); } continue; @@ -251,14 +225,8 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) continue; } freeaddrinfo(res); - if (_IO_fwide (stderr, 0) > 0) - (void)__fwprintf(stderr, L"%s: %s\n", *ahost, - __strerror_r(errno, - errbuf, sizeof (errbuf))); - else - (void)fprintf(stderr, "%s: %s\n", *ahost, - __strerror_r(errno, - errbuf, sizeof (errbuf))); + (void)__fxprintf(NULL, "%s: %s\n", *ahost, + __strerror_r(errno, errbuf, sizeof (errbuf))); __sigsetmask(oldmask); return -1; } @@ -281,10 +249,7 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af) if (__asprintf (&buf, _("\ rcmd: write (setting up stderr): %m\n")) >= 0) { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf(stderr, L"%s", buf); - else - fputs (buf, stderr); + __fxprintf(NULL, "%s", buf); free (buf); } (void)__close(s2); @@ -303,10 +268,7 @@ rcmd: poll (setting up stderr): %m\n")) >= 0) && __asprintf(&buf, _("\ poll: protocol failure in circuit setup\n")) >= 0)) { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s", buf); - else - fputs (buf, stderr); + __fxprintf (NULL, "%s", buf); free (buf); } (void)__close(s2); @@ -327,12 +289,7 @@ poll: protocol failure in circuit setup\n")) >= 0)) } (void)__close(s2); if (s3 < 0) { - if (_IO_fwide (stderr, 0) > 0) - (void)__fwprintf(stderr, - L"rcmd: accept: %m\n"); - else - (void)fprintf(stderr, - "rcmd: accept: %m\n"); + (void)__fxprintf(NULL, "rcmd: accept: %m\n"); lport = 0; goto bad; } @@ -344,10 +301,7 @@ poll: protocol failure in circuit setup\n")) >= 0)) if (__asprintf(&buf, _("\ socket: protocol failure in circuit setup\n")) >= 0) { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s", buf); - else - fputs (buf, stderr); + __fxprintf (NULL, "%s", buf); free (buf); } goto bad2; @@ -373,10 +327,7 @@ socket: protocol failure in circuit setup\n")) >= 0) || (n != 0 && __asprintf(&buf, "rcmd: %s: %m\n", *ahost) >= 0)) { - if (_IO_fwide (stderr, 0) > 0) - __fwprintf (stderr, L"%s", buf); - else - fputs (buf, stderr); + __fxprintf (NULL, "%s", buf); free (buf); } goto bad2; @@ -526,7 +477,6 @@ iruserfopen (const char *file, uid_t okuser) /* If not a regular file, if owned by someone other than user or root, if writeable by anyone but the owner, or if hardlinked anywhere, quit. */ - cp = NULL; if (__lxstat64 (_STAT_VER, file, &st)) cp = _("lstat failed"); else if (!S_ISREG (st.st_mode)) diff --git a/inet/rexec.c b/inet/rexec.c index 3c14836aa2..07ddeeafea 100644 --- a/inet/rexec.c +++ b/inet/rexec.c @@ -87,8 +87,11 @@ rexec_af(ahost, rport, name, pass, cmd, fd2p, af) return (-1); } *ahost = ahostbuf; - } else + } else { *ahost = NULL; + __set_errno (ENOENT); + return -1; + } ruserpass(res0->ai_canonname, &name, &pass); retry: s = __socket(res0->ai_family, res0->ai_socktype, 0); @@ -111,7 +114,8 @@ retry: port = 0; } else { char num[32]; - int s2, sa2len; + int s2; + socklen_t sa2len; s2 = __socket(res0->ai_family, res0->ai_socktype, 0); if (s2 < 0) { @@ -136,7 +140,7 @@ retry: port = atoi(servbuff); (void) sprintf(num, "%u", port); (void) __write(s, num, strlen(num)+1); - { int len = sizeof (from); + { socklen_t len = sizeof (from); s3 = TEMP_FAILURE_RETRY (accept(s2, (struct sockaddr *)&from, &len)); __close(s2); diff --git a/inet/setipv4sourcefilter.c b/inet/setipv4sourcefilter.c new file mode 100644 index 0000000000..db2b8433bb --- /dev/null +++ b/inet/setipv4sourcefilter.c @@ -0,0 +1,33 @@ +/* Set source filter. Stub version. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 <errno.h> +#include <netinet/in.h> + + +int +setipv4sourcefilter (int s, struct in_addr interface, struct in_addr group, + uint32_t fmode, uint32_t numsrc, + const struct in_addr *slist) +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (setipv4sourcefilter) diff --git a/inet/setsourcefilter.c b/inet/setsourcefilter.c new file mode 100644 index 0000000000..870f5e2c38 --- /dev/null +++ b/inet/setsourcefilter.c @@ -0,0 +1,33 @@ +/* Set source filter. Stub version. + Copyright (C) 2004 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. + + 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 <errno.h> +#include <netinet/in.h> + + +int +setsourcefilter (int s, uint32_t interface, const struct sockaddr *group, + socklen_t grouplen, uint32_t fmode, uint32_t numsrc, + const struct sockaddr_storage *slist) +{ + __set_errno (ENOSYS); + return -1; +} +stub_warning (setsourcefilter) diff --git a/inet/test-ifaddrs.c b/inet/test-ifaddrs.c index 7efca25337..0d30d05b64 100644 --- a/inet/test-ifaddrs.c +++ b/inet/test-ifaddrs.c @@ -1,5 +1,5 @@ /* Test listing of network interface addresses. - Copyright (C) 2002, 2004 Free Software Foundation, Inc. + Copyright (C) 2002, 2004, 2005 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 @@ -62,8 +62,8 @@ addr_string (struct sockaddr *sa, char *buf, size_t size) } -int -main (void) +static int +do_test (void) { struct ifaddrs *ifaces, *ifa; @@ -95,3 +95,6 @@ Name Flags Address Netmask Broadcast/Destination"); return failures ? 1 : 0; } + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" diff --git a/inet/test-inet6_opt.c b/inet/test-inet6_opt.c new file mode 100644 index 0000000000..4db9b59389 --- /dev/null +++ b/inet/test-inet6_opt.c @@ -0,0 +1,207 @@ +#include <netinet/in.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define OPT_X 42 +#define OPT_Y 43 +#define OPT_Z 44 + +static void * +encode_inet6_opt (socklen_t *elp) +{ + void *eb = NULL; + socklen_t el; + int cl; + void *db; + int offset; + uint8_t val1; + uint16_t val2; + uint32_t val4; + uint64_t val8; + + *elp = 0; +#define CHECK() \ + if (cl == -1) \ + { \ + printf ("cl == -1 on line %d\n", __LINE__); \ + free (eb); \ + return NULL; \ + } + + /* Estimate the length */ + cl = inet6_opt_init (NULL, 0); + CHECK (); + cl = inet6_opt_append (NULL, 0, cl, OPT_X, 12, 8, NULL); + CHECK (); + cl = inet6_opt_append (NULL, 0, cl, OPT_Y, 7, 4, NULL); + CHECK (); + cl = inet6_opt_append (NULL, 0, cl, OPT_Z, 7, 1, NULL); + CHECK (); + cl = inet6_opt_finish (NULL, 0, cl); + CHECK (); + el = cl; + + eb = malloc (el + 8); + if (eb == NULL) + { + puts ("malloc failed"); + return NULL; + } + /* Canary. */ + memcpy (eb + el, "deadbeef", 8); + + cl = inet6_opt_init (eb, el); + CHECK (); + + cl = inet6_opt_append (eb, el, cl, OPT_X, 12, 8, &db); + CHECK (); + val4 = 0x12345678; + offset = inet6_opt_set_val (db, 0, &val4, sizeof (val4)); + val8 = 0x0102030405060708LL; + inet6_opt_set_val (db, offset, &val8, sizeof (val8)); + + cl = inet6_opt_append (eb, el, cl, OPT_Y, 7, 4, &db); + CHECK (); + val1 = 0x01; + offset = inet6_opt_set_val (db, 0, &val1, sizeof (val1)); + val2 = 0x1331; + offset = inet6_opt_set_val (db, offset, &val2, sizeof (val2)); + val4 = 0x01020304; + inet6_opt_set_val (db, offset, &val4, sizeof (val4)); + + cl = inet6_opt_append (eb, el, cl, OPT_Z, 7, 1, &db); + CHECK (); + inet6_opt_set_val (db, 0, (void *) "abcdefg", 7); + + cl = inet6_opt_finish (eb, el, cl); + CHECK (); + + if (memcmp (eb + el, "deadbeef", 8) != 0) + { + puts ("Canary corrupted"); + free (eb); + return NULL; + } + *elp = el; + return eb; +} + +int +decode_inet6_opt (void *eb, socklen_t el) +{ + int ret = 0; + int seq = 0; + int cl = 0; + int offset; + uint8_t type; + socklen_t len; + uint8_t val1; + uint16_t val2; + uint32_t val4; + uint64_t val8; + void *db; + char buf[8]; + + while ((cl = inet6_opt_next (eb, el, cl, &type, &len, &db)) != -1) + switch (type) + { + case OPT_X: + if (seq++ != 0) + { + puts ("OPT_X is not first"); + ret = 1; + } + if (len != 12) + { + printf ("OPT_X's length %d != 12\n", len); + ret = 1; + } + offset = inet6_opt_get_val (db, 0, &val4, sizeof (val4)); + if (val4 != 0x12345678) + { + printf ("OPT_X's val4 %x != 0x12345678\n", val4); + ret = 1; + } + offset = inet6_opt_get_val (db, offset, &val8, sizeof (val8)); + if (offset != len || val8 != 0x0102030405060708LL) + { + printf ("OPT_X's val8 %llx != 0x0102030405060708\n", + (long long) val8); + ret = 1; + } + break; + case OPT_Y: + if (seq++ != 1) + { + puts ("OPT_Y is not second"); + ret = 1; + } + if (len != 7) + { + printf ("OPT_Y's length %d != 7\n", len); + ret = 1; + } + offset = inet6_opt_get_val (db, 0, &val1, sizeof (val1)); + if (val1 != 0x01) + { + printf ("OPT_Y's val1 %x != 0x01\n", val1); + ret = 1; + } + offset = inet6_opt_get_val (db, offset, &val2, sizeof (val2)); + if (val2 != 0x1331) + { + printf ("OPT_Y's val2 %x != 0x1331\n", val2); + ret = 1; + } + offset = inet6_opt_get_val (db, offset, &val4, sizeof (val4)); + if (offset != len || val4 != 0x01020304) + { + printf ("OPT_Y's val4 %x != 0x01020304\n", val4); + ret = 1; + } + break; + case OPT_Z: + if (seq++ != 2) + { + puts ("OPT_Z is not third"); + ret = 1; + } + if (len != 7) + { + printf ("OPT_Z's length %d != 7\n", len); + ret = 1; + } + offset = inet6_opt_get_val (db, 0, buf, 7); + if (offset != len || memcmp (buf, "abcdefg", 7) != 0) + { + buf[7] = '\0'; + printf ("OPT_Z's buf \"%s\" != \"abcdefg\"\n", buf); + ret = 1; + } + break; + default: + printf ("Unknown option %d\n", type); + ret = 1; + break; + } + if (seq != 3) + { + puts ("Didn't see all of OPT_X, OPT_Y and OPT_Z"); + ret = 1; + } + return ret; +} + +int +main (void) +{ + void *eb; + socklen_t el; + eb = encode_inet6_opt (&el); + if (eb == NULL) + return 1; + if (decode_inet6_opt (eb, el)) + return 1; + return 0; +} diff --git a/inet/test_ifindex.c b/inet/test_ifindex.c index 9e081233be..2920494521 100644 --- a/inet/test_ifindex.c +++ b/inet/test_ifindex.c @@ -1,5 +1,5 @@ /* Test interface name <-> index conversions. - Copyright (C) 1997, 2000 Free Software Foundation, Inc. + Copyright (C) 1997, 2000, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Philip Blundell <Philip.Blundell@pobox.com>. @@ -24,8 +24,8 @@ #include <string.h> #include <net/if.h> -int -main (void) +static int +do_test (void) { int failures = 0; struct if_nameindex *idx = if_nameindex (), *p; @@ -63,3 +63,6 @@ main (void) if_freenameindex (idx); return failures ? 1 : 0; } + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" |