tags 630206 patch thanks 2011/6/13 Robert Millan <r...@debian.org>: > 2011/6/13 Lennart Poettering <lenn...@poettering.net>: >> I think it is a major waste of time thinking about BSD and Hurd. >> >> That said, I'd be willing to merge a patch that adds support for those >> legacy systems -- if it is minimal. Note however that it wouldn't be >> release critical to me, i.e. I will not care if it works or not when >> releasing a new version. But I geuss that doesn't matter much since it >> is quite a finished project and I expect very few updates in the future. > > Seems simple enough, I'll give it a try.
Patch attached. To be applied after "mv netlink.h ifconf.h". -- Robert Millan
diff -Nur -x aclocal.m4 -x configure -x doc libnss-myhostname-0.3/ifconf.c libnss-myhostname-0.3.new/ifconf.c --- libnss-myhostname-0.3/ifconf.c 1970-01-01 01:00:00.000000000 +0100 +++ libnss-myhostname-0.3.new/ifconf.c 2011-06-13 14:06:34.000000000 +0200 @@ -0,0 +1,5 @@ +#ifdef __linux__ +#include "netlink.c" +#else +#include "legacy.c" +#endif diff -Nur -x aclocal.m4 -x configure -x doc libnss-myhostname-0.3/ifconf.h libnss-myhostname-0.3.new/ifconf.h --- libnss-myhostname-0.3/ifconf.h 2011-05-09 15:00:58.000000000 +0200 +++ libnss-myhostname-0.3.new/ifconf.h 2011-06-13 14:01:28.000000000 +0200 @@ -3,6 +3,8 @@ #ifndef foonetlinkhfoo #define foonetlinkhfoo +#include <sys/socket.h> + /*** This file is part of nss-myhostname. @@ -37,7 +39,7 @@ #define _public_ __attribute__ ((visibility("default"))) #define _hidden_ __attribute__ ((visibility("hidden"))) -int netlink_acquire_addresses(struct address **_list, unsigned *_n_list) _hidden_; +int ifconf_acquire_addresses(struct address **_list, unsigned *_n_list) _hidden_; static inline size_t PROTO_ADDRESS_SIZE(int proto) { assert(proto == AF_INET || proto == AF_INET6); @@ -45,4 +47,28 @@ return proto == AF_INET6 ? 16 : 4; } +static inline int address_compare(const void *_a, const void *_b) { + const struct address *a = _a, *b = _b; + + /* Order lowest scope first, IPv4 before IPv6, lowest interface index first */ + + if (a->scope < b->scope) + return -1; + if (a->scope > b->scope) + return 1; + + if (a->family == AF_INET && b->family == AF_INET6) + return -1; + if (a->family == AF_INET6 && b->family == AF_INET) + return 1; + + if (a->ifindex < b->ifindex) + return -1; + if (a->ifindex > b->ifindex) + return 1; + + return 0; +} + + #endif diff -Nur -x aclocal.m4 -x configure -x doc libnss-myhostname-0.3/legacy.c libnss-myhostname-0.3.new/legacy.c --- libnss-myhostname-0.3/legacy.c 1970-01-01 01:00:00.000000000 +0100 +++ libnss-myhostname-0.3.new/legacy.c 2011-06-13 14:06:18.000000000 +0200 @@ -0,0 +1,116 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/*** + This file is part of nss-myhostname. + + Copyright 2008-2011 Lennart Poettering + Copyright 2011 Robert millan + + nss-myhostname 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. + + nss-myhostname 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 nss-myhostname; If not, see + <http://www.gnu.org/licenses/>. +***/ + +#include <sys/socket.h> +#include <sys/un.h> +#include <sys/ioctl.h> +#include <net/if.h> +#include <netinet/in.h> +#include <inttypes.h> +#include <string.h> +#include <assert.h> +#include <errno.h> +#include <limits.h> +#include <arpa/inet.h> +#include <unistd.h> +#include <inttypes.h> +#include <stdlib.h> + +#include "ifconf.h" + +int ifconf_acquire_addresses(struct address **_list, unsigned *_n_list) { + + struct address *list = NULL; + unsigned n_list = 0; + + struct ifconf ifc; + int fd, r = 1, want; + unsigned int i; + + fd = socket (AF_INET6, SOCK_DGRAM, 0); + + want = sizeof (struct ifreq); + ifc.ifc_req = NULL; + + do { + want *= 2; + + ifc.ifc_req = realloc (ifc.ifc_req, want); + if (! ifc.ifc_req) { + r = -errno; + goto finish; + } + + ifc.ifc_len = want; + + if (ioctl (fd, SIOCGIFCONF, &ifc) == -1) { + r = -errno; + goto finish; + } + } while (want == ifc.ifc_len); + + for (i = 0; i < ifc.ifc_len / sizeof (struct ifreq); i++) { + int af = ifc.ifc_req[i].ifr_addr.sa_family; + const void *cp; + + struct sockaddr_in6 *in6 = (void *) &ifc.ifc_req[i].ifr_addr; + struct sockaddr_in *in = (void *) &ifc.ifc_req[i].ifr_addr; + + if (af != AF_INET && af != AF_INET6) + continue; + + list = realloc(list, (n_list+1) * sizeof(struct address)); + if (!list) { + r = -ENOMEM; + goto finish; + } + + if (af == AF_INET6) + cp = &in6->sin6_addr; + else + cp = &in->sin_addr; + + list[n_list].family = af; + list[n_list].scope = 0; + memcpy (list[n_list].address, cp, af == AF_INET ? 4 : 16); + list[n_list].ifindex = i; + n_list++; + } + +finish: + if (ifc.ifc_req) + free (ifc.ifc_req); + + close(fd); + + if (r < 0) + free(list); + else { + qsort(list, n_list, sizeof(struct address), address_compare); + + *_list = list; + *_n_list = n_list; + } + + return r; +} diff -Nur -x aclocal.m4 -x configure -x doc libnss-myhostname-0.3/Makefile.am libnss-myhostname-0.3.new/Makefile.am --- libnss-myhostname-0.3/Makefile.am 2011-05-06 16:27:54.000000000 +0200 +++ libnss-myhostname-0.3.new/Makefile.am 2011-06-13 14:02:40.000000000 +0200 @@ -43,8 +43,8 @@ libnss_myhostname_la_SOURCES = \ nss-myhostname.c \ - netlink.c \ - netlink.h + ifconf.c \ + ifconf.h libnss_myhostname_la_LDFLAGS = \ -avoid-version \ diff -Nur -x aclocal.m4 -x configure -x doc libnss-myhostname-0.3/netlink.c libnss-myhostname-0.3.new/netlink.c --- libnss-myhostname-0.3/netlink.c 2011-05-09 14:56:34.000000000 +0200 +++ libnss-myhostname-0.3.new/netlink.c 2011-06-13 14:04:09.000000000 +0200 @@ -35,32 +35,9 @@ #include <inttypes.h> #include <stdlib.h> -#include "netlink.h" +#include "ifconf.h" -static int address_compare(const void *_a, const void *_b) { - const struct address *a = _a, *b = _b; - - /* Order lowest scope first, IPv4 before IPv6, lowest interface index first */ - - if (a->scope < b->scope) - return -1; - if (a->scope > b->scope) - return 1; - - if (a->family == AF_INET && b->family == AF_INET6) - return -1; - if (a->family == AF_INET6 && b->family == AF_INET) - return 1; - - if (a->ifindex < b->ifindex) - return -1; - if (a->ifindex > b->ifindex) - return 1; - - return 0; -} - -int netlink_acquire_addresses(struct address **_list, unsigned *_n_list) { +int ifconf_acquire_addresses(struct address **_list, unsigned *_n_list) { struct { struct nlmsghdr hdr; diff -Nur -x aclocal.m4 -x configure -x doc libnss-myhostname-0.3/nss-myhostname.c libnss-myhostname-0.3.new/nss-myhostname.c --- libnss-myhostname-0.3/nss-myhostname.c 2011-06-13 14:06:58.000000000 +0200 +++ libnss-myhostname-0.3.new/nss-myhostname.c 2011-06-13 14:02:26.000000000 +0200 @@ -32,7 +32,7 @@ #include <stdlib.h> #include <arpa/inet.h> -#include "netlink.h" +#include "ifconf.h" /* We use 127.0.0.2 as IPv4 address. This has the advantage over * 127.0.0.1 that it can be translated back to the local hostname. For @@ -120,7 +120,7 @@ } /* If this fails, n_addresses is 0. Which is fine */ - netlink_acquire_addresses(&addresses, &n_addresses); + ifconf_acquire_addresses(&addresses, &n_addresses); /* If this call fails we fill in 0 as scope. Which is fine */ lo_ifi = if_nametoindex(LOOPBACK_INTERFACE); @@ -206,7 +206,7 @@ alen = PROTO_ADDRESS_SIZE(af); - netlink_acquire_addresses(&addresses, &n_addresses); + ifconf_acquire_addresses(&addresses, &n_addresses); for (a = addresses, n = 0, c = 0; n < n_addresses; a++, n++) if (af == a->family) @@ -405,7 +405,7 @@ return NSS_STATUS_UNAVAIL; } - netlink_acquire_addresses(&addresses, &n_addresses); + ifconf_acquire_addresses(&addresses, &n_addresses); for (a = addresses, n = 0; n < n_addresses; n++, a++) { if (af != a->family)