Back to index

glibc  2.9
test-netdb.c
Go to the documentation of this file.
00001 /* Copyright (C) 1998,99,2000,01 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Andreas Jaeger <aj@suse.de>, 1998.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 /*
00021   Testing of some network related lookup functions.
00022   The system databases looked up are:
00023   - /etc/services
00024   - /etc/hosts
00025   - /etc/networks
00026   - /etc/protocols
00027   - /etc/rpc
00028   The tests try to be fairly generic and simple so that they work on
00029   every possible setup (and might therefore not detect some possible
00030   errors).
00031 */
00032 
00033 #include <netdb.h>
00034 #include <rpc/netdb.h>
00035 #include <stdio.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <arpa/inet.h>
00039 #include <netinet/in.h>
00040 #include <sys/param.h>
00041 #include <sys/socket.h>
00042 #include <unistd.h>
00043 #include <errno.h>
00044 #include "nss.h"
00045 
00046 /*
00047   The following define is necessary for glibc 2.0.6
00048 */
00049 #ifndef INET6_ADDRSTRLEN
00050 # define INET6_ADDRSTRLEN 46
00051 #endif
00052 
00053 int error_count;
00054 
00055 static void
00056 output_servent (const char *call, struct servent *sptr)
00057 {
00058   char **pptr;
00059 
00060   if (sptr == NULL)
00061     printf ("Call: %s returned NULL\n", call);
00062   else
00063     {
00064       printf ("Call: %s, returned: s_name: %s, s_port: %d, s_proto: %s\n",
00065              call, sptr->s_name, ntohs(sptr->s_port), sptr->s_proto);
00066       for (pptr = sptr->s_aliases; *pptr != NULL; pptr++)
00067        printf ("  alias: %s\n", *pptr);
00068     }
00069 }
00070 
00071 
00072 static void
00073 test_services (void)
00074 {
00075   struct servent *sptr;
00076 
00077   sptr = getservbyname ("domain", "tcp");
00078   output_servent ("getservbyname (\"domain\", \"tcp\")", sptr);
00079 
00080   sptr = getservbyname ("domain", "udp");
00081   output_servent ("getservbyname (\"domain\", \"udp\")", sptr);
00082 
00083   sptr = getservbyname ("domain", NULL);
00084   output_servent ("getservbyname (\"domain\", NULL)", sptr);
00085 
00086   sptr = getservbyname ("not-existant", NULL);
00087   output_servent ("getservbyname (\"not-existant\", NULL)", sptr);
00088 
00089   /* This shouldn't return anything.  */
00090   sptr = getservbyname ("", "");
00091   output_servent ("getservbyname (\"\", \"\")", sptr);
00092 
00093   sptr = getservbyname ("", "tcp");
00094   output_servent ("getservbyname (\"\", \"tcp\")", sptr);
00095 
00096   sptr = getservbyport (htons(53), "tcp");
00097   output_servent ("getservbyport (htons(53), \"tcp\")", sptr);
00098 
00099   sptr = getservbyport (htons(53), NULL);
00100   output_servent ("getservbyport (htons(53), NULL)", sptr);
00101 
00102   sptr = getservbyport (htons(1), "udp"); /* shouldn't exist */
00103   output_servent ("getservbyport (htons(1), \"udp\")", sptr);
00104 
00105   setservent (0);
00106   do
00107     {
00108       sptr = getservent ();
00109       output_servent ("getservent ()", sptr);
00110     }
00111   while (sptr != NULL);
00112   endservent ();
00113 }
00114 
00115 
00116 static void
00117 output_hostent (const char *call, struct hostent *hptr)
00118 {
00119   char **pptr;
00120   char buf[INET6_ADDRSTRLEN];
00121 
00122   if (hptr == NULL)
00123     printf ("Call: %s returned NULL\n", call);
00124   else
00125     {
00126       printf ("Call: %s returned: name: %s, addr_type: %d\n",
00127              call, hptr->h_name, hptr->h_addrtype);
00128       if (hptr->h_aliases)
00129        for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
00130          printf ("  alias: %s\n", *pptr);
00131 
00132       for (pptr = hptr->h_addr_list; *pptr != NULL; pptr++)
00133        printf ("  ip: %s\n",
00134               inet_ntop (hptr->h_addrtype, *pptr, buf, sizeof (buf)));
00135     }
00136 }
00137 
00138 static void
00139 test_hosts (void)
00140 {
00141   struct hostent *hptr1, *hptr2;
00142   char *name = NULL;
00143   size_t namelen = 0;
00144   struct in_addr ip;
00145 
00146   hptr1 = gethostbyname ("localhost");
00147   hptr2 = gethostbyname ("LocalHost");
00148   if (hptr1 != NULL || hptr2 != NULL)
00149     {
00150       if (hptr1 == NULL)
00151        {
00152          printf ("localhost not found - but LocalHost found:-(\n");
00153          ++error_count;
00154        }
00155       else if (hptr2 == NULL)
00156        {
00157          printf ("LocalHost not found - but localhost found:-(\n");
00158          ++error_count;
00159        }
00160       else if (strcmp (hptr1->h_name, hptr2->h_name) != 0)
00161        {
00162          printf ("localhost and LocalHost have different canoncial name\n");
00163          printf ("gethostbyname (\"localhost\")->%s\n", hptr1->h_name);
00164          printf ("gethostbyname (\"LocalHost\")->%s\n", hptr2->h_name);
00165          ++error_count;
00166        }
00167       else
00168        output_hostent ("gethostbyname(\"localhost\")", hptr1);
00169     }
00170 
00171   hptr1 = gethostbyname ("127.0.0.1");
00172   output_hostent ("gethostbyname (\"127.0.0.1\")", hptr1);
00173 
00174   hptr1 = gethostbyname ("10.1234");
00175   output_hostent ("gethostbyname (\"10.1234\")", hptr1);
00176 
00177   hptr1 = gethostbyname2 ("localhost", AF_INET);
00178   output_hostent ("gethostbyname2 (\"localhost\", AF_INET)", hptr1);
00179 
00180   while (gethostname (name, namelen) < 0 && errno == ENAMETOOLONG)
00181     {
00182       namelen += 2;         /* tiny increments to test a lot */
00183       name = realloc (name, namelen);
00184     }
00185   if (gethostname (name, namelen) == 0)
00186     {
00187       printf ("Hostname: %s\n", name);
00188       if (name != NULL)
00189        {
00190          hptr1 = gethostbyname (name);
00191          output_hostent ("gethostbyname (gethostname(...))", hptr1);
00192        }
00193     }
00194 
00195   ip.s_addr = htonl (INADDR_LOOPBACK);
00196   hptr1 = gethostbyaddr ((char *) &ip, sizeof(ip), AF_INET);
00197   if (hptr1 != NULL)
00198     {
00199       printf ("official name of 127.0.0.1: %s\n", hptr1->h_name);
00200     }
00201 
00202   sethostent (0);
00203   do
00204     {
00205       hptr1 = gethostent ();
00206       output_hostent ("gethostent ()", hptr1);
00207     }
00208   while (hptr1 != NULL);
00209   endhostent ();
00210 
00211 }
00212 
00213 
00214 static void
00215 output_netent (const char *call, struct netent *nptr)
00216 {
00217   char **pptr;
00218 
00219   if (nptr == NULL)
00220     printf ("Call: %s returned NULL\n", call);
00221   else
00222     {
00223       struct in_addr ip;
00224 
00225       ip.s_addr = htonl(nptr->n_net);
00226       printf ("Call: %s, returned: n_name: %s, network_number: %s\n",
00227              call, nptr->n_name, inet_ntoa (ip));
00228 
00229       for (pptr = nptr->n_aliases; *pptr != NULL; pptr++)
00230        printf ("  alias: %s\n", *pptr);
00231     }
00232 }
00233 
00234 static void
00235 test_network (void)
00236 {
00237   struct netent *nptr;
00238   u_int32_t ip;
00239 
00240   /*
00241      This test needs the following line in /etc/networks:
00242      loopback        127.0.0.0
00243   */
00244   nptr = getnetbyname ("loopback");
00245   output_netent ("getnetbyname (\"loopback\")",nptr);
00246 
00247   nptr = getnetbyname ("LoopBACK");
00248   output_netent ("getnetbyname (\"LoopBACK\")",nptr);
00249 
00250   ip = inet_network ("127.0.0.0");
00251   nptr = getnetbyaddr (ip, AF_INET);
00252   output_netent ("getnetbyaddr (inet_network (\"127.0.0.0\"), AF_INET)",nptr);
00253 
00254   setnetent (0);
00255   do
00256     {
00257       nptr = getnetent ();
00258       output_netent ("getnetent ()", nptr);
00259     }
00260   while (nptr != NULL);
00261   endnetent ();
00262 }
00263 
00264 
00265 static void
00266 output_protoent (const char *call, struct protoent *prptr)
00267 {
00268   char **pptr;
00269 
00270   if (prptr == NULL)
00271     printf ("Call: %s returned NULL\n", call);
00272   else
00273     {
00274       printf ("Call: %s, returned: p_name: %s, p_proto: %d\n",
00275              call, prptr->p_name, prptr->p_proto);
00276       for (pptr = prptr->p_aliases; *pptr != NULL; pptr++)
00277        printf ("  alias: %s\n", *pptr);
00278     }
00279 }
00280 
00281 
00282 static void
00283 test_protocols (void)
00284 {
00285   struct protoent *prptr;
00286 
00287   prptr = getprotobyname ("IP");
00288   output_protoent ("getprotobyname (\"IP\")", prptr);
00289 
00290   prptr = getprotobynumber (1);
00291   output_protoent ("getprotobynumber (1)", prptr);
00292 
00293   setprotoent (0);
00294   do
00295     {
00296       prptr = getprotoent ();
00297       output_protoent ("getprotoent ()", prptr);
00298     }
00299   while (prptr != NULL);
00300   endprotoent ();
00301 }
00302 
00303 
00304 static void
00305 output_rpcent (const char *call, struct rpcent *rptr)
00306 {
00307   char **pptr;
00308 
00309   if (rptr == NULL)
00310     printf ("Call: %s returned NULL\n", call);
00311   else
00312     {
00313       printf ("Call: %s, returned: r_name: %s, r_number: %d\n",
00314               call, rptr->r_name, rptr->r_number);
00315       for (pptr = rptr->r_aliases; *pptr != NULL; pptr++)
00316        printf ("  alias: %s\n", *pptr);
00317     }
00318 }
00319 
00320 static void
00321 test_rpc (void)
00322 {
00323   struct rpcent *rptr;
00324 
00325   rptr = getrpcbyname ("portmap");
00326   output_rpcent ("getrpcyname (\"portmap\")", rptr);
00327 
00328   rptr = getrpcbynumber (100000);
00329   output_rpcent ("getrpcbynumber (100000)", rptr);
00330 
00331   setrpcent (0);
00332   do
00333     {
00334       rptr = getrpcent ();
00335       output_rpcent ("getrpcent ()", rptr);
00336     }
00337   while (rptr != NULL);
00338   endrpcent ();
00339 }
00340 
00341 /* Override /etc/nsswitch.conf for this program.  This is mainly
00342    useful for developers. */
00343 static void  __attribute__ ((unused))
00344 setdb (const char *dbname)
00345 {
00346   if (strcmp ("db", dbname))
00347       {
00348        /*
00349          db is not implemented for hosts, networks
00350        */
00351        __nss_configure_lookup ("hosts", dbname);
00352        __nss_configure_lookup ("networks", dbname);
00353       }
00354   __nss_configure_lookup ("protocols", dbname);
00355   __nss_configure_lookup ("rpc", dbname);
00356   __nss_configure_lookup ("services", dbname);
00357 }
00358 
00359 
00360 int
00361 main (void)
00362 {
00363   /*
00364     setdb ("db");
00365   */
00366 
00367   test_hosts ();
00368   test_network ();
00369   test_protocols ();
00370   test_rpc ();
00371   test_services ();
00372 
00373   if (error_count)
00374     printf ("\n %d errors occurred!\n", error_count);
00375   else
00376     printf ("No visible errors occurred!\n");
00377 
00378   return (error_count != 0);
00379 }