diff options
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 resu |
