diff options
Diffstat (limited to 'inet')
96 files changed, 1845 insertions, 605 deletions
diff --git a/inet/Makefile b/inet/Makefile index 0e7a3c3b45..09f5ba78fc 100644 --- a/inet/Makefile +++ b/inet/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-2016 Free Software Foundation, Inc. +# Copyright (C) 1991-2018 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 @@ -44,48 +44,72 @@ routines := htonl htons \ getaliasent_r getaliasent getaliasname getaliasname_r \ in6_addr getnameinfo if_index ifaddrs inet6_option \ getipv4sourcefilter setipv4sourcefilter \ - getsourcefilter setsourcefilter inet6_opt inet6_rth + getsourcefilter setsourcefilter inet6_opt inet6_rth \ + inet6_scopeid_pton deadline idna idna_name_classify aux := check_pf check_native ifreq tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \ tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \ - tst-getni1 tst-getni2 tst-inet6_rth tst-checks + tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-checks-posix \ + tst-sockaddr test-hnto-types + +# tst-deadline must be linked statically so that we can access +# internal functions. +tests-static += tst-deadline +tests-internal += tst-deadline + +# tst-idna_name_classify must be linked statically because it tests +# internal functionality. +tests-static += tst-idna_name_classify +tests-internal += tst-idna_name_classify + +# tst-inet6_scopeid_pton also needs internal functions but does not +# need to be linked statically. +tests-internal += tst-inet6_scopeid_pton include ../Rules +LOCALES := en_US.UTF-8 en_US.ISO-8859-1 +include ../gen-locales.mk + ifeq ($(have-thread-library),yes) -CFLAGS-gethstbyad_r.c = -fexceptions -CFLAGS-gethstbyad.c = -fexceptions -CFLAGS-gethstbynm_r.c = -fexceptions -CFLAGS-gethstbynm.c = -fexceptions -CFLAGS-gethstbynm2_r.c = -fexceptions -CFLAGS-gethstbynm2.c = -fexceptions -CFLAGS-gethstent_r.c = -fexceptions -CFLAGS-gethstent.c = -fexceptions -CFLAGS-rcmd.c = -fexceptions -CFLAGS-getnetbynm_r.c = -fexceptions -CFLAGS-getnetbynm.c = -fexceptions -CFLAGS-getnetbyad_r.c = -fexceptions -CFLAGS-getnetbyad.c = -fexceptions -CFLAGS-getnetent_r.c = -fexceptions -CFLAGS-getnetent.c = -fexceptions -CFLAGS-getaliasent_r.c = -fexceptions -CFLAGS-getaliasent.c = -fexceptions -CFLAGS-getrpcent_r.c = -fexceptions -CFLAGS-getrpcent.c = -fexceptions -CFLAGS-getservent_r.c = -fexceptions -CFLAGS-getservent.c = -fexceptions -CFLAGS-getprtent_r.c = -fexceptions -CFLAGS-getprtent.c = -fexceptions -CFLAGS-either_ntoh.c = -fexceptions -CFLAGS-either_hton.c = -fexceptions -CFLAGS-getnetgrent.c = -fexceptions -CFLAGS-getnetgrent_r.c = -fexceptions +CFLAGS-gethstbyad_r.c += -fexceptions +CFLAGS-gethstbyad.c += -fexceptions +CFLAGS-gethstbynm_r.c += -fexceptions +CFLAGS-gethstbynm.c += -fexceptions +CFLAGS-gethstbynm2_r.c += -fexceptions +CFLAGS-gethstbynm2.c += -fexceptions +CFLAGS-gethstent_r.c += -fexceptions +CFLAGS-gethstent.c += -fexceptions +CFLAGS-rcmd.c += -fexceptions +CFLAGS-getnetbynm_r.c += -fexceptions +CFLAGS-getnetbynm.c += -fexceptions +CFLAGS-getnetbyad_r.c += -fexceptions +CFLAGS-getnetbyad.c += -fexceptions +CFLAGS-getnetent_r.c += -fexceptions +CFLAGS-getnetent.c += -fexceptions +CFLAGS-getaliasent_r.c += -fexceptions +CFLAGS-getaliasent.c += -fexceptions +CFLAGS-getrpcent_r.c += -fexceptions +CFLAGS-getrpcent.c += -fexceptions +CFLAGS-getservent_r.c += -fexceptions +CFLAGS-getservent.c += -fexceptions +CFLAGS-getprtent_r.c += -fexceptions +CFLAGS-getprtent.c += -fexceptions +CFLAGS-either_ntoh.c += -fexceptions +CFLAGS-either_hton.c += -fexceptions +CFLAGS-getnetgrent.c += -fexceptions +CFLAGS-getnetgrent_r.c += -fexceptions + +CFLAGS-tst-checks-posix.c += -std=c99 +CFLAGS-tst-sockaddr.c += -fno-strict-aliasing endif ifeq ($(build-static-nss),yes) CFLAGS += -DSTATIC_NSS endif + +$(objpfx)tst-idna_name_classify.out: $(gen-locales) diff --git a/inet/Versions b/inet/Versions index 56eb274634..9b3661e046 100644 --- a/inet/Versions +++ b/inet/Versions @@ -85,5 +85,10 @@ libc { # functions used in other libraries __internal_endnetgrent; __internal_getnetgrent_r; __internal_setnetgrent; + + # Used from nscd. + __inet6_scopeid_pton; + __idna_to_dns_encoding; + __idna_from_dns_encoding; } } diff --git a/inet/aliases.h b/inet/aliases.h index 44760d3040..ec44284f60 100644 --- a/inet/aliases.h +++ b/inet/aliases.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/arpa/inet.h b/inet/arpa/inet.h index 94d333038b..731f1c5d29 100644 --- a/inet/arpa/inet.h +++ b/inet/arpa/inet.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997-2016 Free Software Foundation, Inc. +/* Copyright (C) 1997-2018 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 diff --git a/inet/bug-if1.c b/inet/bug-if1.c index cbe9638a53..5a98e99cef 100644 --- a/inet/bug-if1.c +++ b/inet/bug-if1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004-2016 Free Software Foundation, Inc. +/* Copyright (C) 2004-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. diff --git a/inet/check_native.c b/inet/check_native.c index f59458dd95..372f25882a 100644 --- a/inet/check_native.c +++ b/inet/check_native.c @@ -1,5 +1,5 @@ /* Determine whether interfaces use native transport. Generic version. - Copyright (C) 2012-2016 Free Software Foundation, Inc. + Copyright (C) 2012-2018 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 diff --git a/inet/check_pf.c b/inet/check_pf.c index e7e7f9f949..4dc3125296 100644 --- a/inet/check_pf.c +++ b/inet/check_pf.c @@ -1,5 +1,5 @@ /* Determine protocol families for which interfaces exist. Generic version. - Copyright (C) 2003-2016 Free Software Foundation, Inc. + Copyright (C) 2003-2018 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 @@ -32,7 +32,7 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6, /* Get the interface list via getifaddrs. */ struct ifaddrs *ifa = NULL; - if (getifaddrs (&ifa) != 0) + if (__getifaddrs (&ifa) != 0) { /* We cannot determine what interfaces are available. Be pessimistic. */ @@ -51,7 +51,7 @@ __check_pf (bool *seen_ipv4, bool *seen_ipv6, else if (runp->ifa_addr->sa_family == PF_INET6) *seen_ipv6 = true; - (void) freeifaddrs (ifa); + (void) __freeifaddrs (ifa); } diff --git a/inet/deadline.c b/inet/deadline.c new file mode 100644 index 0000000000..c54005c3c1 --- /dev/null +++ b/inet/deadline.c @@ -0,0 +1,122 @@ +/* Computing deadlines for timeouts. + Copyright (C) 2017-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <net-internal.h> + +#include <assert.h> +#include <limits.h> +#include <stdio.h> +#include <stdint.h> +#include <time.h> + +struct deadline_current_time +__deadline_current_time (void) +{ + struct deadline_current_time result; + if (__clock_gettime (CLOCK_MONOTONIC, &result.current) != 0) + { + struct timeval current_tv; + if (__gettimeofday (¤t_tv, NULL) == 0) + __libc_fatal ("Fatal error: gettimeofday system call failed\n"); + result.current.tv_sec = current_tv.tv_sec; + result.current.tv_nsec = current_tv.tv_usec * 1000; + } + assert (result.current.tv_sec >= 0); + return result; +} + +/* A special deadline value for which __deadline_is_infinite is + true. */ +static inline struct deadline +infinite_deadline (void) +{ + return (struct deadline) { { -1, -1 } }; +} + +struct deadline +__deadline_from_timeval (struct deadline_current_time current, + struct timeval tv) +{ + assert (__is_timeval_valid_timeout (tv)); + + /* Compute second-based deadline. Perform the addition in + uintmax_t, which is unsigned, to simply overflow detection. */ + uintmax_t sec = current.current.tv_sec; + sec += tv.tv_sec; + if (sec < (uintmax_t) tv.tv_sec) + return infinite_deadline (); + + /* Compute nanosecond deadline. */ + int nsec = current.current.tv_nsec + tv.tv_usec * 1000; + if (nsec >= 1000 * 1000 * 1000) + { + /* Carry nanosecond overflow to seconds. */ + nsec -= 1000 * 1000 * 1000; + if (sec + 1 < sec) + return infinite_deadline (); + ++sec; + } + /* This uses a GCC extension, otherwise these casts for detecting + overflow would not be defined. */ + if ((time_t) sec < 0 || sec != (uintmax_t) (time_t) sec) + return infinite_deadline (); + + return (struct deadline) { { sec, nsec } }; +} + +int +__deadline_to_ms (struct deadline_current_time current, + struct deadline deadline) +{ + if (__deadline_is_infinite (deadline)) + return INT_MAX; + + if (current.current.tv_sec > deadline.absolute.tv_sec + || (current.current.tv_sec == deadline.absolute.tv_sec + && current.current.tv_nsec >= deadline.absolute.tv_nsec)) + return 0; + time_t sec = deadline.absolute.tv_sec - current.current.tv_sec; + if (sec >= INT_MAX) + /* This value will overflow below. */ + return INT_MAX; + int nsec = deadline.absolute.tv_nsec - current.current.tv_nsec; + if (nsec < 0) + { + /* Borrow from the seconds field. */ + assert (sec > 0); + --sec; + nsec += 1000 * 1000 * 1000; + } + + /* Prepare for rounding up to milliseconds. */ + nsec += 999999; + if (nsec > 1000 * 1000 * 1000) + { + assert (sec < INT_MAX); + ++sec; + nsec -= 1000 * 1000 * 1000; + } + + unsigned int msec = nsec / (1000 * 1000); + if (sec > INT_MAX / 1000) + return INT_MAX; + msec += sec * 1000; + if (msec > INT_MAX) + return INT_MAX; + return msec; +} diff --git a/inet/ether_aton.c b/inet/ether_aton.c index 9c2c26e618..5c8df40c8d 100644 --- a/inet/ether_aton.c +++ b/inet/ether_aton.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/ether_aton_r.c b/inet/ether_aton_r.c index 07b82c123c..185d606d68 100644 --- a/inet/ether_aton_r.c +++ b/inet/ether_aton_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/ether_hton.c b/inet/ether_hton.c index 225604e334..37de9b8c4e 100644 --- a/inet/ether_hton.c +++ b/inet/ether_hton.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -27,11 +27,6 @@ typedef int (*lookup_function) (const char *, struct etherent *, char *, int, int *); -/* The lookup function for the first entry of this service. */ -extern int __nss_ethers_lookup (service_user **nip, const char *name, - void **fctp) internal_function; - - int ether_hostton (const char *hostname, struct ether_addr *addr) { @@ -49,7 +44,7 @@ ether_hostton (const char *hostname, struct ether_addr *addr) if (startp == NULL) { - no_more = __nss_ethers_lookup (&nip, "gethostton_r", &fct.ptr); + no_more = __nss_ethers_lookup2 (&nip, "gethostton_r", NULL, &fct.ptr); if (no_more) startp = (service_user *) -1; else diff --git a/inet/ether_line.c b/inet/ether_line.c index fc7107262a..4304f5a465 100644 --- a/inet/ether_line.c +++ b/inet/ether_line.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/ether_ntoa.c b/inet/ether_ntoa.c index 2dab761fdc..6dd5c3b5cb 100644 --- a/inet/ether_ntoa.c +++ b/inet/ether_ntoa.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/ether_ntoa_r.c b/inet/ether_ntoa_r.c index e2b956af4e..22fd7480bf 100644 --- a/inet/ether_ntoa_r.c +++ b/inet/ether_ntoa_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/ether_ntoh.c b/inet/ether_ntoh.c index 8063a44bce..56366b961a 100644 --- a/inet/ether_ntoh.c +++ b/inet/ether_ntoh.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -28,11 +28,6 @@ typedef int (*lookup_function) (const struct ether_addr *, struct etherent *, char *, size_t, int *); -/* The lookup function for the first entry of this service. */ -extern int __nss_ethers_lookup (service_user **nip, const char *name, - void **fctp) internal_function; - - int ether_ntohost (char *hostname, const struct ether_addr *addr) { @@ -50,7 +45,7 @@ ether_ntohost (char *hostname, const struct ether_addr *addr) if (startp == NULL) { - no_more = __nss_ethers_lookup (&nip, "getntohost_r", &fct.ptr); + no_more = __nss_ethers_lookup2 (&nip, "getntohost_r", NULL, &fct.ptr); if (no_more) startp = (service_user *) -1; else diff --git a/inet/getaliasent.c b/inet/getaliasent.c index 0df80ecb14..46dff533e5 100644 --- a/inet/getaliasent.c +++ b/inet/getaliasent.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/getaliasent_r.c b/inet/getaliasent_r.c index d6c32e9f02..df027973bf 100644 --- a/inet/getaliasent_r.c +++ b/inet/getaliasent_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getaliasname.c b/inet/getaliasname.c index 1a011265b6..60f29a8b2f 100644 --- a/inet/getaliasname.c +++ b/inet/getaliasname.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getaliasname_r.c b/inet/getaliasname_r.c index 2133947ab1..926a4433bf 100644 --- a/inet/getaliasname_r.c +++ b/inet/getaliasname_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/gethstbyad.c b/inet/gethstbyad.c index 31e91d0d1a..d8557d9da9 100644 --- a/inet/gethstbyad.c +++ b/inet/gethstbyad.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/gethstbyad_r.c b/inet/gethstbyad_r.c index 3683ce3e2e..e12f573678 100644 --- a/inet/gethstbyad_r.c +++ b/inet/gethstbyad_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -18,7 +18,7 @@ #include <netdb.h> #include <string.h> - +#include <resolv/res_hconf.h> #define LOOKUP_TYPE struct hostent #define FUNCTION_NAME gethostbyaddr @@ -27,7 +27,6 @@ #define ADD_VARIABLES addr, len, type #define NEED_H_ERRNO 1 #define NEED__RES 1 -#define NEED__RES_HCONF 1 /* If the addr parameter is the IPv6 unspecified address no query must be performed. */ #define PREPROCESS \ diff --git a/inet/gethstbynm.c b/inet/gethstbynm.c index 7597cc3783..a7a64d306d 100644 --- a/inet/gethstbynm.c +++ b/inet/gethstbynm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/gethstbynm2.c b/inet/gethstbynm2.c index 798455f7d2..7a452d2af8 100644 --- a/inet/gethstbynm2.c +++ b/inet/gethstbynm2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/gethstbynm2_r.c b/inet/gethstbynm2_r.c index c06c7aa5a3..9638e167a5 100644 --- a/inet/gethstbynm2_r.c +++ b/inet/gethstbynm2_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -22,7 +22,7 @@ #include <string.h> #include <arpa/inet.h> #include <netinet/in.h> - +#include <resolv/res_hconf.h> #define LOOKUP_TYPE struct hostent #define FUNCTION_NAME gethostbyname2 @@ -30,7 +30,7 @@ #define ADD_PARAMS const char *name, int af #define ADD_VARIABLES name, af #define NEED_H_ERRNO 1 -#define NEED__RES_HCONF 1 +#define NEED__RES 1 #define POSTPROCESS \ if (status == NSS_STATUS_SUCCESS) \ _res_hconf_reorder_addrs (resbuf); diff --git a/inet/gethstbynm_r.c b/inet/gethstbynm_r.c index 3cfe50b965..b12fb3307f 100644 --- a/inet/gethstbynm_r.c +++ b/inet/gethstbynm_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. @@ -22,7 +22,7 @@ #include <string.h> #include <arpa/inet.h> #include <netinet/in.h> - +#include <resolv/res_hconf.h> #define LOOKUP_TYPE struct hostent #define FUNCTION_NAME gethostbyname @@ -30,7 +30,7 @@ #define ADD_PARAMS const char *name #define ADD_VARIABLES name #define NEED_H_ERRNO 1 -#define NEED__RES_HCONF 1 +#define NEED__RES 1 #define POSTPROCESS \ if (status == NSS_STATUS_SUCCESS) \ _res_hconf_reorder_addrs (resbuf); diff --git a/inet/gethstent.c b/inet/gethstent.c index c1523cfe50..627f19dac4 100644 --- a/inet/gethstent.c +++ b/inet/gethstent.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/gethstent_r.c b/inet/gethstent_r.c index 140e8487cf..12dfab2dad 100644 --- a/inet/gethstent_r.c +++ b/inet/gethstent_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/getipv4sourcefilter.c b/inet/getipv4sourcefilter.c index f387fd1750..2e46661cde 100644 --- a/inet/getipv4sourcefilter.c +++ b/inet/getipv4sourcefilter.c @@ -1,5 +1,5 @@ /* Get source filter. Stub version. - Copyright (C) 2004-2016 Free Software Foundation, Inc. + Copyright (C) 2004-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. diff --git a/inet/getnameinfo.c b/inet/getnameinfo.c index 40f67f082f..5d4978e383 100644 --- a/inet/getnameinfo.c +++ b/inet/getnameinfo.c @@ -1,3 +1,21 @@ +/* Convert socket address to string using Name Service Switch modules. + Copyright (C) 1997-2018 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, see + <http://www.gnu.org/licenses/>. */ + /* The Inner Net License, Version 2.00 The author(s) grant permission for redistribution and use in source and @@ -53,12 +71,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <sys/utsname.h> #include <libc-lock.h> #include <scratch_buffer.h> - -#ifdef HAVE_LIBIDN -# include <libidn/idna.h> -extern int __idna_to_unicode_lzlz (const char *input, char **output, - int flags); -#endif +#include <net-internal.h> #ifndef min # define min(x,y) (((x) > (y)) ? (y) : (x)) @@ -66,9 +79,11 @@ extern int __idna_to_unicode_lzlz (const char *input, char **output, libc_freeres_ptr (static char *domain); +/* Former NI_IDN_ALLOW_UNASSIGNED, NI_IDN_USE_STD3_ASCII_RULES flags, + now ignored. */ +#define DEPRECATED_NI_IDN 192 static char * -internal_function nrl_domainname (void) { static int not_first; @@ -169,25 +184,311 @@ nrl_domainname (void) return domain; }; +/* Copy a string to a destination buffer with length checking. Return + EAI_OVERFLOW if the buffer is not large enough, and 0 on + success. */ +static int +checked_copy (char *dest, size_t destlen, const char *source) +{ + size_t source_length = strlen (source); + if (source_length + 1 > destlen) + return EAI_OVERFLOW; + memcpy (dest, source, source_length + 1); + return 0; +} -int -getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, - socklen_t hostlen, char *serv, socklen_t servlen, - int flags) +/* Helper function for CHECKED_SNPRINTF below. */ +static int +check_sprintf_result (int result, size_t destlen) +{ + if (result < 0) + return EAI_SYSTEM; + if ((size_t) result >= destlen) + /* If ret == destlen, there was no room for the terminating NUL + character. */ + return EAI_OVERFLOW; + return 0; +} + +/* Format a string in the destination buffer. Return 0 on success, + EAI_OVERFLOW in case the buffer is too small, or EAI_SYSTEM on any + other error. */ +#define CHECKED_SNPRINTF(dest, destlen, format, ...) \ + check_sprintf_result \ + (__snprintf (dest, destlen, format, __VA_ARGS__), destlen) + +/* Convert host name, AF_INET/AF_INET6 case, name only. */ +static int +gni_host_inet_name (struct scratch_buffer *tmpbuf, + const struct sockaddr *sa, socklen_t addrlen, + char *host, socklen_t hostlen, int flags) { - int serrno = errno; int herrno; struct hostent th; - int ok = 0; - struct scratch_buffer tmpbuf; + struct hostent *h = NULL; + if (sa->sa_family == AF_INET6) + { + const struct sockaddr_in6 *sin6p = (const struct sockaddr_in6 *) sa; + while (__gethostbyaddr_r (&sin6p->sin6_addr, sizeof(struct in6_addr), + AF_INET6, &th, tmpbuf->data, tmpbuf->length, + &h, &herrno)) + if (herrno == NETDB_INTERNAL && errno == ERANGE) + { + if (!scratch_buffer_grow (tmpbuf)) + { + __set_h_errno (herrno); + return EAI_MEMORY; + } + } + else + break; + } + else + { + const struct sockaddr_in *sinp = (const struct sockaddr_in *) sa; + while (__gethostbyaddr_r (&sinp->sin_addr, sizeof(struct in_addr), + AF_INET, &th, tmpbuf->data, tmpbuf->length, + &h, &herrno)) + if (herrno == NETDB_INTERNAL && errno == ERANGE) + { + if (!scratch_buffer_grow (tmpbuf)) + { + __set_h_errno (herrno); + return EAI_MEMORY; + } + } + else + break; + } - scratch_buffer_init (&tmpbuf); + if (h == NULL) + { + if (herrno == NETDB_INTERNAL) + { + __set_h_errno (herrno); + return EAI_SYSTEM; + } + if (herrno == TRY_AGAIN) + { + __set_h_errno (herrno); + return EAI_AGAIN; + } + } + + if (h) + { + char *c; + if ((flags & NI_NOFQDN) + && (c = nrl_domainname ()) + && (c = strstr (h->h_name, c)) + && (c != h->h_name) && (*(--c) == '.')) + /* Terminate the string after the prefix. */ + *c = '\0'; + + /* If requested, convert from the IDN format. */ + bool do_idn = flags & NI_IDN; + char *h_name; + if (do_idn) + { + int rc = __idna_from_dns_encoding (h->h_name, &h_name); + if (rc == EAI_IDN_ENCODE) + /* Use the punycode name as a fallback. */ + do_idn = false; + else if (rc != 0) + return rc; + } + if (!do_idn) + h_name = h->h_name; + + size_t len = strlen (h_name) + 1; + if (len > hostlen) + return EAI_OVERFLOW; + memcpy (host, h_name, len); + + if (do_idn) + free (h_name); + + return 0; + } + + return EAI_NONAME; +} + +/* Convert host name, AF_INET/AF_INET6 case, numeric conversion. */ +static int +gni_host_inet_numeric (struct scratch_buffer *tmpbuf, + const struct sockaddr *sa, socklen_t addrlen, + char *host, socklen_t hostlen, int flags) +{ + if (sa->sa_family == AF_INET6) + { + const struct sockaddr_in6 *sin6p = (const struct sockaddr_in6 *) sa; + if (inet_ntop (AF_INET6, &sin6p->sin6_addr, host, hostlen) == NULL) + return EAI_OVERFLOW; + + uint32_t scopeid = sin6p->sin6_scope_id; + if (scopeid != 0) + { + size_t used_hostlen = __strnlen (host, hostlen); + /* Location of the scope string in the host buffer. */ + char *scope_start = host + used_hostlen; + size_t scope_length = hostlen - used_hostlen; + + if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr) + || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) + { + char scopebuf[IFNAMSIZ]; + if (if_indextoname (scopeid, scopebuf) != NULL) + return CHECKED_SNPRINTF + (scope_start, scope_length, + "%c%s", SCOPE_DELIMITER, scopebuf); + } + return CHECKED_SNPRINTF + (scope_start, scope_length, "%c%u", SCOPE_DELIMITER, scopeid); + } + } + else + { + const struct sockaddr_in *sinp = (const struct sockaddr_in *) sa; + if (inet_ntop (AF_INET, &sinp->sin_addr, host, hostlen) == NULL) + return EAI_OVERFLOW; + } + return 0; +} + +/* Convert AF_INET or AF_INET6 socket address, host part. */ +static int +gni_host_inet (struct scratch_buffer *tmpbuf, + const struct sockaddr *sa, socklen_t addrlen, + char *host, socklen_t hostlen, int flags) +{ + if (!(flags & NI_NUMERICHOST)) + { + int result = gni_host_inet_name + (tmpbuf, sa, addrlen, host, hostlen, flags); + if (result != EAI_NONAME) + return result; + } + + if (flags & NI_NAMEREQD) + return EAI_NONAME; + else + return gni_host_inet_numeric + (tmpbuf, sa, addrlen, host, hostlen, flags); +} + +/* Convert AF_LOCAL socket address, host part. */ +static int +gni_host_local (struct scratch_buffer *tmpbuf, + const struct sockaddr *sa, socklen_t addrlen, + char *host, socklen_t hostlen, int flags) +{ + if (!(flags & NI_NUMERICHOST)) + { + struct utsname utsname; + if (uname (&utsname) == 0) + return checked_copy (host, hostlen, utsname.nodename); + } + + if (flags & NI_NAMEREQD) + return EAI_NONAME; + + return checked_copy (host, hostlen, "localhost"); +} + +/* Convert the host part of an AF_LOCAK socket address. */ +static int +gni_host (struct scratch_buffer *tmpbuf, + const struct sockaddr *sa, socklen_t addrlen, + char *host, socklen_t hostlen, int flags) +{ + switch (sa->sa_family) + { + case AF_INET: + case AF_INET6: + return gni_host_inet (tmpbuf, sa, addrlen, host, hostlen, flags); + + case AF_LOCAL: + return gni_host_local (tmpbuf, sa, addrlen, host, hostlen, flags); + + default: + return EAI_FAMILY; + } +} + +/* Convert service to string, AF_INET and AF_INET6 variant. */ +static int +gni_serv_inet (struct scratch_buffer *tmpbuf, + const struct sockaddr *sa, socklen_t addrlen, + char *serv, socklen_t servlen, int flags) +{ + _Static_assert + (offsetof (struct sockaddr_in, sin_port) + == offsetof (struct sockaddr_in6, sin6_port) + && sizeof (((struct sockaddr_in) {}).sin_port) == sizeof (in_port_t) + && sizeof (((struct sockaddr_in6) {}).sin6_port) == sizeof (in_port_t), + "AF_INET and AF_INET6 port consistency"); + const struct sockaddr_in *sinp = (const struct sockaddr_in *) sa; + if (!(flags & NI_NUMERICSERV)) + { + struct servent *s, ts; + int e; + while ((e = __getservbyport_r (sinp->sin_port, + ((flags & NI_DGRAM) + ? "udp" : "tcp"), &ts, + tmpbuf->data, tmpbuf->length, &s))) + { + if (e == ERANGE) + { + if (!scratch_buffer_grow (tmpbuf)) + return EAI_MEMORY; + } + else + break; + } + if (s) + return checked_copy (serv, servlen, s->s_name); + /* Fall through to numeric conversion. */ + } + return CHECKED_SNPRINTF (serv, servlen, "%d", ntohs (sinp->sin_port)); +} + +/* Convert service to string, AF_LOCAL variant. */ +static int +gni_serv_local (struct scratch_buffer *tmpbuf, + const struct sockaddr *sa, socklen_t addrlen, + char *serv, socklen_t servlen, int flags) +{ + return checked_copy + (serv, servlen, ((const struct sockaddr_un *) sa)->sun_path); +} + +/* Convert service to string, dispatching to the implementations + above. */ +static int +gni_serv (struct scratch_buffer *tmpbuf, + const struct sockaddr *sa, socklen_t addrlen, + char *serv, socklen_t servlen, int flags) +{ + switch (sa->sa_family) + { + case AF_INET: + case AF_INET6: + return gni_serv_inet (tmpbuf, sa, addrlen, serv, servlen, flags); + case AF_LOCAL: + return gni_serv_local (tmpbuf, sa, addrlen, serv, servlen, flags); + default: + return EAI_FAMILY; + } +} +int +getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, + socklen_t hostlen, char *serv, socklen_t servlen, + int flags) +{ if (flags & ~(NI_NUMERICHOST|NI_NUMERICSERV|NI_NOFQDN|NI_NAMEREQD|NI_DGRAM -#ifdef HAVE_LIBIDN - |NI_IDN|NI_IDN_ALLOW_UNASSIGNED|NI_IDN_USE_STD3_ASCII_RULES -#endif - )) + |NI_IDN|DEPRECATED_NI_IDN)) return EAI_BADFLAGS; if (sa == NULL || addrlen < sizeof (sa_family_t)) @@ -214,256 +515,30 @@ getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, return EAI_FAMILY; } - if (host != NULL && hostlen > 0) - switch (sa->sa_family) - { - case AF_INET: - case AF_INET6: - 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.data, tmpbuf.length, - &h, &herrno)) - if (herrno == NETDB_INTERNAL && errno == ERANGE) - { - if (!scratch_buffer_grow (&tmpbuf)) - { - __set_h_errno (herrno); - return EAI_MEMORY; - } - } - else - break; - } - else - { - while (__gethostbyaddr_r ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr), - sizeof(struct in_addr), - AF_INET, &th, - tmpbuf.data, tmpbuf.length, - &h, &herrno)) - if (herrno == NETDB_INTERNAL && errno == ERANGE) - { - if (!scratch_buffer_grow (&tmpbuf)) - { - __set_h_errno (herrno); - return EAI_MEMORY; - } - } - else - break; - } - - if (h == NULL) - { - if (herrno == NETDB_INTERNAL) - { - __set_h_errno (herrno); - return EAI_SYSTEM; - } - if (herrno == TRY_AGAIN) - { - __set_h_errno (herrno); - return EAI_AGAIN; - } - } - - if (h) - { - char *c; - if ((flags & NI_NOFQDN) - && (c = nrl_domainname ()) - && (c = strstr (h->h_name, c)) - && (c != h->h_name) && (*(--c) == '.')) - /* Terminate the string after the prefix. */ - *c = '\0'; - -#ifdef HAVE_LIBIDN - /* If requested, convert from the IDN format. */ - if (flags & NI_IDN) - { - int idn_flags = 0; - if (flags & NI_IDN_ALLOW_UNASSIGNED) - idn_flags |= IDNA_ALLOW_UNASSIGNED; - if (flags & NI_IDN_USE_STD3_ASCII_RULES) - idn_flags |= IDNA_USE_STD3_ASCII_RULES; - - char *out; - int rc = __idna_to_unicode_lzlz (h->h_name, &out, - idn_flags); - if (rc != IDNA_SUCCESS) - { - if (rc == IDNA_MALLOC_ERROR) - return EAI_MEMORY; - if (rc == IDNA_DLOPEN_ERROR) - return EAI_SYSTEM; - return EAI_IDN_ENCODE; - } - - if (out != h->h_name) - { - h->h_name = strdupa (out); - free (out); - } - } -#endif - - size_t len = strlen (h->h_name) + 1; - if (len > hostlen) - return EAI_OVERFLOW; - - memcpy (host, h->h_name, len); - - ok = 1; - } - } - - if (!ok) - { - if (flags & NI_NAMEREQD) - { - __set_errno (serrno); - return EAI_NONAME; - } - else - { - const char *c; - if (sa->sa_family == AF_INET6) - { - const struct sockaddr_in6 *sin6p; - uint32_t scopeid; - - sin6p = (const struct sockaddr_in6 *) sa; - - c = inet_ntop (AF_INET6, - (const void *) &sin6p->sin6_addr, host, hostlen); - scopeid = sin6p->sin6_scope_id; - if (scopeid != 0) - { - /* Buffer is >= IFNAMSIZ+1. */ - char scopebuf[IFNAMSIZ + 1]; - char *scopeptr; - int ni_numericscope = 0; - size_t real_hostlen = __strnlen (host, hostlen); - size_t scopelen = 0; - - scopebuf[0] = SCOPE_DELIMITER; - scopebuf[1] = '\0'; - scopeptr = &scopebuf[1]; - - if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr) - || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) - { - if (if_indextoname (scopeid, scopeptr) == NULL) - ++ni_numericscope; - else - scopelen = strlen (scopebuf); - } - else - ++ni_numericscope; - - if (ni_numericscope) - scopelen = 1 + __snprintf (scopeptr, - (scopebuf - + sizeof scopebuf - - scopeptr), - "%u", scopeid); - - if (real_hostlen + scopelen + 1 > hostlen) - /* Signal the buffer is too small. This is - what inet_ntop does. */ - c = NULL; - else - memcpy (host + real_hostlen, scopebuf, scopelen + 1); - } - } - else - c = inet_ntop (AF_INET, - (const void *) &(((const struct sockaddr_in *) sa)->sin_addr), - host, hostlen); - if (c == NULL) - return EAI_OVERFLOW; - } - ok = 1; - } - break; - - case AF_LOCAL: - if (!(flags & NI_NUMERICHOST)) - { - struct utsname utsname; - - if (!uname (&utsname)) - { - strncpy (host, utsname.nodename, hostlen); - break; - }; - }; - - if (flags & NI_NAMEREQD) - { - __set_errno (serrno); - return EAI_NONAME; - } - - strncpy (host, "localhost", hostlen); - break; + struct scratch_buffer tmpbuf; + scratch_buffer_init (&tmpbuf); - default: - return EAI_FAMILY; + if (host != NULL && hostlen > 0) + { + int result = gni_host (&tmpbuf, sa, addrlen, host, hostlen, flags); + if (result != 0) + { + scratch_buffer_free (&tmpbuf); + return result; + } } if (serv && (servlen > 0)) - switch (sa->sa_family) - { - case AF_INET: - case AF_INET6: - if (!(flags & NI_NUMERICSERV)) - { - struct servent *s, ts; - int e; - while ((e = __getservbyport_r (((const struct sockaddr_in *) sa)->sin_port, - ((flags & NI_DGRAM) - ? "udp" : "tcp"), &ts, - tmpbuf.data, tmpbuf.length, &s))) - { - if (e == ERANGE) - { - if (!scratch_buffer_grow (&tmpbuf)) - return EAI_MEMORY; - } - else - break; - } - if (s) - { - strncpy (serv, s->s_name, servlen); - break; - } - } - - if (__snprintf (serv, servlen, "%d", - ntohs (((const struct sockaddr_in *) sa)->sin_port)) - + 1 > servlen) - return EAI_OVERFLOW; - - break; - - case AF_LOCAL: - strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen); - break; + { + int result = gni_serv (&tmpbuf, sa, addrlen, serv, servlen, flags); + if (result != 0) + { + scratch_buffer_free (&tmpbuf); + return result; + } } - if (host && (hostlen > 0)) - host[hostlen-1] = 0; - if (serv && (servlen > 0)) - serv[servlen-1] = 0; - errno = serrno; + scratch_buffer_free (&tmpbuf); return 0; } libc_hidden_def (getnameinfo) diff --git a/inet/getnetbyad.c b/inet/getnetbyad.c index 827ff9a003..981361b199 100644 --- a/inet/getnetbyad.c +++ b/inet/getnetbyad.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getnetbyad_r.c b/inet/getnetbyad_r.c index 155a3c3931..53f1cb90c2 100644 --- a/inet/getnetbyad_r.c +++ b/inet/getnetbyad_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getnetbynm.c b/inet/getnetbynm.c index 5cf806ba90..4a2ac86e33 100644 --- a/inet/getnetbynm.c +++ b/inet/getnetbynm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getnetbynm_r.c b/inet/getnetbynm_r.c index a74599ffa7..99d07e1dd9 100644 --- a/inet/getnetbynm_r.c +++ b/inet/getnetbynm_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getnetent.c b/inet/getnetent.c index 273e35f795..9c0fce1e09 100644 --- a/inet/getnetent.c +++ b/inet/getnetent.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/getnetent_r.c b/inet/getnetent_r.c index 0f009c9440..807953f1a4 100644 --- a/inet/getnetent_r.c +++ b/inet/getnetent_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/getnetgrent.c b/inet/getnetgrent.c index 3443235cca..ee52924a45 100644 --- a/inet/getnetgrent.c +++ b/inet/getnetgrent.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/getnetgrent_r.c b/inet/getnetgrent_r.c index 1af97c0380..dc0aa4f627 100644 --- a/inet/getnetgrent_r.c +++ b/inet/getnetgrent_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 @@ -36,10 +36,6 @@ __libc_lock_define_initialized (static, lock) kept in this structure. */ static struct __netgrent dataset; -/* The lookup function for the first entry of this service. */ -extern int __nss_netgroup_lookup (service_user **nipp, const char *name, - void **fctp) internal_function; - /* Set up NIP to run through the services. Return nonzero if there are no services (left). */ static int @@ -54,7 +50,7 @@ setup (void **fctp, 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, "setnetgrent", fctp); + no_more = __nss_netgroup_lookup2 (nipp, "setnetgrent", NULL, fctp); startp = no_more ? (service_user *) -1 : *nipp; #ifdef PTR_MANGLE PTR_MANGLE (startp); @@ -114,7 +110,6 @@ endnetgrent_hook (struct __netgrent *datap) } static int -internal_function __internal_setnetgrent_reuse (const char *group, struct __netgrent *datap, int *errnop) { @@ -172,7 +167,6 @@ __internal_setnetgrent_reuse (const char *group, struct __netgrent *datap, } int -internal_function __internal_setnetgrent (const char *group, struct __netgrent *datap) { /* Free list of all netgroup names from last run. */ @@ -214,7 +208,6 @@ setnetgrent (const char *group) } void -internal_function __internal_endnetgrent (struct __netgrent *datap) { endnetgrent_hook (datap); @@ -263,7 +256,6 @@ nscd_getnetgrent (struct __netgrent *datap, char *buffer, size_t buflen, #endif int -internal_function __internal_getnetgrent_r (char **hostp, char **userp, char **domainp, struct __netgrent *datap, char *buffer, size_t buflen, int *errnop) diff --git a/inet/getproto.c b/inet/getproto.c index bf9d7e0776..a89bcb6955 100644 --- a/inet/getproto.c +++ b/inet/getproto.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getproto_r.c b/inet/getproto_r.c index df5ccda7c0..69cb311473 100644 --- a/inet/getproto_r.c +++ b/inet/getproto_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getprtent.c b/inet/getprtent.c index 714bbf3f75..8cc19e90db 100644 --- a/inet/getprtent.c +++ b/inet/getprtent.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/getprtent_r.c b/inet/getprtent_r.c index 2fb4158702..38c2e5bdda 100644 --- a/inet/getprtent_r.c +++ b/inet/getprtent_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/getprtname.c b/inet/getprtname.c index b3b0067f0e..89e4db4fc7 100644 --- a/inet/getprtname.c +++ b/inet/getprtname.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getprtname_r.c b/inet/getprtname_r.c index fbc747694a..1bd9d6ee3a 100644 --- a/inet/getprtname_r.c +++ b/inet/getprtname_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getservent.c b/inet/getservent.c index b478e9f391..71857c2617 100644 --- a/inet/getservent.c +++ b/inet/getservent.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/getservent_r.c b/inet/getservent_r.c index 52dcc7998c..b22caf8030 100644 --- a/inet/getservent_r.c +++ b/inet/getservent_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/getsourcefilter.c b/inet/getsourcefilter.c index 3e69a04c8e..405f13a610 100644 --- a/inet/getsourcefilter.c +++ b/inet/getsourcefilter.c @@ -1,5 +1,5 @@ /* Get source filter. Stub version. - Copyright (C) 2004-2016 Free Software Foundation, Inc. + Copyright (C) 2004-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. diff --git a/inet/getsrvbynm.c b/inet/getsrvbynm.c index 1a33aab196..797aac3249 100644 --- a/inet/getsrvbynm.c +++ b/inet/getsrvbynm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getsrvbynm_r.c b/inet/getsrvbynm_r.c index e8e5c5378b..8adc0eee12 100644 --- a/inet/getsrvbynm_r.c +++ b/inet/getsrvbynm_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getsrvbypt.c b/inet/getsrvbypt.c index cd1d3ee6de..588be44085 100644 --- a/inet/getsrvbypt.c +++ b/inet/getsrvbypt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/getsrvbypt_r.c b/inet/getsrvbypt_r.c index d4a47ab158..371120635d 100644 --- a/inet/getsrvbypt_r.c +++ b/inet/getsrvbypt_r.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. diff --git a/inet/herrno-loc.c b/inet/herrno-loc.c index cd8e009f08..df475b8f9e 100644 --- a/inet/herrno-loc.c +++ b/inet/herrno-loc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/herrno.c b/inet/herrno.c index 17582dd2bf..20b983bc3c 100644 --- a/inet/herrno.c +++ b/inet/herrno.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996-2016 Free Software Foundation, Inc. +/* Copyright (C) 1996-2018 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 diff --git a/inet/htonl.c b/inet/htonl.c index c7c0e0dd78..fec533f693 100644 --- a/inet/htonl.c +++ b/inet/htonl.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 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 diff --git a/inet/htons.c b/inet/htons.c index c8381ae5a9..4f7974de91 100644 --- a/inet/htons.c +++ b/inet/htons.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1993-2016 Free Software Foundation, Inc. +/* Copyright (C) 1993-2018 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 diff --git a/inet/htontest.c b/inet/htontest.c index 93b33b9a81..e819f2bf19 100644 --- a/inet/htontest.c +++ b/inet/htontest.c @@ -1,5 +1,5 @@ /* Test hton/ntoh functions. - Copyright (C) 1997-2016 Free Software Foundation, Inc. + Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -38,8 +38,8 @@ # error "Bah, what kind of system do you use?" #endif -u_int32_t lo = 0x67452301; -u_int16_t foo = 0x1234; +uint32_t lo = 0x67452301; +uint16_t foo = 0x1234; int main (void) diff --git a/inet/idna.c b/inet/idna.c new file mode 100644 index 0000000000..c561bf2e9e --- /dev/null +++ b/inet/idna.c @@ -0,0 +1,182 @@ +/* IDNA functions, forwarding to implementations in libidn2. + Copyright (C) 2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <allocate_once.h> +#include <dlfcn.h> +#include <inet/net-internal.h> +#include <netdb.h> +#include <stdbool.h> + +/* Use the soname and version to locate libidn2, to ensure a + compatible ABI. */ +#define LIBIDN2_SONAME "libidn2.so.0" +#define LIBIDN2_VERSION "IDN2_0.0.0" + +/* Return codes from libidn2. */ +enum + { + IDN2_OK = 0, + IDN2_MALLOC = -100, + }; + +/* Functions from libidn2. */ +struct functions +{ + void *handle; + int (*lookup_ul) (const char *src, char **result, int flags); + int (*to_unicode_lzlz) (const char *name, char **result, int flags); +}; + +static void * +functions_allocate (void *closure) +{ + struct functions *result = malloc (sizeof (*result)); + if (result == NULL) + return NULL; + + void *handle = __libc_dlopen (LIBIDN2_SONAME); + if (handle == NULL) + /* Do not cache open failures. The library may appear + later. */ + { + free (result); + return NULL; + } + + void *ptr_lookup_ul + = __libc_dlvsym (handle, "idn2_lookup_ul", LIBIDN2_VERSION); + void *ptr_to_unicode_lzlz + = __libc_dlvsym (handle, "idn2_to_unicode_lzlz", LIBIDN2_VERSION); + if (ptr_lookup_ul == NULL || ptr_to_unicode_lzlz == NULL) + { + __libc_dlclose (handle); + free (result); + return NULL; + } + + result->handle = handle; + result->lookup_ul = ptr_lookup_ul; + result->to_unicode_lzlz = ptr_to_unicode_lzlz; +#ifdef PTR_MANGLE + PTR_MANGLE (result->lookup_ul); + PTR_MANGLE (result->to_unicode_lzlz); +#endif + + return result; +} + +static void +functions_deallocate (void *closure, void *ptr) +{ + struct functions *functions = ptr; + __libc_dlclose (functions->handle); + free (functions); +} + +/* Ensure that *functions is initialized and return the value of the + pointer. If the library cannot be loaded, return NULL. */ +static inline struct functions * +get_functions (void) +{ + static void *functions; + return allocate_once (&functions, functions_allocate, functions_deallocate, + NULL); +} + +/* strdup with an EAI_* error code. */ +static int +gai_strdup (const char *name, char **result) +{ + char *ptr = __strdup (name); + if (ptr == NULL) + return EAI_MEMORY; + *result = ptr; + return 0; +} + +int +__idna_to_dns_encoding (const char *name, char **result) +{ + switch (__idna_name_classify (name)) + { + case idna_name_ascii: + /* Nothing to convert. */ + return gai_strdup (name, result); + case idna_name_nonascii: + /* Encoding needed. Handled below. */ + break; + case idna_name_nonascii_backslash: + case idna_name_encoding_error: + return EAI_IDN_ENCODE; + case idna_name_memory_error: + return EAI_MEMORY; + case idna_name_error: + return EAI_SYSTEM; + } + + struct functions *functions = get_functions (); + if (functions == NULL) + /* We report this as an encoding error (assuming that libidn2 is + not installed), although the root cause may be a temporary + error condition due to resource shortage. */ + return EAI_IDN_ENCODE; + char *ptr = NULL; + __typeof__ (functions->lookup_ul) fptr = functions->lookup_ul; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (fptr); +#endif + int ret = fptr (name, &ptr, 0); + if (ret == 0) + { + /* Assume that idn2_free is equivalent to free. */ + *result = ptr; + return 0; + } + else if (ret == IDN2_MALLOC) + return EAI_MEMORY; + else + return EAI_IDN_ENCODE; +} +libc_hidden_def (__idna_to_dns_encoding) + +int +__idna_from_dns_encoding (const char *name, char **result) +{ + struct functions *functions = get_functions (); + if (functions == NULL) + /* Simply use the encoded name, assuming that it is not punycode + (but even a punycode name would be syntactically valid). */ + return gai_strdup (name, result); + char *ptr = NULL; + __typeof__ (functions->to_unicode_lzlz) fptr = functions->to_unicode_lzlz; +#ifdef PTR_DEMANGLE + PTR_DEMANGLE (fptr); +#endif + int ret = fptr (name, &ptr, 0); + if (ret == 0) + { + /* Assume that idn2_free is equivalent to free. */ + *result = ptr; + return 0; + } + else if (ret == IDN2_MALLOC) + return EAI_MEMORY; + else + return EAI_IDN_ENCODE; +} +libc_hidden_def (__idna_from_dns_encoding) diff --git a/inet/idna_name_classify.c b/inet/idna_name_classify.c new file mode 100644 index 0000000000..3683e1133f --- /dev/null +++ b/inet/idna_name_classify.c @@ -0,0 +1,75 @@ +/* Classify a domain name for IDNA purposes. + Copyright (C) 2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <errno.h> +#include <inet/net-internal.h> +#include <stdbool.h> +#include <string.h> +#include <wchar.h> + +enum idna_name_classification +__idna_name_classify (const char *name) +{ + mbstate_t mbs; + memset (&mbs, 0, sizeof (mbs)); + const char *p = name; + const char *end = p + strlen (p) + 1; + bool nonascii = false; + bool backslash = false; + while (true) + { + wchar_t wc; + size_t result = mbrtowc (&wc, p, end - p, &mbs); + if (result == 0) + /* NUL terminator was reached. */ + break; + else if (result == (size_t) -2) + /* Incomplete trailing multi-byte character. This is an + encoding error becaue we received the full name. */ + return idna_name_encoding_error; + else if (result == (size_t) -1) + { + /* Other error, including EILSEQ. */ + if (errno == EILSEQ) + return idna_name_encoding_error; + else if (errno == ENOMEM) + return idna_name_memory_error; + else + return idna_name_error; + } + else + { + /* A wide character was decoded. */ + p += result; + if (wc == L'\\') + backslash = true; + else if (wc > 127) + nonascii = true; + } + } + + if (nonascii) + { + if (backslash) + return idna_name_nonascii_backslash; + else + return idna_name_nonascii; + } + else + return idna_name_ascii; +} diff --git a/inet/if_index.c b/inet/if_index.c index b55e427fac..f537d088e0 100644 --- a/inet/if_index.c +++ b/inet/if_index.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997-2016 Free Software Foundation, Inc. +/* Copyright (C) 1997-2018 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 @@ -58,14 +58,3 @@ __if_nameindex (void) weak_alias (__if_nameindex, if_nameindex) libc_hidden_weak (if_nameindex) stub_warning (if_nameindex) - -#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 index c6ddf0ddb0..fe98508115 100644 --- a/inet/ifaddrs.c +++ b/inet/ifaddrs.c @@ -1,5 +1,5 @@ /* getifaddrs -- get names and addresses of all network interfaces - Copyright (C) 2002-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2018 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 @@ -30,6 +30,7 @@ __getifaddrs (struct ifaddrs **ifap) return -1; } weak_alias (__getifaddrs, getifaddrs) +libc_hidden_def (__getifaddrs) libc_hidden_weak (getifaddrs) stub_warning (getifaddrs) @@ -43,5 +44,6 @@ __freeifaddrs (struct ifaddrs *ifa) abort (); } weak_alias (__freeifaddrs, freeifaddrs) +libc_hidden_def (__freeifaddrs) libc_hidden_weak (freeifaddrs) stub_warning (freeifaddrs) diff --git a/inet/ifaddrs.h b/inet/ifaddrs.h index cd8d20960c..799bf09209 100644 --- a/inet/ifaddrs.h +++ b/inet/ifaddrs.h @@ -1,5 +1,5 @@ /* ifaddrs.h -- declarations for getting network interface addresses - Copyright (C) 2002-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2018 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 diff --git a/inet/ifreq.c b/inet/ifreq.c index 3f0b6ea938..37fdb6a881 100644 --- a/inet/ifreq.c +++ b/inet/ifreq.c @@ -1,5 +1,5 @@ /* Collect network interface list. Stub version. - Copyright (C) 2013-2016 Free Software Foundation, Inc. + Copyright (C) 2013-2018 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 diff --git a/inet/in6_addr.c b/inet/in6_addr.c index 4486a886c5..a2269b8fd6 100644 --- a/inet/in6_addr.c +++ b/inet/in6_addr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1997-2016 Free Software Foundation, Inc. +/* Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Philip Blundell <pjb27@cam.ac.uk>, 1997. diff --git a/inet/inet6_opt.c b/inet/inet6_opt.c index 74115ac966..2f512d8fc5 100644 --- a/inet/inet6_opt.c +++ b/inet/inet6_opt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2006-2016 Free Software Foundation, Inc. +/* Copyright (C) 2006-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2006. diff --git a/inet/inet6_option.c b/inet/inet6_option.c index 91ae982f0d..806bf9c1f3 100644 --- a/inet/inet6_option.c +++ b/inet/inet6_option.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2016 Free Software Foundation, Inc. +/* Copyright (C) 2003-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2003. @@ -24,7 +24,6 @@ static void -internal_function add_pad (struct cmsghdr *cmsg, int len) { unsigned char *p = CMSG_DATA (cmsg) + cmsg->cmsg_len - CMSG_LEN (0); diff --git a/inet/inet6_rth.c b/inet/inet6_rth.c index 42d673cd0f..7caafbc91b 100644 --- a/inet/inet6_rth.c +++ b/inet/inet6_rth.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2006-2016 Free Software Foundation, Inc. +/* Copyright (C) 2006-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2006. diff --git a/inet/inet6_scopeid_pton.c b/inet/inet6_scopeid_pton.c new file mode 100644 index 0000000000..b3c58e73de --- /dev/null +++ b/inet/inet6_scopeid_pton.c @@ -0,0 +1,64 @@ +/* Convert an IPv6 scope ID from text to the internal representation. + Copyright (C) 2016-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <net-internal.h> + +#include <ctype.h> +#include <errno.h> +#include <locale.h> +#include <net/if.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +/* Parse SOURCE as a scope ID for ADDRESS. Return 0 on success and -1 + on error. */ +int +__inet6_scopeid_pton (const struct in6_addr *address, const char *scope, + uint32_t *result) +{ + if (IN6_IS_ADDR_LINKLOCAL (address) + || IN6_IS_ADDR_MC_NODELOCAL (address) + || IN6_IS_ADDR_MC_LINKLOCAL (address)) + { + uint32_t number = __if_nametoindex (scope); + if (number != 0) + { + *result = number; + return 0; + } + } + + if (isdigit_l (scope[0], _nl_C_locobj_ptr)) + { + char *end; + unsigned long long number + = ____strtoull_l_internal (scope, &end, /*base */ 10, /* group */ 0, + _nl_C_locobj_ptr); + if (*end == '\0' && number <= UINT32_MAX) + { + *result = number; + return 0; + } + } + + __set_errno (EINVAL); + return -1; +} + +libc_hidden_def (__inet6_scopeid_pton) diff --git a/inet/inet_lnaof.c b/inet/inet_lnaof.c index 8fd759ccbb..c9e25869b8 100644 --- a/inet/inet_lnaof.c +++ b/inet/inet_lnaof.c @@ -27,10 +27,6 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - #include <sys/param.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -43,7 +39,7 @@ static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93"; in_addr_t inet_lnaof (struct in_addr in) { - u_int32_t i = ntohl(in.s_addr); + uint32_t i = ntohl(in.s_addr); if (IN_CLASSA(i)) return ((i)&IN_CLASSA_HOST); diff --git a/inet/inet_mkadr.c b/inet/inet_mkadr.c index 75d8daa654..88faef74cf 100644 --- a/inet/inet_mkadr.c +++ b/inet/inet_mkadr.c @@ -27,10 +27,6 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - #include <sys/param.h> #include <netinet/in.h> #include <arpa/inet.h> diff --git a/inet/inet_net.c b/inet/inet_net.c index 2e8752d3be..eeb9830d5e 100644 --- a/inet/inet_net.c +++ b/inet/inet_net.c @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ -/* Copyright (C) 2013-2016 Free Software Foundation, Inc. +/* Copyright (C) 2013-2018 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 @@ -44,11 +44,6 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -59,12 +54,12 @@ static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93"; * The library routines call this routine to interpret * network numbers. */ -u_int32_t +uint32_t inet_network (const char *cp) { - u_int32_t val, base, n, i; + uint32_t val, base, n, i; char c; - u_int32_t parts[4], *pp = parts; + uint32_t parts[4], *pp = parts; int digit; again: diff --git a/inet/inet_netof.c b/inet/inet_netof.c index 0f048e6c46..22b91920b5 100644 --- a/inet/inet_netof.c +++ b/inet/inet_netof.c @@ -27,10 +27,6 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - #include <sys/param.h> #include <netinet/in.h> #include <arpa/inet.h> @@ -42,7 +38,7 @@ static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93"; in_addr_t inet_netof (struct in_addr in) { - u_int32_t i = ntohl(in.s_addr); + uint32_t i = ntohl(in.s_addr); if (IN_CLASSA(i)) return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); diff --git a/inet/inet_ntoa.c b/inet/inet_ntoa.c index e4f25ae881..22308a16e0 100644 --- a/inet/inet_ntoa.c +++ b/inet/inet_ntoa.c @@ -1,5 +1,5 @@ /* Convert Inet number to ASCII representation. - Copyright (C) 1997-2016 Free Software Foundation, Inc. + Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. diff --git a/inet/net-internal.h b/inet/net-internal.h new file mode 100644 index 0000000000..0ba6736aef --- /dev/null +++ b/inet/net-internal.h @@ -0,0 +1,143 @@ +/* Network-related functions for internal library use. + Copyright (C) 2016-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _NET_INTERNAL_H +#define _NET_INTERNAL_H 1 + +#include <arpa/inet.h> +#include <stdbool.h> +#include <stdint.h> +#include <sys/time.h> + +int __inet6_scopeid_pton (const struct in6_addr *address, + const char *scope, uint32_t *result); +libc_hidden_proto (__inet6_scopeid_pton) + + +/* IDNA conversion. These functions convert domain names between the + current multi-byte character set and the IDNA encoding. On + success, the result string is written to *RESULT (which the caller + has to free), and zero is returned. On error, an EAI_* error code + is returned (see <netdb.h>), and *RESULT is not changed. */ +int __idna_to_dns_encoding (const char *name, char **result); +libc_hidden_proto (__idna_to_dns_encoding) +int __idna_from_dns_encoding (const char *name, char **result); +libc_hidden_proto (__idna_from_dns_encoding) + + +/* Return value of __idna_name_classify below. */ +enum idna_name_classification +{ + idna_name_ascii, /* No non-ASCII characters. */ + idna_name_nonascii, /* Non-ASCII characters, no backslash. */ + idna_name_nonascii_backslash, /* Non-ASCII characters with backslash. */ + idna_name_encoding_error, /* Decoding error. */ + idna_name_memory_error, /* Memory allocation failure. */ + idna_name_error, /* Other error during decoding. Check errno. */ +}; + +/* Check the specified name for non-ASCII characters and backslashes + or encoding errors. */ +enum idna_name_classification __idna_name_classify (const char *name) + attribute_hidden; + +/* Deadline handling for enforcing timeouts. + + Code should call __deadline_current_time to obtain the current time + and cache it locally. The cache needs updating after every + long-running or potentially blocking operation. Deadlines relative + to the current time can be computed using __deadline_from_timeval. + The deadlines may have to be recomputed in response to certain + events (such as an incoming packet), but they are absolute (not + relative to the current time). A timeout suitable for use with the + poll function can be computed from such a deadline using + __deadline_to_ms. + + The fields in the structs defined belowed should only be used + within the implementation. */ + +/* Cache of the current time. Used to compute deadlines from relative + timeouts and vice versa. */ +struct deadline_current_time +{ + struct timespec current; +}; + +/* Return the current time. Terminates the process if the current + time is not available. */ +struct deadline_current_time __deadline_current_time (void) attribute_hidden; + +/* Computed absolute deadline. */ +struct deadline +{ + struct timespec absolute; +}; + + +/* For internal use only. */ +static inline bool +__deadline_is_infinite (struct deadline deadline) +{ + return deadline.absolute.tv_nsec < 0; +} + +/* Return true if the current time is at the deadline or past it. */ +static inline bool +__deadline_elapsed (struct deadline_current_time current, + struct deadline deadline) +{ + return !__deadline_is_infinite (deadline) + && (current.current.tv_sec > deadline.absolute.tv_sec + || (current.current.tv_sec == deadline.absolute.tv_sec + && current.current.tv_nsec >= deadline.absolute.tv_nsec)); +} + +/* Return the deadline which occurs first. */ +static inline struct deadline +__deadline_first (struct deadline left, struct deadline right) +{ + if (__deadline_is_infinite (right) + || left.absolute.tv_sec < right.absolute.tv_sec + || (left.absolute.tv_sec == right.absolute.tv_sec + && left.absolute.tv_nsec < right.absolute.tv_nsec)) + return left; + else + return right; +} + +/* Add TV to the current time and return it. Returns a special + infinite absolute deadline on overflow. */ +struct deadline __deadline_from_timeval (struct deadline_current_time, + struct timeval tv) attribute_hidden; + +/* Compute the number of milliseconds until the specified deadline, + from the current time in the argument. The result is mainly for + use with poll. If the deadline has already passed, return 0. If + the result would overflow an int, return INT_MAX. */ +int __deadline_to_ms (struct deadline_current_time, struct deadline) + attribute_hidden; + +/* Return true if TV.tv_sec is non-negative and TV.tv_usec is in the + interval [0, 999999]. */ +static inline bool +__is_timeval_valid_timeout (struct timeval tv) +{ + return tv.tv_sec >= 0 && tv.tv_usec >= 0 && tv.tv_usec < 1000 * 1000; +} + +#endif /* _NET_INTERNAL_H */ diff --git a/inet/netgroup.h b/inet/netgroup.h index 365970fad7..e1109b9f1b 100644 --- a/inet/netgroup.h +++ b/inet/netgroup.h @@ -1,5 +1,5 @@ /* Internal header for netgroup related functions. - Copyright (C) 1996-2016 Free Software Foundation, Inc. + Copyright (C) 1996-2018 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 @@ -70,16 +70,13 @@ struct __netgrent /* The internal netgroup handling functions might be called from outside. */ extern int __internal_setnetgrent (const char *group, - struct __netgrent *datap) - internal_function; + struct __netgrent *datap); libc_hidden_proto (__internal_setnetgrent) -extern void __internal_endnetgrent (struct __netgrent *datap) - internal_function; +extern void __internal_endnetgrent (struct __netgrent *datap); libc_hidden_proto (__internal_endnetgrent) extern int __internal_getnetgrent_r (char **hostp, char **userp, char **domainp, struct __netgrent *datap, - char *buffer, size_t buflen, int *errnop) - internal_function; + char *buffer, size_t buflen, int *errnop); libc_hidden_proto (__internal_getnetgrent_r) #endif /* netgroup.h */ diff --git a/inet/netinet/ether.h b/inet/netinet/ether.h index 3dff523b2f..1d23e4a4c6 100644 --- a/inet/netinet/ether.h +++ b/inet/netinet/ether.h @@ -1,5 +1,5 @@ /* Functions for storing Ethernet addresses in ASCII and mapping to hostnames. - Copyright (C) 1996-2016 Free Software Foundation, Inc. + Copyright (C) 1996-2018 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 @@ -24,6 +24,7 @@ /* Get definition of `struct ether_addr'. */ #include <netinet/if_ether.h> +#ifdef __USE_MISC __BEGIN_DECLS /* Convert 48 bit Ethernet ADDRess to ASCII. */ @@ -49,5 +50,6 @@ extern int ether_line (const char *__line, struct ether_addr *__addr, char *__hostname) __THROW; __END_DECLS +#endif /* Use misc. */ #endif /* netinet/ether.h */ diff --git a/inet/netinet/icmp6.h b/inet/netinet/icmp6.h index b7a9637b52..a7100abf00 100644 --- a/inet/netinet/icmp6.h +++ b/inet/netinet/icmp6.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 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 @@ -160,11 +160,11 @@ struct nd_neighbor_advert /* neighbor advertisement */ #define nd_na_code nd_na_hdr.icmp6_code #define nd_na_cksum nd_na_hdr.icmp6_cksum #define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0] -#if BYTE_ORDER == BIG_ENDIAN +#if __BYTE_ORDER == __BIG_ENDIAN #define ND_NA_FLAG_ROUTER 0x80000000 #define ND_NA_FLAG_SOLICITED 0x40000000 #define ND_NA_FLAG_OVERRIDE 0x20000000 -#else /* BYTE_ORDER == LITTLE_ENDIAN */ +#else /* __BYTE_ORDER == __LITTLE_ENDIAN */ #define ND_NA_FLAG_ROUTER 0x00000080 #define ND_NA_FLAG_SOLICITED 0x00000040 #define ND_NA_FLAG_OVERRIDE 0x00000020 @@ -298,10 +298,10 @@ struct rr_pco_use /* use prefix part */ #define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x20 #define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x10 -#if BYTE_ORDER == BIG_ENDIAN +#if __BYTE_ORDER == __BIG_ENDIAN # define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80000000 # define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40000000 -#elif BYTE_ORDER == LITTLE_ENDIAN +#elif __BYTE_ORDER == __LITTLE_ENDIAN # define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME 0x80 # define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME 0x40 #endif @@ -315,10 +315,10 @@ struct rr_result /* router renumbering result message */ struct in6_addr rrr_prefix; }; -#if BYTE_ORDER == BIG_ENDIAN +#if __BYTE_ORDER == __BIG_ENDIAN # define ICMP6_RR_RESULT_FLAGS_OOB 0x0002 # define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0001 -#elif BYTE_ORDER == LITTLE_ENDIAN +#elif __BYTE_ORDER == __LITTLE_ENDIAN # define ICMP6_RR_RESULT_FLAGS_OOB 0x0200 # define ICMP6_RR_RESULT_FLAGS_FORBIDDEN 0x0100 #endif diff --git a/inet/netinet/igmp.h b/inet/netinet/igmp.h index fc7599e5e8..7a5b5249df 100644 --- a/inet/netinet/igmp.h +++ b/inet/netinet/igmp.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1997-2016 Free Software Foundation, Inc. +/* Copyright (C) 1997-2018 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 @@ -64,10 +64,10 @@ __BEGIN_DECLS */ struct igmp { - u_int8_t igmp_type; /* IGMP type */ - u_int8_t igmp_code; /* routing code */ - u_int16_t igmp_cksum; /* checksum */ - struct in_addr igmp_group; /* group address */ + uint8_t igmp_type; /* IGMP type */ + uint8_t igmp_code; /* routing code */ + uint16_t igmp_cksum; /* checksum */ + struct in_addr igmp_group; /* group address */ }; #define IGMP_MINLEN 8 diff --git a/inet/netinet/in.h b/inet/netinet/in.h index 6122ab599b..03a31b634c 100644 --- a/inet/netinet/in.h +++ b/inet/netinet/in.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 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 @@ -19,7 +19,7 @@ #define _NETINET_IN_H 1 #include <features.h> -#include <stdint.h> +#include <bits/stdint-uintn.h> #include <sys/socket.h> #include <bits/types.h> @@ -92,10 +92,10 @@ enum IPPROTO_MAX }; -/* If __USE_KERNEL_IPV6_DEFS is defined then the user has included the kernel +/* If __USE_KERNEL_IPV6_DEFS is 1 then the user has included the kernel network headers first and we should use those ABI-identical definitions - instead of our own. */ -#ifndef __USE_KERNEL_IPV6_DEFS + instead of our own, otherwise 0. */ +#if !__USE_KERNEL_IPV6_DEFS enum { IPPROTO_HOPOPTS = 0, /* IPv6 Hop-by-Hop options. */ @@ -206,17 +206,15 @@ enum #define INADDR_ALLRTRS_GROUP ((in_addr_t) 0xe0000002) /* 224.0.0.2 */ #define INADDR_MAX_LOCAL_GROUP ((in_addr_t) 0xe00000ff) /* 224.0.0.255 */ -#ifndef __USE_KERNEL_IPV6_DEFS +#if !__USE_KERNEL_IPV6_DEFS /* IPv6 address */ struct in6_addr { union { uint8_t __u6_addr8[16]; -#ifdef __USE_MISC uint16_t __u6_addr16[8]; uint32_t __u6_addr32[4]; -#endif } __in6_u; #define s6_addr __in6_u.__u6_addr8 #ifdef __USE_MISC @@ -249,7 +247,7 @@ struct sockaddr_in sizeof (struct in_addr)]; }; -#ifndef __USE_KERNEL_IPV6_DEFS +#if !__USE_KERNEL_IPV6_DEFS /* Ditto, for IPv6. */ struct sockaddr_in6 { @@ -277,15 +275,15 @@ struct ip_mreq_source /* IP multicast address of group. */ struct in_addr imr_multiaddr; - /* IP address of source. */ + /* IP address of interface. */ struct in_addr imr_interface; - /* IP address of interface. */ + /* IP address of source. */ struct in_addr imr_sourceaddr; }; #endif -#ifndef __USE_KERNEL_IPV6_DEFS +#if !__USE_KERNEL_IPV6_DEFS /* Likewise, for IPv6. */ struct ipv6_mreq { @@ -385,6 +383,7 @@ extern uint16_t htons (uint16_t __hostshort) /* Get machine dependent optimized versions of byte swapping functions. */ #include <bits/byteswap.h> +#include <bits/uintn-identity.h> #ifdef __OPTIMIZE__ /* We can optimize calls to the conversion functions. Either nothing has @@ -393,10 +392,10 @@ extern uint16_t htons (uint16_t __hostshort) # if __BYTE_ORDER == __BIG_ENDIAN /* The host byte order is the same as network byte order, so these functions are all just identity. */ -# define ntohl(x) (x) -# define ntohs(x) (x) -# define htonl(x) (x) -# define htons(x) (x) +# define ntohl(x) __uint32_identity (x) +# define ntohs(x) __uint16_identity (x) +# define htonl(x) __uint32_identity (x) +# define htons(x) __uint16_identity (x) # else # if __BYTE_ORDER == __LITTLE_ENDIAN # define ntohl(x) __bswap_32 (x) @@ -411,52 +410,52 @@ extern uint16_t htons (uint16_t __hostshort) # define IN6_IS_ADDR_UNSPECIFIED(a) \ (__extension__ \ ({ const struct in6_addr *__a = (const struct in6_addr *) (a); \ - __a->s6_addr32[0] == 0 \ - && __a->s6_addr32[1] == 0 \ - && __a->s6_addr32[2] == 0 \ - && __a->s6_addr32[3] == 0; })) + __a->__in6_u.__u6_addr32[0] == 0 \ + && __a->__in6_u.__u6_addr32[1] == 0 \ + && __a->__in6_u.__u6_addr32[2] == 0 \ + && __a->__in6_u.__u6_addr32[3] == 0; })) # define IN6_IS_ADDR_LOOPBACK(a) \ (__extension__ \ ({ const struct in6_addr *__a = (const struct in6_addr *) (a); \ - __a->s6_addr32[0] == 0 \ - && __a->s6_addr32[1] == 0 \ - && __a->s6_addr32[2] == 0 \ - && __a->s6_addr32[3] == htonl (1); })) + __a->__in6_u.__u6_addr32[0] == 0 \ + && __a->__in6_u.__u6_addr32[1] == 0 \ + && __a->__in6_u.__u6_addr32[2] == 0 \ + && __a->__in6_u.__u6_addr32[3] == htonl (1); })) # define IN6_IS_ADDR_LINKLOCAL(a) \ (__extension__ \ ({ const struct in6_addr *__a = (const struct in6_addr *) (a); \ - (__a->s6_addr32[0] & htonl (0xffc00000)) == htonl (0xfe800000); })) + (__a->__in6_u.__u6_addr32[0] & htonl (0xffc00000)) == htonl (0xfe800000); })) # define IN6_IS_ADDR_SITELOCAL(a) \ (__extension__ \ ({ const struct in6_addr *__a = (const struct in6_addr *) (a); \ - (__a->s6_addr32[0] & htonl (0xffc00000)) == htonl (0xfec00000); })) + (__a->__in6_u.__u6_addr32[0] & htonl (0xffc00000)) == htonl (0xfec00000); })) # define IN6_IS_ADDR_V4MAPPED(a) \ (__extension__ \ ({ const struct in6_addr *__a = (const struct in6_addr *) (a); \ - __a->s6_addr32[0] == 0 \ - && __a->s6_addr32[1] == 0 \ - && __a->s6_addr32[2] == htonl (0xffff); })) + __a->__in6_u.__u6_addr32[0] == 0 \ + && __a->__in6_u.__u6_addr32[1] == 0 \ + && __a->__in6_u.__u6_addr32[2] == htonl (0xffff); })) # define IN6_IS_ADDR_V4COMPAT(a) \ (__extension__ \ ({ const struct in6_addr *__a = (const struct in6_addr *) (a); \ - __a->s6_addr32[0] == 0 \ - && __a->s6_addr32[1] == 0 \ - && __a->s6_addr32[2] == 0 \ - && ntohl (__a->s6_addr32[3]) > 1; })) + __a->__in6_u.__u6_addr32[0] == 0 \ + && __a->__in6_u.__u6_addr32[1] == 0 \ + && __a->__in6_u.__u6_addr32[2] == 0 \ + && ntohl (__a->__in6_u.__u6_addr32[3]) > 1; })) # define IN6_ARE_ADDR_EQUAL(a,b) \ (__extension__ \ ({ const struct in6_addr *__a = (const struct in6_addr *) (a); \ const struct in6_addr *__b = (const struct in6_addr *) (b); \ - __a->s6_addr32[0] == __b->s6_addr32[0] \ - && __a->s6_addr32[1] == __b->s6_addr32[1] \ - && __a->s6_addr32[2] == __b->s6_addr32[2] \ - && __a->s6_addr32[3] == __b->s6_addr32[3]; })) + __a->__in6_u.__u6_addr32[0] == __b->__in6_u.__u6_addr32[0] \ + && __a->__in6_u.__u6_addr32[1] == __b->__in6_u.__u6_addr32[1] \ + && __a->__in6_u.__u6_addr32[2] == __b->__in6_u.__u6_addr32[2] \ + && __a->__in6_u.__u6_addr32[3] == __b->__in6_u.__u6_addr32[3]; })) #else # define IN6_IS_ADDR_UNSPECIFIED(a) \ (((const uint32_t *) (a))[0] == 0 \ @@ -532,7 +531,7 @@ extern int bindresvport6 (int __sockfd, struct sockaddr_in6 *__sock_in) #ifdef __USE_GNU struct cmsghdr; /* Forward declaration. */ -#ifndef __USE_KERNEL_IPV6_DEFS +#if !__USE_KERNEL_IPV6_DEFS /* IPv6 packet information. */ struct in6_pktinfo { diff --git a/inet/netinet/ip6.h b/inet/netinet/ip6.h index 929d4b5dc0..31422ff927 100644 --- a/inet/netinet/ip6.h +++ b/inet/netinet/ip6.h @@ -1,4 +1,4 @@ -/* Copyright (C) 1991-2016 Free Software Foundation, Inc. +/* Copyright (C) 1991-2018 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 @@ -101,11 +101,11 @@ struct ip6_frag uint32_t ip6f_ident; /* identification */ }; -#if BYTE_ORDER == BIG_ENDIAN +#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 */ +#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 */ @@ -175,11 +175,11 @@ 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 -#else /* BYTE_ORDER == LITTLE_ENDING */ +#else /* __BYTE_ORDER == __LITTLE_ENDIAN */ # define IP6_ALERT_MLD 0x0000 # define IP6_ALERT_RSVP 0x0100 # define IP6_ALERT_AN 0x0200 diff --git a/inet/protocols/routed.h b/inet/protocols/routed.h index befd8654d7..adb1767dca 100644 --- a/inet/protocols/routed.h +++ b/inet/protocols/routed.h @@ -48,9 +48,9 @@ struct netinfo { }; struct rip { - u_char rip_cmd; /* request/response */ - u_char rip_vers; /* protocol version # */ - u_char rip_res1[2]; /* pad to 32-bit boundary */ + unsigned char rip_cmd; /* request/response */ + unsigned char rip_vers; /* protocol version # */ + unsigned char rip_res1[2]; /* pad to 32-bit boundary */ union { struct netinfo ru_nets[1]; /* variable length... */ char ru_tracefile[1]; /* ditto ... */ diff --git a/inet/protocols/talkd.h b/inet/protocols/talkd.h index a8f33b1bab..09bd8a90ba 100644 --- a/inet/protocols/talkd.h +++ b/inet/protocols/talkd.h @@ -52,16 +52,18 @@ #include <sys/types.h> #include <sys/socket.h> +#include <stdint.h> +#include <bits/types/struct_osockaddr.h> /* * Client->server request message format. */ typedef struct { - u_char vers; /* protocol version */ - u_char type; /* request type, see below */ - u_char answer; /* not used */ - u_char pad; - u_int32_t id_num; /* message id */ + unsigned char vers; /* protocol version */ + unsigned char type; /* request type, see below */ + unsigned char answer; /* not used */ + unsigned char pad; + uint32_t id_num; /* message id */ struct osockaddr addr; /* old (4.3) style */ struct osockaddr ctl_addr; /* old (4.3) style */ int32_t pid; /* caller's process id */ @@ -76,11 +78,11 @@ typedef struct { * Server->client response message format. */ typedef struct { - u_char vers; /* protocol version */ - u_char type; /* type of request message, see below */ - u_char answer; /* response to request message, see below */ - u_char pad; - u_int32_t id_num; /* message id */ + unsigned char vers; /* protocol version */ + unsigned char type; /* type of request message, see below */ + unsigned char answer; /* response to request message, see below */ + unsigned char pad; + uint32_t id_num; /* message id */ struct osockaddr addr; /* address for establishing conversation */ } CTL_RESPONSE; diff --git a/inet/protocols/timed.h b/inet/protocols/timed.h index b5d4702ff3..cabdce44a6 100644 --- a/inet/protocols/timed.h +++ b/inet/protocols/timed.h @@ -44,9 +44,9 @@ #define MAXHOSTNAMELEN 64 struct tsp { - u_char tsp_type; - u_char tsp_vers; - u_short tsp_seq; + unsigned char tsp_type; + unsigned char tsp_vers; + unsigned short tsp_seq; union { struct timeval tspu_time; char tspu_hopcnt; diff --git a/inet/rcmd.c b/inet/rcmd.c index ace6b14a93..8a9616f847 100644 --- a/inet/rcmd.c +++ b/inet/rcmd.c @@ -55,10 +55,6 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; -#endif /* LIBC_SCCS and not lint */ - #include <sys/param.h> #include <sys/poll.h> #include <sys/socket.h> @@ -82,9 +78,10 @@ static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; #include <stdlib.h> #include <wchar.h> #include <sys/uio.h> +#include <sigsetops.h> -int __ivaliduser (FILE *, u_int32_t, const char *, const char *); +int __ivaliduser (FILE *, uint32_t, const char *, const char *); static int __validuser2_sa (FILE *, struct sockaddr *, size_t, const char *, const char *, const char *); static int ruserok2_sa (struct sockaddr *ra, size_t ralen, @@ -95,7 +92,7 @@ static int ruserok_sa (struct sockaddr *ra, size_t ralen, const char *luser); int iruserok_af (const void *raddr, int superuser, const char *ruser, const char *luser, sa_family_t af); -int iruserok (u_int32_t raddr, int superuser, const char *ruser, +int iruserok (uint32_t raddr, int superuser, const char *ruser, const char *luser); libc_hidden_proto (iruserok_af) @@ -116,7 +113,8 @@ rcmd_af (char **ahost, u_short rport, const char *locuser, const char *remuser, struct sockaddr_in6 sin6; } from; struct pollfd pfd[2]; - int32_t oldmask; + sigset_t mask, omask; + pid_t pid; int s, lport, timo, error; char c; @@ -153,7 +151,7 @@ rcmd_af (char **ahost, u_short rport, const char *locuser, const char *remuser, if (res->ai_canonname){ free (ahostbuf); - ahostbuf = strdup (res->ai_canonname); + ahostbuf = __strdup (res->ai_canonname); if (ahostbuf == NULL) { __fxprintf(NULL, "%s", _("rcmd: Cannot allocate memory\n")); @@ -164,7 +162,9 @@ rcmd_af (char **ahost, u_short rport, const char *locuser, const char *remuser, *ahost = NULL; ai = res; refused = 0; - oldmask = __sigblock(sigmask(SIGURG)); + __sigemptyset(&mask); + __sigaddset(&mask, SIGURG); + __sigprocmask (SIG_BLOCK, &mask, &omask); for (timo = 1, lport = IPPORT_RESERVED - 1;;) { char errbuf[200]; @@ -176,7 +176,7 @@ rcmd: socket: All ports in use\n")); else __fxprintf(NULL, "rcmd: socket: %m\n"); - __sigsetmask(oldmask); + __sigprocmask (SIG_SETMASK, &omask, 0); freeaddrinfo(res); return -1; } @@ -229,7 +229,7 @@ rcmd: socket: All ports in use\n")); freeaddrinfo(res); (void)__fxprintf(NULL, "%s: %s\n", *ahost, __strerror_r(errno, errbuf, sizeof (errbuf))); - __sigsetmask(oldmask); + __sigprocmask (SIG_SETMASK, &omask, 0); return -1; } lport--; @@ -341,7 +341,7 @@ socket: protocol failure in circuit setup\n")) >= 0) } goto bad2; } - __sigsetmask(oldmask); + __sigprocmask (SIG_SETMASK, &omask, 0); freeaddrinfo(res); return s; bad2: @@ -349,7 +349,7 @@ bad2: (void)__close(*fd2p); bad: (void)__close(s); - __sigsetmask(oldmask); + __sigprocmask (SIG_SETMASK, &omask, 0); freeaddrinfo(res); return -1; } @@ -387,6 +387,7 @@ rresvport_af (int *alport, sa_family_t family) __set_errno (EAFNOSUPPORT); return -1; } + /* NB: No SOCK_CLOEXEC for backwards compatibility. */ s = __socket(family, SOCK_STREAM, 0); if (s < 0) return -1; @@ -614,7 +615,7 @@ iruserok_af (const void *raddr, int superuser, const char *ruser, libc_hidden_def (iruserok_af) int -iruserok (u_int32_t raddr, int superuser, const char *ruser, const char *luser) +iruserok (uint32_t raddr, int superuser, const char *ruser, const char *luser) { return iruserok_af (&raddr, superuser, ruser, luser, AF_INET); } @@ -631,7 +632,7 @@ iruserok (u_int32_t raddr, int superuser, const char *ruser, const char *luser) * Returns 0 if ok, -1 if not ok. */ int -__ivaliduser (FILE *hostf, u_int32_t raddr, const char *luser, +__ivaliduser (FILE *hostf, uint32_t raddr, const char *luser, const char *ruser) { struct sockaddr_in ra; @@ -645,7 +646,6 @@ __ivaliduser (FILE *hostf, u_int32_t raddr, const char *luser, /* Returns 1 on positive match, 0 on no match, -1 on negative match. */ static int -internal_function __checkhost_sa (struct sockaddr *ra, size_t ralen, char *lhost, const char *rhost) { @@ -699,7 +699,6 @@ __checkhost_sa (struct sockaddr *ra, size_t ralen, char *lhost, /* Returns 1 on positive match, 0 on no match, -1 on negative match. */ static int -internal_function __icheckuser (const char *luser, const char *ruser) { /* diff --git a/inet/rexec.c b/inet/rexec.c index 4e6d48d6b8..bda536723b 100644 --- a/inet/rexec.c +++ b/inet/rexec.c @@ -27,10 +27,6 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)rexec.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - #include <sys/types.h> #include <sys/socket.h> @@ -77,7 +73,7 @@ rexec_af (char **ahost, int rport, const char *name, const char *pass, if (res0->ai_canonname){ free (ahostbuf); - ahostbuf = strdup (res0->ai_canonname); + ahostbuf = __strdup (res0->ai_canonname); if (ahostbuf == NULL) { perror ("rexec: strdup"); return (-1); @@ -90,6 +86,7 @@ rexec_af (char **ahost, int rport, const char *name, const char *pass, } ruserpass(res0->ai_canonname, &name, &pass); retry: + /* NB: No SOCK_CLOEXEC for backwards compatibility. */ s = __socket(res0->ai_family, res0->ai_socktype, 0); if (s < 0) { perror("rexec: socket"); diff --git a/inet/ruserpass.c b/inet/ruserpass.c index ff379db43b..4fa6520c1a 100644 --- a/inet/ruserpass.c +++ b/inet/ruserpass.c @@ -27,10 +27,6 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)ruserpass.c 8.3 (Berkeley) 4/2/94"; -#endif /* not lint */ - #include <sys/types.h> #include <sys/stat.h> @@ -181,7 +177,7 @@ next: fstat64(fileno(cfile), &stb) >= 0 && (stb.st_mode & 077) != 0) { warnx(_("Error: .netrc file is readable by others.")); - warnx(_("Remove password or make file unreadable by others.")); + warnx(_("Remove 'password' line or make file unreadable by others.")); goto bad; } if (token() && *apass == 0) { @@ -196,81 +192,8 @@ next: } break; case ACCOUNT: -#if 0 - if (fstat64(fileno(cfile), &stb) >= 0 - && (stb.st_mode & 077) != 0) { - warnx("Error: .netrc file is readable by others."); - warnx("Remove account or make file unreadable by others."); - goto bad; - } - if (token() && *aacct == 0) { - *aacct = malloc((unsigned) strlen(tokval) + 1); - (void) strcpy(*aacct, tokval); - } -#endif break; case MACDEF: -#if 0 - if (proxy) { - (void) fclose(cfile); - return (0); - } - while ((c=getc_unlocked(cfile)) != EOF && c == ' ' - || c == '\t'); - if (c == EOF || c == '\n') { - printf("Missing macdef name argument.\n"); - goto bad; - } - if (macnum == 16) { - printf("Limit of 16 macros have already been defined\n"); - goto bad; - } - tmp = macros[macnum].mac_name; - *tmp++ = c; - for (i=0; i < 8 && (c=getc_unlocked(cfile)) != EOF && - !isspace(c); ++i) { - *tmp++ = c; - } - if (c == EOF) { - printf("Macro definition missing null line terminator.\n"); - goto bad; - } - *tmp = '\0'; - if (c != '\n') { - while ((c=getc_unlocked(cfile)) != EOF - && c != '\n'); - } - if (c == EOF) { - printf("Macro definition missing null line terminator.\n"); - goto bad; - } - if (macnum == 0) { - macros[macnum].mac_start = macbuf; - } - else { - macros[macnum].mac_start = macros[macnum-1].mac_end + 1; - } - tmp = macros[macnum].mac_start; - while (tmp != macbuf + 4096) { - if ((c=getc_unlocked(cfile)) == EOF) { - printf("Macro definition missing null line terminator.\n"); - goto bad; - } - *tmp = c; - if (*tmp == '\n') { - if (*(tmp-1) == '\0') { - macros[macnum++].mac_end = tmp - 1; - break; - } - *tmp = '\0'; - } - tmp++; - } - if (tmp == macbuf + 4096) { - printf("4K macro buffer exceeded\n"); - goto bad; - } -#endif break; default: warnx(_("Unknown .netrc keyword %s"), tokval); diff --git a/inet/setipv4sourcefilter.c b/inet/setipv4sourcefilter.c index 0422c3180b..7e6bd49154 100644 --- a/inet/setipv4sourcefilter.c +++ b/inet/setipv4sourcefilter.c @@ -1,5 +1,5 @@ /* Set source filter. Stub version. - Copyright (C) 2004-2016 Free Software Foundation, Inc. + Copyright (C) 2004-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. diff --git a/inet/setsourcefilter.c b/inet/setsourcefilter.c index 9cbeff1755..85883cfb2f 100644 --- a/inet/setsourcefilter.c +++ b/inet/setsourcefilter.c @@ -1,5 +1,5 @@ /* Set source filter. Stub version. - Copyright (C) 2004-2016 Free Software Foundation, Inc. + Copyright (C) 2004-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2004. diff --git a/inet/test-hnto-types.c b/inet/test-hnto-types.c new file mode 100644 index 0000000000..6220753228 --- /dev/null +++ b/inet/test-hnto-types.c @@ -0,0 +1,39 @@ +/* Test netinet/in.h endian-conversion macros always return the correct type. + Copyright (C) 2017-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <netinet/in.h> +#include <stdint.h> + +int i; +uint16_t u16; +uint32_t u32; + +int +do_test (void) +{ + /* This is a compilation test. */ + extern __typeof (htons (i)) u16; + extern __typeof (ntohs (i)) u16; + extern __typeof (htonl (i)) u32; + extern __typeof (ntohl (i)) u32; + (void) u16; + (void) u32; + return 0; +} + +#include <support/test-driver.c> diff --git a/inet/test-ifaddrs.c b/inet/test-ifaddrs.c index 32555af6e4..5e31c51c01 100644 --- a/inet/test-ifaddrs.c +++ b/inet/test-ifaddrs.c @@ -1,5 +1,5 @@ /* Test listing of network interface addresses. - Copyright (C) 2002-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2018 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 diff --git a/inet/test_ifindex.c b/inet/test_ifindex.c index f55b5af9d3..b163637131 100644 --- a/inet/test_ifindex.c +++ b/inet/test_ifindex.c @@ -1,5 +1,5 @@ /* Test interface name <-> index conversions. - Copyright (C) 1997-2016 Free Software Foundation, Inc. + Copyright (C) 1997-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Philip Blundell <Philip.Blundell@pobox.com>. diff --git a/inet/tst-checks-posix.c b/inet/tst-checks-posix.c new file mode 100644 index 0000000000..243b4ca9d8 --- /dev/null +++ b/inet/tst-checks-posix.c @@ -0,0 +1,23 @@ +/* Test IPv6 classification macros in POSIX mode. + Copyright (C) 2016-2018 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, see + <http://www.gnu.org/licenses/>. */ + +/* Process tst-checks.c in POSIX mode. */ +#undef _GNU_SOURCE +#define _POSIX_C_SOURCE 200112L + +#include "tst-checks.c" diff --git a/inet/tst-checks.c b/inet/tst-checks.c index 5d97564cd6..1a4785d96e 100644 --- a/inet/tst-checks.c +++ b/inet/tst-checks.c @@ -169,5 +169,4 @@ do_test (void) return result; } -#define TEST_FUNCTION do_test () -#include "../test-skeleton.c" +#include <support/test-driver.c> diff --git a/inet/tst-deadline.c b/inet/tst-deadline.c new file mode 100644 index 0000000000..ff44a15605 --- /dev/null +++ b/inet/tst-deadline.c @@ -0,0 +1,188 @@ +/* Tests for computing deadlines for timeouts. + Copyright (C) 2017-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <inet/net-internal.h> +#include <limits.h> +#include <stdbool.h> +#include <stdint.h> +#include <support/check.h> + +/* Find the maximum value which can be represented in a time_t. */ +static time_t +time_t_max (void) +{ + _Static_assert (0 > (time_t) -1, "time_t is signed"); + uintmax_t current = 1; + while (true) + { + uintmax_t next = current * 2; + /* This cannot happen because time_t is signed. */ + TEST_VERIFY_EXIT (next > current); + ++next; + if ((time_t) next < 0 || next != (uintmax_t) (time_t) next) + /* Value cannot be represented in time_t. Return the previous + value. */ + return current; + current = next; + } +} + +static int +do_test (void) +{ + { + struct deadline_current_time current_time = __deadline_current_time (); + TEST_VERIFY (current_time.current.tv_sec >= 0); + current_time = __deadline_current_time (); + /* Due to CLOCK_MONOTONIC, either seconds or nanoseconds are + greater than zero. This is also true for the gettimeofday + fallback. */ + TEST_VERIFY (current_time.current.tv_sec >= 0); + TEST_VERIFY (current_time.current.tv_sec > 0 + || current_time.current.tv_nsec > 0); + } + + /* Check basic computations of deadlines. */ + struct deadline_current_time current_time = { { 1, 123456789 } }; + struct deadline deadline = __deadline_from_timeval + (current_time, (struct timeval) { 0, 1 }); + TEST_VERIFY (deadline.absolute.tv_sec == 1); + TEST_VERIFY (deadline.absolute.tv_nsec == 123457789); + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1); + + deadline = __deadline_from_timeval + (current_time, ((struct timeval) { 0, 2 })); + TEST_VERIFY (deadline.absolute.tv_sec == 1); + TEST_VERIFY (deadline.absolute.tv_nsec == 123458789); + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1); + + deadline = __deadline_from_timeval + (current_time, ((struct timeval) { 1, 0 })); + TEST_VERIFY (deadline.absolute.tv_sec == 2); + TEST_VERIFY (deadline.absolute.tv_nsec == 123456789); + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000); + + /* Check if timeouts are correctly rounded up to the next + millisecond. */ + for (int i = 0; i < 999999; ++i) + { + ++current_time.current.tv_nsec; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000); + } + + /* A full millisecond has elapsed, so the time to the deadline is + now less than 1000. */ + ++current_time.current.tv_nsec; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 999); + + /* Check __deadline_to_ms carry-over. */ + current_time = (struct deadline_current_time) { { 9, 123456789 } }; + deadline = (struct deadline) { { 10, 122456789 } }; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 999); + deadline = (struct deadline) { { 10, 122456790 } }; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000); + deadline = (struct deadline) { { 10, 123456788 } }; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000); + deadline = (struct deadline) { { 10, 123456789 } }; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 1000); + + /* Check __deadline_to_ms overflow. */ + deadline = (struct deadline) { { INT_MAX - 1, 1 } }; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == INT_MAX); + + /* Check __deadline_to_ms for elapsed deadlines. */ + current_time = (struct deadline_current_time) { { 9, 123456789 } }; + deadline.absolute = current_time.current; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0); + current_time = (struct deadline_current_time) { { 9, 123456790 } }; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0); + current_time = (struct deadline_current_time) { { 10, 0 } }; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0); + current_time = (struct deadline_current_time) { { 10, 123456788 } }; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0); + current_time = (struct deadline_current_time) { { 10, 123456789 } }; + TEST_VERIFY (__deadline_to_ms (current_time, deadline) == 0); + + /* Check carry-over in __deadline_from_timeval. */ + current_time = (struct deadline_current_time) { { 9, 998000001 } }; + for (int i = 0; i < 2000; ++i) + { + deadline = __deadline_from_timeval + (current_time, (struct timeval) { 1, i }); + TEST_VERIFY (deadline.absolute.tv_sec == 10); + TEST_VERIFY (deadline.absolute.tv_nsec == 998000001 + i * 1000); + } + for (int i = 2000; i < 3000; ++i) + { + deadline = __deadline_from_timeval + (current_time, (struct timeval) { 2, i }); + TEST_VERIFY (deadline.absolute.tv_sec == 12); + TEST_VERIFY (deadline.absolute.tv_nsec == 1 + (i - 2000) * 1000); + } + + /* Check infinite deadlines. */ + deadline = __deadline_from_timeval + ((struct deadline_current_time) { { 0, 1000 * 1000 * 1000 - 1000 } }, + (struct timeval) { time_t_max (), 1 }); + TEST_VERIFY (__deadline_is_infinite (deadline)); + deadline = __deadline_from_timeval + ((struct deadline_current_time) { { 0, 1000 * 1000 * 1000 - 1001 } }, + (struct timeval) { time_t_max (), 1 }); + TEST_VERIFY (!__deadline_is_infinite (deadline)); + deadline = __deadline_from_timeval + ((struct deadline_current_time) + { { time_t_max (), 1000 * 1000 * 1000 - 1000 } }, + (struct timeval) { 0, 1 }); + TEST_VERIFY (__deadline_is_infinite (deadline)); + deadline = __deadline_from_timeval + ((struct deadline_current_time) + { { time_t_max () / 2 + 1, 0 } }, + (struct timeval) { time_t_max () / 2 + 1, 0 }); + TEST_VERIFY (__deadline_is_infinite (deadline)); + + /* Check __deadline_first behavior. */ + deadline = __deadline_first + ((struct deadline) { { 1, 2 } }, + (struct deadline) { { 1, 3 } }); + TEST_VERIFY (deadline.absolute.tv_sec == 1); + TEST_VERIFY (deadline.absolute.tv_nsec == 2); + deadline = __deadline_first + ((struct deadline) { { 1, 3 } }, + (struct deadline) { { 1, 2 } }); + TEST_VERIFY (deadline.absolute.tv_sec == 1); + TEST_VERIFY (deadline.absolute.tv_nsec == 2); + deadline = __deadline_first + ((struct deadline) { { 1, 2 } }, + (struct deadline) { { 2, 1 } }); + TEST_VERIFY (deadline.absolute.tv_sec == 1); + TEST_VERIFY (deadline.absolute.tv_nsec == 2); + deadline = __deadline_first + ((struct deadline) { { 1, 2 } }, + (struct deadline) { { 2, 4 } }); + TEST_VERIFY (deadline.absolute.tv_sec == 1); + TEST_VERIFY (deadline.absolute.tv_nsec == 2); + deadline = __deadline_first + ((struct deadline) { { 2, 4 } }, + (struct deadline) { { 1, 2 } }); + TEST_VERIFY (deadline.absolute.tv_sec == 1); + TEST_VERIFY (deadline.absolute.tv_nsec == 2); + + return 0; +} + +#include <support/test-driver.c> diff --git a/inet/tst-idna_name_classify.c b/inet/tst-idna_name_classify.c new file mode 100644 index 0000000000..c4a2c91329 --- /dev/null +++ b/inet/tst-idna_name_classify.c @@ -0,0 +1,73 @@ +/* Test IDNA name classification. + Copyright (C) 2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <inet/net-internal.h> +#include <locale.h> +#include <stdio.h> +#include <support/check.h> + +static void +locale_insensitive_tests (void) +{ + TEST_COMPARE (__idna_name_classify (""), idna_name_ascii); + TEST_COMPARE (__idna_name_classify ("abc"), idna_name_ascii); + TEST_COMPARE (__idna_name_classify (".."), idna_name_ascii); + TEST_COMPARE (__idna_name_classify ("\001abc\177"), idna_name_ascii); + TEST_COMPARE (__idna_name_classify ("\\065bc"), idna_name_ascii); +} + +static int +do_test (void) +{ + puts ("info: C locale tests"); + locale_insensitive_tests (); + TEST_COMPARE (__idna_name_classify ("abc\200def"), + idna_name_encoding_error); + TEST_COMPARE (__idna_name_classify ("abc\200\\def"), + idna_name_encoding_error); + TEST_COMPARE (__idna_name_classify ("abc\377def"), + idna_name_encoding_error); + + puts ("info: en_US.ISO-8859-1 locale tests"); + if (setlocale (LC_CTYPE, "en_US.ISO-8859-1") == 0) + FAIL_EXIT1 ("setlocale for en_US.ISO-8859-1: %m\n"); + locale_insensitive_tests (); + TEST_COMPARE (__idna_name_classify ("abc\200def"), idna_name_nonascii); + TEST_COMPARE (__idna_name_classify ("abc\377def"), idna_name_nonascii); + TEST_COMPARE (__idna_name_classify ("abc\\\200def"), + idna_name_nonascii_backslash); + TEST_COMPARE (__idna_name_classify ("abc\200\\def"), + idna_name_nonascii_backslash); + + puts ("info: en_US.UTF-8 locale tests"); + if (setlocale (LC_CTYPE, "en_US.UTF-8") == 0) + FAIL_EXIT1 ("setlocale for en_US.UTF-8: %m\n"); + locale_insensitive_tests (); + TEST_COMPARE (__idna_name_classify ("abc\xc3\x9f""def"), idna_name_nonascii); + TEST_COMPARE (__idna_name_classify ("abc\\\xc3\x9f""def"), + idna_name_nonascii_backslash); + TEST_COMPARE (__idna_name_classify ("abc\xc3\x9f\\def"), + idna_name_nonascii_backslash); + TEST_COMPARE (__idna_name_classify ("abc\200def"), idna_name_encoding_error); + TEST_COMPARE (__idna_name_classify ("abc\xc3""def"), idna_name_encoding_error); + TEST_COMPARE (__idna_name_classify ("abc\xc3"), idna_name_encoding_error); + + return 0; +} + +#include <support/test-driver.c> diff --git a/inet/tst-inet6_scopeid_pton.c b/inet/tst-inet6_scopeid_pton.c new file mode 100644 index 0000000000..61d4b24d09 --- /dev/null +++ b/inet/tst-inet6_scopeid_pton.c @@ -0,0 +1,230 @@ +/* Tests for __inet6_scopeid_pton and IPv6 scopes in getaddrinfo. + Copyright (C) 2016-2018 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, see + <http://www.gnu.org/licenses/>. */ + +#include <arpa/inet.h> +#include <inttypes.h> +#include <net-internal.h> +#include <net/if.h> +#include <netdb.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <support/check.h> +#include <support/support.h> +#include <support/test-driver.h> + +/* An interface which is known to the system. */ +static const char *interface_name; +static uint32_t interface_index; + +/* Initiale the variables above. */ +static void +setup_interface (void) +{ + struct if_nameindex *list = if_nameindex (); + if (list != NULL && list[0].if_index != 0 && list[0].if_name[0] != '\0') + { + interface_name = list[0].if_name; + interface_index = list[0].if_index; + } +} + +/* Convert ADDRESS to struct in6_addr. */ +static struct in6_addr +from_string (const char *address) +{ + struct in6_addr addr; + if (inet_pton (AF_INET6, address, &addr) != 1) + FAIL_EXIT1 ("inet_pton (\"%s\")", address); + return addr; +} + +/* Invoke getaddrinfo to parse ADDRESS%SCOPE. Return true if + getaddrinfo was successful. */ +static bool +call_gai (int family, const char *address, const char *scope, + struct sockaddr_in6 *result) +{ + struct addrinfo hints = + { + .ai_family = family, + .ai_flags = AI_NUMERICHOST, + .ai_socktype = SOCK_DGRAM, + .ai_protocol = IPPROTO_UDP, + }; + char *fulladdr = xasprintf ("%s%%%s", address, scope); + struct addrinfo *ai = NULL; + int ret = getaddrinfo (fulladdr, NULL, &hints, &ai); + if (ret == EAI_ADDRFAMILY || ret == EAI_NONAME) + { + if (test_verbose > 0) + printf ("info: getaddrinfo (\"%s\"): %s (%d)\n", + fulladdr, gai_strerror (ret), ret); + free (fulladdr); + return false; + } + if (ret != 0) + FAIL_EXIT1 ("getaddrinfo (\"%s\"): %s (%d)\n", + fulladdr, gai_strerror (ret), ret); + TEST_VERIFY_EXIT (ai != NULL); + TEST_VERIFY_EXIT (ai->ai_addrlen == sizeof (*result)); + TEST_VERIFY (ai->ai_family == AF_INET6); + TEST_VERIFY (ai->ai_next == NULL); + memcpy (result, ai->ai_addr, sizeof (*result)); + free (fulladdr); + freeaddrinfo (ai); + return true; +} + +/* Verify that a successful call to getaddrinfo returned the expected + scope data. */ +static void +check_ai (const char *what, const char *addr_string, const char *scope_string, + const struct sockaddr_in6 *sa, + const struct in6_addr *addr, uint32_t scope) +{ + if (memcmp (addr, &sa->sin6_addr, sizeof (*addr)) != 0) + { + support_record_failure (); + printf ("error: getaddrinfo %s address mismatch for %s%%%s\n", + what, addr_string, scope_string); + } + if (sa->sin6_scope_id != scope) + { + support_record_failure (); + printf ("error: getaddrinfo %s scope mismatch for %s%%%s\n" + " expected: %" PRIu32 "\n" + " actual: %" PRIu32 "\n", + what, addr_string, scope_string, scope, sa->sin6_scope_id); + } +} + +/* Check a single address were we expected a failure. */ +static void +expect_failure (const char *address, const char *scope) +{ + if (test_verbose > 0) + printf ("info: expecting failure for %s%%%s\n", address, scope); + struct in6_addr addr = from_string (address); + uint32_t result = 1234; + if (__inet6_scopeid_pton (&addr, scope, &result) == 0) + { + support_record_failure (); + printf ("error: unexpected success for %s%%%s\n", + address, scope); + } + if (result != 1234) + { + support_record_failure (); + printf ("error: unexpected result update for %s%%%s\n", + address, scope); + } + + struct sockaddr_in6 sa; + if (call_gai (AF_UNSPEC, address, scope, &sa)) + { + support_record_failure (); + printf ("error: unexpected getaddrinfo success for %s%%%s (AF_UNSPEC)\n", + address, scope); + } + if (call_gai (AF_INET6, address, scope, &sa)) + { + support_record_failure (); + printf ("error: unexpected getaddrinfo success for %s%%%s (AF_INET6)\n", + address, scope); + } +} + +/* Check a single address were we expected a success. */ +static void +expect_success (const char *address, const char *scope, uint32_t expected) +{ + if (test_verbose > 0) + printf ("info: expecting success for %s%%%s\n", address, scope); + struct in6_addr addr = from_string (address); + uint32_t actual = expected + 1; + if (__inet6_scopeid_pton (&addr, scope, &actual) != 0) + { + support_record_failure (); + printf ("error: unexpected failure for %s%%%s\n", + address, scope); + } + if (actual != expected) + { + support_record_failure (); + printf ("error: unexpected result for for %s%%%s\n", + address, scope); + printf (" expected: %" PRIu32 "\n", expected); + printf (" actual: %" PRIu32 "\n", actual); + } + + struct sockaddr_in6 sa; + memset (&sa, 0xc0, sizeof (sa)); + if (call_gai (AF_UNSPEC, address, scope, &sa)) + check_ai ("AF_UNSPEC", address, scope, &sa, &addr, expected); + else + { + support_record_failure (); + printf ("error: unexpected getaddrinfo failure for %s%%%s (AF_UNSPEC)\n", + address, scope); + } + memset (&sa, 0xc0, sizeof (sa)); + if (call_gai (AF_INET6, address, scope, &sa)) + check_ai ("AF_INET6", address, scope, &sa, &addr, expected); + else + { + support_record_failure (); + printf ("error: unexpected getaddrinfo failure for %s%%%s (AF_INET6)\n", + address, scope); + } +} + +static int +do_test (void) +{ + setup_interface (); + + static const char *test_addresses[] + = { "::", "::1", "2001:db8::1", NULL }; + for (int i = 0; test_addresses[i] != NULL; ++i) + { + expect_success (test_addresses[i], "0", 0); + expect_success (test_addresses[i], "5555", 5555); + + expect_failure (test_addresses[i], ""); + expect_failure (test_addresses[i], "-1"); + expect_failure (test_addresses[i], "-99"); + expect_failure (test_addresses[i], "037777777777"); + expect_failure (test_addresses[i], "0x"); + expect_failure (test_addresses[i], "0x1"); + } + + if (interface_name != NULL) + { + expect_success ("fe80::1", interface_name, interface_index); + expect_success ("ff02::1", interface_name, interface_index); + expect_success ("ff01::1", interface_name, interface_index); + expect_failure ("::", interface_name); + expect_failure ("::1", interface_name); + expect_failure ("2001:db8::1", interface_name); + } + + return 0; +} + +#include <support/test-driver.c> diff --git a/inet/tst-network.c b/inet/tst-network.c index e0befd7953..96eb873197 100644 --- a/inet/tst-network.c +++ b/inet/tst-network.c @@ -1,5 +1,5 @@ /* Test for inet_network. - Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2000-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Andreas Jaeger <aj@suse.de>, 2000. diff --git a/inet/tst-sockaddr.c b/inet/tst-sockaddr.c new file mode 100644 index 0000000000..8e497d9506 --- /dev/null +++ b/inet/tst-sockaddr.c @@ -0,0 +1,125 @@ +/* Tests for socket address type definitions. + Copyright (C) 2016-2018 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; see the file COPYING.LIB. If + not, see <http://www.gnu.org/licenses/>. */ + +#include <netinet/in.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/socket.h> +#include <sys/un.h> + +/* This is a copy of the previous definition of struct + sockaddr_storage. It is not equal to the old value of _SS_SIZE + (128) on all architectures. We must stay compatible with the old + definition. */ + +#define OLD_REFERENCE_SIZE 128 +#define OLD_PADSIZE (OLD_REFERENCE_SIZE - (2 * sizeof (__ss_aligntype))) +struct sockaddr_storage_old + { + __SOCKADDR_COMMON (old_); + __ss_aligntype old_align; + char old_padding[OLD_PADSIZE]; + }; + +static bool errors; + +static void +check (bool ok, const char *message) +{ + if (!ok) + { + printf ("error: failed check: %s\n", message); + errors = true; + } +} + +static int +do_test (void) +{ + check (OLD_REFERENCE_SIZE >= _SS_SIZE, + "old target size is not smaller than actual size"); + check (sizeof (struct sockaddr_storage_old) + == sizeof (struct sockaddr_storage), + "old and new sizes match"); + check (__alignof (struct sockaddr_storage_old) + == __alignof (struct sockaddr_storage), + "old and new alignment matches"); + check (offsetof (struct sockaddr_storage_old, old_family) + == offsetof (struct sockaddr_storage, ss_family), + "old and new family offsets match"); + check (sizeof (struct sockaddr_storage) == _SS_SIZE, + "struct sockaddr_storage size"); + + /* Check for lack of holes in the struct definition. */ + check (offsetof (struct sockaddr_storage, __ss_padding) + == __SOCKADDR_COMMON_SIZE, + "implicit padding before explicit padding"); + check (offsetof (struct sockaddr_storage, __ss_align) + == __SOCKADDR_COMMON_SIZE + + sizeof (((struct sockaddr_storage) {}).__ss_padding), + "implicit padding before explicit padding"); + + /* Check for POSIX compatibility requirements between struct + sockaddr_storage and struct sockaddr_un. */ + check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_un), + "sockaddr_storage is at least as large as sockaddr_un"); + check (__alignof (struct sockaddr_storage) + >= __alignof (struct sockaddr_un), + "sockaddr_storage is at least as aligned as sockaddr_un"); + check (offsetof (struct sockaddr_storage, ss_family) + == offsetof (struct sockaddr_un, sun_family), + "family offsets match"); + + /* Check that the compiler preserves bit patterns in aggregate + copies. Based on <https://gcc.gnu.org/PR71120>. */ + check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_in), + "sockaddr_storage is at least as large as sockaddr_in"); + { + struct sockaddr_storage addr; + memset (&addr, 0, sizeof (addr)); + { + struct sockaddr_in *sinp = (struct sockaddr_in *)&addr; + sinp->sin_family = AF_INET; + sinp->sin_addr.s_addr = htonl (INADDR_LOOPBACK); + sinp->sin_port = htons (80); + } + struct sockaddr_storage copy; + copy = addr; + + struct sockaddr_storage *p = malloc (sizeof (*p)); + if (p == NULL) + { + printf ("error: malloc: %m\n"); + return 1; + } + *p = copy; + const struct sockaddr_in *sinp = (const struct sockaddr_in *)p; + check (sinp->sin_family == AF_INET, "sin_family"); + check (sinp->sin_addr.s_addr == htonl (INADDR_LOOPBACK), "sin_addr"); + check (sinp->sin_port == htons (80), "sin_port"); + free (p); + } + + return errors; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" |