LCOV - code coverage report
Current view: top level - nss-myhostname - nss-myhostname.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 272 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 7 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 182 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <net/if.h>
       5                 :            : #include <netdb.h>
       6                 :            : #include <nss.h>
       7                 :            : #include <stdlib.h>
       8                 :            : #include <string.h>
       9                 :            : 
      10                 :            : #include "alloc-util.h"
      11                 :            : #include "errno-util.h"
      12                 :            : #include "hostname-util.h"
      13                 :            : #include "local-addresses.h"
      14                 :            : #include "macro.h"
      15                 :            : #include "nss-util.h"
      16                 :            : #include "signal-util.h"
      17                 :            : #include "string-util.h"
      18                 :            : 
      19                 :            : /* We use 127.0.0.2 as IPv4 address. This has the advantage over
      20                 :            :  * 127.0.0.1 that it can be translated back to the local hostname. For
      21                 :            :  * IPv6 we use ::1 which unfortunately will not translate back to the
      22                 :            :  * hostname but instead something like "localhost" or so. */
      23                 :            : 
      24                 :            : #define LOCALADDRESS_IPV4 (htobe32(0x7F000002))
      25                 :            : #define LOCALADDRESS_IPV6 &in6addr_loopback
      26                 :            : 
      27                 :            : NSS_GETHOSTBYNAME_PROTOTYPES(myhostname);
      28                 :            : NSS_GETHOSTBYADDR_PROTOTYPES(myhostname);
      29                 :            : 
      30                 :          0 : enum nss_status _nss_myhostname_gethostbyname4_r(
      31                 :            :                 const char *name,
      32                 :            :                 struct gaih_addrtuple **pat,
      33                 :            :                 char *buffer, size_t buflen,
      34                 :            :                 int *errnop, int *h_errnop,
      35                 :            :                 int32_t *ttlp) {
      36                 :            : 
      37                 :          0 :         struct gaih_addrtuple *r_tuple, *r_tuple_prev = NULL;
      38                 :          0 :         _cleanup_free_ struct local_address *addresses = NULL;
      39                 :          0 :         _cleanup_free_ char *hn = NULL;
      40                 :          0 :         const char *canonical = NULL;
      41                 :          0 :         int n_addresses = 0;
      42                 :            :         uint32_t local_address_ipv4;
      43                 :            :         struct local_address *a;
      44                 :            :         size_t l, idx, ms;
      45                 :            :         char *r_name;
      46                 :            :         unsigned n;
      47                 :            : 
      48                 :          0 :         PROTECT_ERRNO;
      49         [ #  # ]:          0 :         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
      50                 :            : 
      51         [ #  # ]:          0 :         assert(name);
      52         [ #  # ]:          0 :         assert(pat);
      53         [ #  # ]:          0 :         assert(buffer);
      54         [ #  # ]:          0 :         assert(errnop);
      55         [ #  # ]:          0 :         assert(h_errnop);
      56                 :            : 
      57         [ #  # ]:          0 :         if (is_localhost(name)) {
      58                 :            :                 /* We respond to 'localhost', so that /etc/hosts
      59                 :            :                  * is optional */
      60                 :            : 
      61                 :          0 :                 canonical = "localhost";
      62                 :          0 :                 local_address_ipv4 = htobe32(INADDR_LOOPBACK);
      63                 :            : 
      64         [ #  # ]:          0 :         } else if (is_gateway_hostname(name)) {
      65                 :            : 
      66                 :          0 :                 n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
      67         [ #  # ]:          0 :                 if (n_addresses <= 0)
      68                 :          0 :                         goto not_found;
      69                 :            : 
      70                 :          0 :                 canonical = "_gateway";
      71                 :            : 
      72                 :            :         } else {
      73                 :          0 :                 hn = gethostname_malloc();
      74         [ #  # ]:          0 :                 if (!hn) {
      75                 :          0 :                         UNPROTECT_ERRNO;
      76                 :          0 :                         *errnop = ENOMEM;
      77                 :          0 :                         *h_errnop = NO_RECOVERY;
      78                 :          0 :                         return NSS_STATUS_TRYAGAIN;
      79                 :            :                 }
      80                 :            : 
      81                 :            :                 /* We respond to our local host name, our hostname suffixed with a single dot. */
      82   [ #  #  #  # ]:          0 :                 if (!streq(name, hn) && !streq_ptr(startswith(name, hn), "."))
      83                 :          0 :                         goto not_found;
      84                 :            : 
      85                 :          0 :                 n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
      86         [ #  # ]:          0 :                 if (n_addresses < 0)
      87                 :          0 :                         n_addresses = 0;
      88                 :            : 
      89                 :          0 :                 canonical = hn;
      90                 :          0 :                 local_address_ipv4 = LOCALADDRESS_IPV4;
      91                 :            :         }
      92                 :            : 
      93                 :          0 :         l = strlen(canonical);
      94         [ #  # ]:          0 :         ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2);
      95         [ #  # ]:          0 :         if (buflen < ms) {
      96                 :          0 :                 UNPROTECT_ERRNO;
      97                 :          0 :                 *errnop = ERANGE;
      98                 :          0 :                 *h_errnop = NETDB_INTERNAL;
      99                 :          0 :                 return NSS_STATUS_TRYAGAIN;
     100                 :            :         }
     101                 :            : 
     102                 :            :         /* First, fill in hostname */
     103                 :          0 :         r_name = buffer;
     104                 :          0 :         memcpy(r_name, canonical, l+1);
     105                 :          0 :         idx = ALIGN(l+1);
     106                 :            : 
     107         [ #  # ]:          0 :         assert(n_addresses >= 0);
     108         [ #  # ]:          0 :         if (n_addresses == 0) {
     109                 :            :                 /* Second, fill in IPv6 tuple */
     110                 :          0 :                 r_tuple = (struct gaih_addrtuple*) (buffer + idx);
     111                 :          0 :                 r_tuple->next = r_tuple_prev;
     112                 :          0 :                 r_tuple->name = r_name;
     113                 :          0 :                 r_tuple->family = AF_INET6;
     114                 :          0 :                 memcpy(r_tuple->addr, LOCALADDRESS_IPV6, 16);
     115                 :          0 :                 r_tuple->scopeid = 0;
     116                 :            : 
     117                 :          0 :                 idx += ALIGN(sizeof(struct gaih_addrtuple));
     118                 :          0 :                 r_tuple_prev = r_tuple;
     119                 :            : 
     120                 :            :                 /* Third, fill in IPv4 tuple */
     121                 :          0 :                 r_tuple = (struct gaih_addrtuple*) (buffer + idx);
     122                 :          0 :                 r_tuple->next = r_tuple_prev;
     123                 :          0 :                 r_tuple->name = r_name;
     124                 :          0 :                 r_tuple->family = AF_INET;
     125                 :          0 :                 *(uint32_t*) r_tuple->addr = local_address_ipv4;
     126                 :          0 :                 r_tuple->scopeid = 0;
     127                 :            : 
     128                 :          0 :                 idx += ALIGN(sizeof(struct gaih_addrtuple));
     129                 :          0 :                 r_tuple_prev = r_tuple;
     130                 :            :         }
     131                 :            : 
     132                 :            :         /* Fourth, fill actual addresses in, but in backwards order */
     133         [ #  # ]:          0 :         for (a = addresses + n_addresses - 1, n = 0; (int) n < n_addresses; n++, a--) {
     134                 :          0 :                 r_tuple = (struct gaih_addrtuple*) (buffer + idx);
     135                 :          0 :                 r_tuple->next = r_tuple_prev;
     136                 :          0 :                 r_tuple->name = r_name;
     137                 :          0 :                 r_tuple->family = a->family;
     138   [ #  #  #  # ]:          0 :                 r_tuple->scopeid = a->family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&a->address.in6) ? a->ifindex : 0;
     139                 :          0 :                 memcpy(r_tuple->addr, &a->address, 16);
     140                 :            : 
     141                 :          0 :                 idx += ALIGN(sizeof(struct gaih_addrtuple));
     142                 :          0 :                 r_tuple_prev = r_tuple;
     143                 :            :         }
     144                 :            : 
     145                 :            :         /* Verify the size matches */
     146         [ #  # ]:          0 :         assert(idx == ms);
     147                 :            : 
     148                 :            :         /* Nscd expects us to store the first record in **pat. */
     149         [ #  # ]:          0 :         if (*pat)
     150                 :          0 :                 **pat = *r_tuple_prev;
     151                 :            :         else
     152                 :          0 :                 *pat = r_tuple_prev;
     153                 :            : 
     154         [ #  # ]:          0 :         if (ttlp)
     155                 :          0 :                 *ttlp = 0;
     156                 :            : 
     157                 :            :         /* Explicitly reset both *h_errnop and h_errno to work around
     158                 :            :          * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
     159                 :          0 :         *h_errnop = NETDB_SUCCESS;
     160                 :          0 :         h_errno = 0;
     161                 :            : 
     162                 :          0 :         return NSS_STATUS_SUCCESS;
     163                 :            : 
     164                 :          0 : not_found:
     165                 :          0 :         *h_errnop = HOST_NOT_FOUND;
     166                 :          0 :         return NSS_STATUS_NOTFOUND;
     167                 :            : }
     168                 :            : 
     169                 :          0 : static enum nss_status fill_in_hostent(
     170                 :            :                 const char *canonical, const char *additional,
     171                 :            :                 int af,
     172                 :            :                 struct local_address *addresses, unsigned n_addresses,
     173                 :            :                 uint32_t local_address_ipv4,
     174                 :            :                 struct hostent *result,
     175                 :            :                 char *buffer, size_t buflen,
     176                 :            :                 int *errnop, int *h_errnop,
     177                 :            :                 int32_t *ttlp,
     178                 :            :                 char **canonp) {
     179                 :            : 
     180                 :            :         size_t l_canonical, l_additional, idx, ms, alen;
     181                 :          0 :         char *r_addr, *r_name, *r_aliases, *r_alias = NULL, *r_addr_list;
     182                 :            :         struct local_address *a;
     183                 :            :         unsigned n, c;
     184                 :            : 
     185         [ #  # ]:          0 :         assert(canonical);
     186         [ #  # ]:          0 :         assert(result);
     187         [ #  # ]:          0 :         assert(buffer);
     188         [ #  # ]:          0 :         assert(errnop);
     189         [ #  # ]:          0 :         assert(h_errnop);
     190                 :            : 
     191                 :          0 :         PROTECT_ERRNO;
     192                 :            : 
     193                 :          0 :         alen = FAMILY_ADDRESS_SIZE(af);
     194                 :            : 
     195         [ #  # ]:          0 :         for (a = addresses, n = 0, c = 0; n < n_addresses; a++, n++)
     196         [ #  # ]:          0 :                 if (af == a->family)
     197                 :          0 :                         c++;
     198                 :            : 
     199                 :          0 :         l_canonical = strlen(canonical);
     200                 :          0 :         l_additional = strlen_ptr(additional);
     201                 :          0 :         ms = ALIGN(l_canonical+1)+
     202         [ #  # ]:          0 :                 (additional ? ALIGN(l_additional+1) : 0) +
     203                 :          0 :                 sizeof(char*) +
     204         [ #  # ]:          0 :                 (additional ? sizeof(char*) : 0) +
     205         [ #  # ]:          0 :                 (c > 0 ? c : 1) * ALIGN(alen) +
     206         [ #  # ]:          0 :                 (c > 0 ? c+1 : 2) * sizeof(char*);
     207                 :            : 
     208         [ #  # ]:          0 :         if (buflen < ms) {
     209                 :          0 :                 UNPROTECT_ERRNO;
     210                 :          0 :                 *errnop = ERANGE;
     211                 :          0 :                 *h_errnop = NETDB_INTERNAL;
     212                 :          0 :                 return NSS_STATUS_TRYAGAIN;
     213                 :            :         }
     214                 :            : 
     215                 :            :         /* First, fill in hostnames */
     216                 :          0 :         r_name = buffer;
     217                 :          0 :         memcpy(r_name, canonical, l_canonical+1);
     218                 :          0 :         idx = ALIGN(l_canonical+1);
     219                 :            : 
     220         [ #  # ]:          0 :         if (additional) {
     221                 :          0 :                 r_alias = buffer + idx;
     222                 :          0 :                 memcpy(r_alias, additional, l_additional+1);
     223                 :          0 :                 idx += ALIGN(l_additional+1);
     224                 :            :         }
     225                 :            : 
     226                 :            :         /* Second, create aliases array */
     227                 :          0 :         r_aliases = buffer + idx;
     228         [ #  # ]:          0 :         if (additional) {
     229                 :          0 :                 ((char**) r_aliases)[0] = r_alias;
     230                 :          0 :                 ((char**) r_aliases)[1] = NULL;
     231                 :          0 :                 idx += 2*sizeof(char*);
     232                 :            :         } else {
     233                 :          0 :                 ((char**) r_aliases)[0] = NULL;
     234                 :          0 :                 idx += sizeof(char*);
     235                 :            :         }
     236                 :            : 
     237                 :            :         /* Third, add addresses */
     238                 :          0 :         r_addr = buffer + idx;
     239         [ #  # ]:          0 :         if (c > 0) {
     240                 :          0 :                 unsigned i = 0;
     241                 :            : 
     242         [ #  # ]:          0 :                 for (a = addresses, n = 0; n < n_addresses; a++, n++) {
     243         [ #  # ]:          0 :                         if (af != a->family)
     244                 :          0 :                                 continue;
     245                 :            : 
     246                 :          0 :                         memcpy(r_addr + i*ALIGN(alen), &a->address, alen);
     247                 :          0 :                         i++;
     248                 :            :                 }
     249                 :            : 
     250         [ #  # ]:          0 :                 assert(i == c);
     251                 :          0 :                 idx += c*ALIGN(alen);
     252                 :            :         } else {
     253         [ #  # ]:          0 :                 if (af == AF_INET)
     254                 :          0 :                         *(uint32_t*) r_addr = local_address_ipv4;
     255                 :            :                 else
     256                 :          0 :                         memcpy(r_addr, LOCALADDRESS_IPV6, 16);
     257                 :            : 
     258                 :          0 :                 idx += ALIGN(alen);
     259                 :            :         }
     260                 :            : 
     261                 :            :         /* Fourth, add address pointer array */
     262                 :          0 :         r_addr_list = buffer + idx;
     263         [ #  # ]:          0 :         if (c > 0) {
     264                 :            :                 unsigned i;
     265                 :            : 
     266         [ #  # ]:          0 :                 for (i = 0; i < c; i++)
     267                 :          0 :                         ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen);
     268                 :            : 
     269                 :          0 :                 ((char**) r_addr_list)[i] = NULL;
     270                 :          0 :                 idx += (c+1) * sizeof(char*);
     271                 :            : 
     272                 :            :         } else {
     273                 :          0 :                 ((char**) r_addr_list)[0] = r_addr;
     274                 :          0 :                 ((char**) r_addr_list)[1] = NULL;
     275                 :          0 :                 idx += 2 * sizeof(char*);
     276                 :            :         }
     277                 :            : 
     278                 :            :         /* Verify the size matches */
     279         [ #  # ]:          0 :         assert(idx == ms);
     280                 :            : 
     281                 :          0 :         result->h_name = r_name;
     282                 :          0 :         result->h_aliases = (char**) r_aliases;
     283                 :          0 :         result->h_addrtype = af;
     284                 :          0 :         result->h_length = alen;
     285                 :          0 :         result->h_addr_list = (char**) r_addr_list;
     286                 :            : 
     287         [ #  # ]:          0 :         if (ttlp)
     288                 :          0 :                 *ttlp = 0;
     289                 :            : 
     290         [ #  # ]:          0 :         if (canonp)
     291                 :          0 :                 *canonp = r_name;
     292                 :            : 
     293                 :            :         /* Explicitly reset both *h_errnop and h_errno to work around
     294                 :            :          * https://bugzilla.redhat.com/show_bug.cgi?id=1125975 */
     295                 :          0 :         *h_errnop = NETDB_SUCCESS;
     296                 :          0 :         h_errno = 0;
     297                 :            : 
     298                 :          0 :         return NSS_STATUS_SUCCESS;
     299                 :            : }
     300                 :            : 
     301                 :          0 : enum nss_status _nss_myhostname_gethostbyname3_r(
     302                 :            :                 const char *name,
     303                 :            :                 int af,
     304                 :            :                 struct hostent *host,
     305                 :            :                 char *buffer, size_t buflen,
     306                 :            :                 int *errnop, int *h_errnop,
     307                 :            :                 int32_t *ttlp,
     308                 :            :                 char **canonp) {
     309                 :            : 
     310                 :          0 :         _cleanup_free_ struct local_address *addresses = NULL;
     311                 :          0 :         const char *canonical, *additional = NULL;
     312                 :          0 :         _cleanup_free_ char *hn = NULL;
     313                 :          0 :         uint32_t local_address_ipv4 = 0;
     314                 :          0 :         int n_addresses = 0;
     315                 :            : 
     316                 :          0 :         PROTECT_ERRNO;
     317         [ #  # ]:          0 :         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
     318                 :            : 
     319         [ #  # ]:          0 :         assert(name);
     320         [ #  # ]:          0 :         assert(host);
     321         [ #  # ]:          0 :         assert(buffer);
     322         [ #  # ]:          0 :         assert(errnop);
     323         [ #  # ]:          0 :         assert(h_errnop);
     324                 :            : 
     325         [ #  # ]:          0 :         if (af == AF_UNSPEC)
     326                 :          0 :                 af = AF_INET;
     327                 :            : 
     328   [ #  #  #  # ]:          0 :         if (!IN_SET(af, AF_INET, AF_INET6)) {
     329                 :          0 :                 UNPROTECT_ERRNO;
     330                 :          0 :                 *errnop = EAFNOSUPPORT;
     331                 :          0 :                 *h_errnop = NO_DATA;
     332                 :          0 :                 return NSS_STATUS_UNAVAIL;
     333                 :            :         }
     334                 :            : 
     335         [ #  # ]:          0 :         if (is_localhost(name)) {
     336                 :          0 :                 canonical = "localhost";
     337                 :          0 :                 local_address_ipv4 = htobe32(INADDR_LOOPBACK);
     338                 :            : 
     339         [ #  # ]:          0 :         } else if (is_gateway_hostname(name)) {
     340                 :            : 
     341                 :          0 :                 n_addresses = local_gateways(NULL, 0, af, &addresses);
     342         [ #  # ]:          0 :                 if (n_addresses <= 0)
     343                 :          0 :                         goto not_found;
     344                 :            : 
     345                 :          0 :                 canonical = "_gateway";
     346                 :            : 
     347                 :            :         } else {
     348                 :          0 :                 hn = gethostname_malloc();
     349         [ #  # ]:          0 :                 if (!hn) {
     350                 :          0 :                         UNPROTECT_ERRNO;
     351                 :          0 :                         *errnop = ENOMEM;
     352                 :          0 :                         *h_errnop = NO_RECOVERY;
     353                 :          0 :                         return NSS_STATUS_TRYAGAIN;
     354                 :            :                 }
     355                 :            : 
     356   [ #  #  #  # ]:          0 :                 if (!streq(name, hn) && !streq_ptr(startswith(name, hn), "."))
     357                 :          0 :                         goto not_found;
     358                 :            : 
     359                 :          0 :                 n_addresses = local_addresses(NULL, 0, af, &addresses);
     360         [ #  # ]:          0 :                 if (n_addresses < 0)
     361                 :          0 :                         n_addresses = 0;
     362                 :            : 
     363                 :          0 :                 canonical = hn;
     364   [ #  #  #  # ]:          0 :                 additional = n_addresses <= 0 && af == AF_INET6 ? "localhost" : NULL;
     365                 :          0 :                 local_address_ipv4 = LOCALADDRESS_IPV4;
     366                 :            :         }
     367                 :            : 
     368                 :          0 :         UNPROTECT_ERRNO;
     369                 :            : 
     370                 :          0 :         return fill_in_hostent(
     371                 :            :                         canonical, additional,
     372                 :            :                         af,
     373                 :            :                         addresses, n_addresses,
     374                 :            :                         local_address_ipv4,
     375                 :            :                         host,
     376                 :            :                         buffer, buflen,
     377                 :            :                         errnop, h_errnop,
     378                 :            :                         ttlp,
     379                 :            :                         canonp);
     380                 :            : 
     381                 :          0 : not_found:
     382                 :          0 :         *h_errnop = HOST_NOT_FOUND;
     383                 :          0 :         return NSS_STATUS_NOTFOUND;
     384                 :            : }
     385                 :            : 
     386                 :          0 : enum nss_status _nss_myhostname_gethostbyaddr2_r(
     387                 :            :                 const void* addr, socklen_t len,
     388                 :            :                 int af,
     389                 :            :                 struct hostent *host,
     390                 :            :                 char *buffer, size_t buflen,
     391                 :            :                 int *errnop, int *h_errnop,
     392                 :            :                 int32_t *ttlp) {
     393                 :            : 
     394                 :          0 :         const char *canonical = NULL, *additional = NULL;
     395                 :          0 :         uint32_t local_address_ipv4 = LOCALADDRESS_IPV4;
     396                 :          0 :         _cleanup_free_ struct local_address *addresses = NULL;
     397                 :          0 :         _cleanup_free_ char *hn = NULL;
     398                 :          0 :         int n_addresses = 0;
     399                 :            :         struct local_address *a;
     400                 :          0 :         bool additional_from_hostname = false;
     401                 :            :         unsigned n;
     402                 :            : 
     403                 :          0 :         PROTECT_ERRNO;
     404         [ #  # ]:          0 :         BLOCK_SIGNALS(NSS_SIGNALS_BLOCK);
     405                 :            : 
     406         [ #  # ]:          0 :         assert(addr);
     407         [ #  # ]:          0 :         assert(host);
     408         [ #  # ]:          0 :         assert(buffer);
     409         [ #  # ]:          0 :         assert(errnop);
     410         [ #  # ]:          0 :         assert(h_errnop);
     411                 :            : 
     412   [ #  #  #  # ]:          0 :         if (!IN_SET(af, AF_INET, AF_INET6)) {
     413                 :          0 :                 UNPROTECT_ERRNO;
     414                 :          0 :                 *errnop = EAFNOSUPPORT;
     415                 :          0 :                 *h_errnop = NO_DATA;
     416                 :          0 :                 return NSS_STATUS_UNAVAIL;
     417                 :            :         }
     418                 :            : 
     419         [ #  # ]:          0 :         if (len != FAMILY_ADDRESS_SIZE(af)) {
     420                 :          0 :                 UNPROTECT_ERRNO;
     421                 :          0 :                 *errnop = EINVAL;
     422                 :          0 :                 *h_errnop = NO_RECOVERY;
     423                 :          0 :                 return NSS_STATUS_UNAVAIL;
     424                 :            :         }
     425                 :            : 
     426         [ #  # ]:          0 :         if (af == AF_INET) {
     427         [ #  # ]:          0 :                 if ((*(uint32_t*) addr) == LOCALADDRESS_IPV4)
     428                 :          0 :                         goto found;
     429                 :            : 
     430         [ #  # ]:          0 :                 if ((*(uint32_t*) addr) == htobe32(INADDR_LOOPBACK)) {
     431                 :          0 :                         canonical = "localhost";
     432                 :          0 :                         local_address_ipv4 = htobe32(INADDR_LOOPBACK);
     433                 :          0 :                         goto found;
     434                 :            :                 }
     435                 :            : 
     436                 :            :         } else {
     437         [ #  # ]:          0 :                 assert(af == AF_INET6);
     438                 :            : 
     439         [ #  # ]:          0 :                 if (memcmp(addr, LOCALADDRESS_IPV6, 16) == 0) {
     440                 :          0 :                         canonical = "localhost";
     441                 :          0 :                         additional_from_hostname = true;
     442                 :          0 :                         goto found;
     443                 :            :                 }
     444                 :            :         }
     445                 :            : 
     446                 :          0 :         n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses);
     447         [ #  # ]:          0 :         for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
     448         [ #  # ]:          0 :                 if (af != a->family)
     449                 :          0 :                         continue;
     450                 :            : 
     451         [ #  # ]:          0 :                 if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0)
     452                 :          0 :                         goto found;
     453                 :            :         }
     454                 :            : 
     455                 :          0 :         addresses = mfree(addresses);
     456                 :            : 
     457                 :          0 :         n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses);
     458         [ #  # ]:          0 :         for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
     459         [ #  # ]:          0 :                 if (af != a->family)
     460                 :          0 :                         continue;
     461                 :            : 
     462         [ #  # ]:          0 :                 if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0) {
     463                 :          0 :                         canonical = "_gateway";
     464                 :          0 :                         goto found;
     465                 :            :                 }
     466                 :            :         }
     467                 :            : 
     468                 :          0 :         *h_errnop = HOST_NOT_FOUND;
     469                 :          0 :         return NSS_STATUS_NOTFOUND;
     470                 :            : 
     471                 :          0 : found:
     472   [ #  #  #  # ]:          0 :         if (!canonical || additional_from_hostname) {
     473                 :          0 :                 hn = gethostname_malloc();
     474         [ #  # ]:          0 :                 if (!hn) {
     475                 :          0 :                         UNPROTECT_ERRNO;
     476                 :          0 :                         *errnop = ENOMEM;
     477                 :          0 :                         *h_errnop = NO_RECOVERY;
     478                 :          0 :                         return NSS_STATUS_TRYAGAIN;
     479                 :            :                 }
     480                 :            : 
     481         [ #  # ]:          0 :                 if (!canonical)
     482                 :          0 :                         canonical = hn;
     483                 :            :                 else
     484                 :          0 :                         additional = hn;
     485                 :            :         }
     486                 :            : 
     487                 :          0 :         UNPROTECT_ERRNO;
     488                 :          0 :         return fill_in_hostent(
     489                 :            :                         canonical, additional,
     490                 :            :                         af,
     491                 :            :                         addresses, n_addresses,
     492                 :            :                         local_address_ipv4,
     493                 :            :                         host,
     494                 :            :                         buffer, buflen,
     495                 :            :                         errnop, h_errnop,
     496                 :            :                         ttlp,
     497                 :            :                         NULL);
     498                 :            : }
     499                 :            : 
     500   [ #  #  #  # ]:          0 : NSS_GETHOSTBYNAME_FALLBACKS(myhostname);
     501                 :          0 : NSS_GETHOSTBYADDR_FALLBACKS(myhostname);

Generated by: LCOV version 1.14