(root)/
glibc-2.38/
nss/
test-netdb.c
       1  /* Copyright (C) 1998-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  /*
      19    Testing of some network related lookup functions.
      20    The system databases looked up are:
      21    - /etc/services
      22    - /etc/hosts
      23    - /etc/networks
      24    - /etc/protocols
      25    The tests try to be fairly generic and simple so that they work on
      26    every possible setup (and might therefore not detect some possible
      27    errors).
      28  */
      29  
      30  #include <netdb.h>
      31  #include <stdio.h>
      32  #include <stdlib.h>
      33  #include <string.h>
      34  #include <arpa/inet.h>
      35  #include <netinet/in.h>
      36  #include <sys/param.h>
      37  #include <sys/socket.h>
      38  #include <unistd.h>
      39  #include <errno.h>
      40  #include "nss.h"
      41  
      42  #include <support/support.h>
      43  
      44  /*
      45    The following define is necessary for glibc 2.0.6
      46  */
      47  #ifndef INET6_ADDRSTRLEN
      48  # define INET6_ADDRSTRLEN 46
      49  #endif
      50  
      51  int error_count;
      52  
      53  static void
      54  output_servent (const char *call, struct servent *sptr)
      55  {
      56    char **pptr;
      57  
      58    if (sptr == NULL)
      59      printf ("Call: %s returned NULL\n", call);
      60    else
      61      {
      62        printf ("Call: %s, returned: s_name: %s, s_port: %d, s_proto: %s\n",
      63  	      call, sptr->s_name, ntohs(sptr->s_port), sptr->s_proto);
      64        for (pptr = sptr->s_aliases; *pptr != NULL; pptr++)
      65  	printf ("  alias: %s\n", *pptr);
      66      }
      67  }
      68  
      69  
      70  static void
      71  test_services (void)
      72  {
      73    struct servent *sptr;
      74  
      75    sptr = getservbyname ("domain", "tcp");
      76    output_servent ("getservbyname (\"domain\", \"tcp\")", sptr);
      77  
      78    sptr = getservbyname ("domain", "udp");
      79    output_servent ("getservbyname (\"domain\", \"udp\")", sptr);
      80  
      81    sptr = getservbyname ("domain", NULL);
      82    output_servent ("getservbyname (\"domain\", NULL)", sptr);
      83  
      84    sptr = getservbyname ("not-existant", NULL);
      85    output_servent ("getservbyname (\"not-existant\", NULL)", sptr);
      86  
      87    /* This shouldn't return anything.  */
      88    sptr = getservbyname ("", "");
      89    output_servent ("getservbyname (\"\", \"\")", sptr);
      90  
      91    sptr = getservbyname ("", "tcp");
      92    output_servent ("getservbyname (\"\", \"tcp\")", sptr);
      93  
      94    sptr = getservbyport (htons(53), "tcp");
      95    output_servent ("getservbyport (htons(53), \"tcp\")", sptr);
      96  
      97    sptr = getservbyport (htons(53), NULL);
      98    output_servent ("getservbyport (htons(53), NULL)", sptr);
      99  
     100    sptr = getservbyport (htons(1), "udp"); /* shouldn't exist */
     101    output_servent ("getservbyport (htons(1), \"udp\")", sptr);
     102  
     103    setservent (0);
     104    do
     105      {
     106        sptr = getservent ();
     107        output_servent ("getservent ()", sptr);
     108      }
     109    while (sptr != NULL);
     110    endservent ();
     111  }
     112  
     113  
     114  static void
     115  output_hostent (const char *call, struct hostent *hptr)
     116  {
     117    char **pptr;
     118    char buf[INET6_ADDRSTRLEN];
     119  
     120    if (hptr == NULL)
     121      printf ("Call: %s returned NULL\n", call);
     122    else
     123      {
     124        printf ("Call: %s returned: name: %s, addr_type: %d\n",
     125  	      call, hptr->h_name, hptr->h_addrtype);
     126        if (hptr->h_aliases)
     127  	for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
     128  	  printf ("  alias: %s\n", *pptr);
     129  
     130        for (pptr = hptr->h_addr_list; *pptr != NULL; pptr++)
     131  	printf ("  ip: %s\n",
     132  		inet_ntop (hptr->h_addrtype, *pptr, buf, sizeof (buf)));
     133      }
     134  }
     135  
     136  static void
     137  test_hosts (void)
     138  {
     139    struct hostent *hptr1, *hptr2;
     140    char *name = NULL;
     141    size_t namelen = 0;
     142    struct in_addr ip;
     143  
     144    hptr1 = gethostbyname ("localhost");
     145    hptr2 = gethostbyname ("LocalHost");
     146    if (hptr1 != NULL || hptr2 != NULL)
     147      {
     148        if (hptr1 == NULL)
     149  	{
     150  	  printf ("localhost not found - but LocalHost found:-(\n");
     151  	  ++error_count;
     152  	}
     153        else if (hptr2 == NULL)
     154  	{
     155  	  printf ("LocalHost not found - but localhost found:-(\n");
     156  	  ++error_count;
     157  	}
     158        else if (strcmp (hptr1->h_name, hptr2->h_name) != 0)
     159  	{
     160  	  printf ("localhost and LocalHost have different canonical name\n");
     161  	  printf ("gethostbyname (\"localhost\")->%s\n", hptr1->h_name);
     162  	  printf ("gethostbyname (\"LocalHost\")->%s\n", hptr2->h_name);
     163  	  ++error_count;
     164  	}
     165        else
     166  	output_hostent ("gethostbyname(\"localhost\")", hptr1);
     167      }
     168  
     169    hptr1 = gethostbyname ("127.0.0.1");
     170    output_hostent ("gethostbyname (\"127.0.0.1\")", hptr1);
     171  
     172    hptr1 = gethostbyname ("10.1234");
     173    output_hostent ("gethostbyname (\"10.1234\")", hptr1);
     174  
     175    hptr1 = gethostbyname2 ("localhost", AF_INET);
     176    output_hostent ("gethostbyname2 (\"localhost\", AF_INET)", hptr1);
     177  
     178    while (gethostname (name, namelen) < 0 && errno == ENAMETOOLONG)
     179      {
     180        namelen += 2;		/* tiny increments to test a lot */
     181        name = xrealloc (name, namelen);
     182      }
     183    if (gethostname (name, namelen) == 0)
     184      {
     185        printf ("Hostname: %s\n", name);
     186        if (name != NULL)
     187  	{
     188  	  hptr1 = gethostbyname (name);
     189  	  output_hostent ("gethostbyname (gethostname(...))", hptr1);
     190  	}
     191      }
     192  
     193    ip.s_addr = htonl (INADDR_LOOPBACK);
     194    hptr1 = gethostbyaddr ((char *) &ip, sizeof (ip), AF_INET);
     195    if (hptr1 != NULL)
     196      {
     197        printf ("official name of 127.0.0.1: %s\n", hptr1->h_name);
     198      }
     199  
     200    sethostent (0);
     201    do
     202      {
     203        hptr1 = gethostent ();
     204        output_hostent ("gethostent ()", hptr1);
     205      }
     206    while (hptr1 != NULL);
     207    endhostent ();
     208  
     209  }
     210  
     211  
     212  static void
     213  output_netent (const char *call, struct netent *nptr)
     214  {
     215    char **pptr;
     216  
     217    if (nptr == NULL)
     218      printf ("Call: %s returned NULL\n", call);
     219    else
     220      {
     221        struct in_addr ip;
     222  
     223        ip.s_addr = htonl(nptr->n_net);
     224        printf ("Call: %s, returned: n_name: %s, network_number: %s\n",
     225  	      call, nptr->n_name, inet_ntoa (ip));
     226  
     227        for (pptr = nptr->n_aliases; *pptr != NULL; pptr++)
     228  	printf ("  alias: %s\n", *pptr);
     229      }
     230  }
     231  
     232  static void
     233  test_network (void)
     234  {
     235    struct netent *nptr;
     236    uint32_t ip;
     237  
     238    /*
     239       This test needs the following line in /etc/networks:
     240       loopback        127.0.0.0
     241    */
     242    nptr = getnetbyname ("loopback");
     243    output_netent ("getnetbyname (\"loopback\")",nptr);
     244  
     245    nptr = getnetbyname ("LoopBACK");
     246    output_netent ("getnetbyname (\"LoopBACK\")",nptr);
     247  
     248    ip = inet_network ("127.0.0.0");
     249    nptr = getnetbyaddr (ip, AF_INET);
     250    output_netent ("getnetbyaddr (inet_network (\"127.0.0.0\"), AF_INET)",nptr);
     251  
     252    setnetent (0);
     253    do
     254      {
     255        nptr = getnetent ();
     256        output_netent ("getnetent ()", nptr);
     257      }
     258    while (nptr != NULL);
     259    endnetent ();
     260  }
     261  
     262  
     263  static void
     264  output_protoent (const char *call, struct protoent *prptr)
     265  {
     266    char **pptr;
     267  
     268    if (prptr == NULL)
     269      printf ("Call: %s returned NULL\n", call);
     270    else
     271      {
     272        printf ("Call: %s, returned: p_name: %s, p_proto: %d\n",
     273  	      call, prptr->p_name, prptr->p_proto);
     274        for (pptr = prptr->p_aliases; *pptr != NULL; pptr++)
     275  	printf ("  alias: %s\n", *pptr);
     276      }
     277  }
     278  
     279  
     280  static void
     281  test_protocols (void)
     282  {
     283    struct protoent *prptr;
     284  
     285    prptr = getprotobyname ("IP");
     286    output_protoent ("getprotobyname (\"IP\")", prptr);
     287  
     288    prptr = getprotobynumber (1);
     289    output_protoent ("getprotobynumber (1)", prptr);
     290  
     291    setprotoent (0);
     292    do
     293      {
     294        prptr = getprotoent ();
     295        output_protoent ("getprotoent ()", prptr);
     296      }
     297    while (prptr != NULL);
     298    endprotoent ();
     299  }
     300  
     301  
     302  /* Override /etc/nsswitch.conf for this program.  This is mainly
     303     useful for developers. */
     304  static void  __attribute__ ((unused))
     305  setdb (const char *dbname)
     306  {
     307    if (strcmp ("db", dbname))
     308        {
     309  	/*
     310  	  db is not implemented for hosts, networks
     311  	*/
     312  	__nss_configure_lookup ("hosts", dbname);
     313  	__nss_configure_lookup ("networks", dbname);
     314        }
     315    __nss_configure_lookup ("protocols", dbname);
     316    __nss_configure_lookup ("services", dbname);
     317  }
     318  
     319  
     320  static int
     321  do_test (void)
     322  {
     323    /*
     324      setdb ("db");
     325    */
     326  
     327    test_hosts ();
     328    test_network ();
     329    test_protocols ();
     330    test_services ();
     331  
     332    if (error_count)
     333      printf ("\n %d errors occurred!\n", error_count);
     334    else
     335      printf ("No visible errors occurred!\n");
     336  
     337    return (error_count != 0);
     338  }
     339  
     340  #include <support/test-driver.c>