"Fossies" - the Fresh Open Source Software Archive

Member "krb5-1.18/src/tests/resolve/addrinfo-test.c" (12 Feb 2020, 9432 Bytes) of package /linux/misc/krb5-1.18.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
    2 /* tests/resolve/addrinfo-test.c */
    3 /*
    4  * Copyright 2004 by the Massachusetts Institute of Technology.
    5  * All Rights Reserved.
    6  *
    7  * Export of this software from the United States of America may
    8  *   require a specific license from the United States Government.
    9  *   It is the responsibility of any person or organization contemplating
   10  *   export to obtain such a license before exporting.
   11  *
   12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
   13  * distribute this software and its documentation for any purpose and
   14  * without fee is hereby granted, provided that the above copyright
   15  * notice appear in all copies and that both that copyright notice and
   16  * this permission notice appear in supporting documentation, and that
   17  * the name of M.I.T. not be used in advertising or publicity pertaining
   18  * to distribution of the software without specific, written prior
   19  * permission.  Furthermore if you modify this software you must label
   20  * your software as modified software and not distribute it in such a
   21  * fashion that it might be confused with the original M.I.T. software.
   22  * M.I.T. makes no representations about the suitability of
   23  * this software for any purpose.  It is provided "as is" without express
   24  * or implied warranty.
   25  */
   26 
   27 /*
   28  * A simple program to test the functionality of the getaddrinfo function.
   29  *
   30  * Usage:
   31  *   addrinfo-test [-t|-u|-R|-I] [-d|-s|-r] [-p port] [-P] [hostname]
   32  *
   33  *   When invoked with no arguments, NULL is used for the node name,
   34  *   which (at least with a non-null "port") means a socket address
   35  *   is desired that can be used with connect() or bind() (depending
   36  *   on whether "-P" is given).
   37  */
   38 
   39 #include <k5-platform.h>
   40 #include <sys/types.h>
   41 #include <sys/socket.h>
   42 #include <netdb.h>
   43 #include <netinet/in.h> /* needed for IPPROTO_* on NetBSD */
   44 #ifdef USE_FAKE_ADDRINFO
   45 #include "fake-addrinfo.h"
   46 #endif
   47 
   48 static const char *protoname (int p) {
   49     static char buf[30];
   50 
   51 #define X(N) if (p == IPPROTO_ ## N) return #N
   52 
   53     X(TCP);
   54     X(UDP);
   55     X(ICMP);
   56 #ifdef IPPROTO_IPV6
   57     X(IPV6);
   58 #endif
   59 #ifdef IPPROTO_GRE
   60     X(GRE);
   61 #endif
   62 #ifdef IPPROTO_NONE
   63     X(NONE);
   64 #endif
   65     X(RAW);
   66 #ifdef IPPROTO_COMP
   67     X(COMP);
   68 #endif
   69 
   70     snprintf(buf, sizeof(buf), " %-2d", p);
   71     return buf;
   72 }
   73 
   74 static const char *socktypename (int t) {
   75     static char buf[30];
   76     switch (t) {
   77     case SOCK_DGRAM: return "DGRAM";
   78     case SOCK_STREAM: return "STREAM";
   79     case SOCK_RAW: return "RAW";
   80     case SOCK_RDM: return "RDM";
   81     case SOCK_SEQPACKET: return "SEQPACKET";
   82     }
   83     snprintf(buf, sizeof(buf), " %-2d", t);
   84     return buf;
   85 }
   86 
   87 static char *whoami;
   88 
   89 static void usage () {
   90     fprintf(stderr,
   91             "usage:\n"
   92             "\t%s [ options ] [host]\n"
   93             "options:\n"
   94             "\t-t\tspecify protocol IPPROTO_TCP\n"
   95             "\t-u\tspecify protocol IPPROTO_UDP\n"
   96             "\t-R\tspecify protocol IPPROTO_RAW\n"
   97             "\t-I\tspecify protocol IPPROTO_ICMP\n"
   98             "\n"
   99             "\t-d\tspecify socket type SOCK_DGRAM\n"
  100             "\t-s\tspecify socket type SOCK_STREAM\n"
  101             "\t-r\tspecify socket type SOCK_RAW\n"
  102             "\n"
  103             "\t-4\tspecify address family AF_INET\n"
  104 #ifdef AF_INET6
  105             "\t-6\tspecify address family AF_INET6\n"
  106 #endif
  107             "\n"
  108             "\t-p P\tspecify port P (service name or port number)\n"
  109             "\t-N\thostname is numeric, skip DNS query\n"
  110             "\t-n\tservice/port is numeric (sets AI_NUMERICSERV)\n"
  111             "\t-P\tset AI_PASSIVE\n"
  112             "\n"
  113             "default: protocol 0, socket type 0, address family 0, null port\n"
  114             ,
  115             whoami);
  116     /* [ -t | -u | -R | -I ] [ -d | -s | -r ] [ -p port ] */
  117     exit (1);
  118 }
  119 
  120 static const char *familyname (int f) {
  121     static char buf[30];
  122     switch (f) {
  123     default:
  124         snprintf(buf, sizeof(buf), "AF %d", f);
  125         return buf;
  126     case AF_INET: return "AF_INET";
  127 #ifdef AF_INET6
  128     case AF_INET6: return "AF_INET6";
  129 #endif
  130     }
  131 }
  132 
  133 #define eaistr(X) (X == EAI_SYSTEM ? strerror(errno) : gai_strerror(X))
  134 
  135 int main (int argc, char *argv[])
  136 {
  137     struct addrinfo *ap, *ap2;
  138     int err, numerichost = 0, numericserv = 0;
  139     char *hname, *port = 0, *sep;
  140     struct addrinfo hints;
  141 
  142     whoami = strrchr(argv[0], '/');
  143     if (whoami == 0)
  144         whoami = argv[0];
  145     else
  146         whoami = whoami+1;
  147 
  148     memset(&hints, 0, sizeof(hints));
  149     hints.ai_flags = 0;
  150     hints.ai_socktype = 0;
  151 
  152     hname = 0;
  153     hints.ai_family = 0;
  154 
  155     if (argc == 1)
  156         usage ();
  157 
  158     while (++argv, --argc > 0) {
  159         char *arg;
  160         arg = *argv;
  161 
  162         if (*arg != '-')
  163             hname = arg;
  164         else if (arg[1] == 0 || arg[2] != 0)
  165             usage ();
  166         else
  167             switch (arg[1]) {
  168             case 'u':
  169                 hints.ai_protocol = IPPROTO_UDP;
  170                 break;
  171             case 't':
  172                 hints.ai_protocol = IPPROTO_TCP;
  173                 break;
  174             case 'R':
  175                 hints.ai_protocol = IPPROTO_RAW;
  176                 break;
  177             case 'I':
  178                 hints.ai_protocol = IPPROTO_ICMP;
  179                 break;
  180             case 'd':
  181                 hints.ai_socktype = SOCK_DGRAM;
  182                 break;
  183             case 's':
  184                 hints.ai_socktype = SOCK_STREAM;
  185                 break;
  186             case 'r':
  187                 hints.ai_socktype = SOCK_RAW;
  188                 break;
  189             case 'p':
  190                 if (argv[1] == 0 || argv[1][0] == 0 || argv[1][0] == '-')
  191                     usage ();
  192                 port = argv[1];
  193                 argc--, argv++;
  194                 break;
  195             case '4':
  196                 hints.ai_family = AF_INET;
  197                 break;
  198 #ifdef AF_INET6
  199             case '6':
  200                 hints.ai_family = AF_INET6;
  201                 break;
  202 #endif
  203             case 'N':
  204                 numerichost = 1;
  205                 break;
  206             case 'n':
  207                 numericserv = 1;
  208                 break;
  209             case 'P':
  210                 hints.ai_flags |= AI_PASSIVE;
  211                 break;
  212             default:
  213                 usage ();
  214             }
  215     }
  216 
  217     if (hname && !numerichost)
  218         hints.ai_flags |= AI_CANONNAME;
  219     if (numerichost) {
  220 #ifdef AI_NUMERICHOST
  221         hints.ai_flags |= AI_NUMERICHOST;
  222 #else
  223         fprintf(stderr, "AI_NUMERICHOST not defined on this platform\n");
  224         exit(1);
  225 #endif
  226     }
  227     if (numericserv) {
  228 #ifdef AI_NUMERICSERV
  229         hints.ai_flags |= AI_NUMERICSERV;
  230 #else
  231         fprintf(stderr, "AI_NUMERICSERV not defined on this platform\n");
  232         exit(1);
  233 #endif
  234     }
  235 
  236     printf("getaddrinfo(hostname %s, service %s,\n"
  237            "            hints { ",
  238            hname ? hname : "(null)", port ? port : "(null)");
  239     sep = "";
  240 #define Z(FLAG) if (hints.ai_flags & AI_##FLAG) printf("%s%s", sep, #FLAG), sep = "|"
  241     Z(CANONNAME);
  242     Z(PASSIVE);
  243 #ifdef AI_NUMERICHOST
  244     Z(NUMERICHOST);
  245 #endif
  246 #ifdef AI_NUMERICSERV
  247     Z(NUMERICSERV);
  248 #endif
  249     if (sep[0] == 0)
  250         printf ("no-flags");
  251     if (hints.ai_family)
  252         printf(" %s", familyname(hints.ai_family));
  253     if (hints.ai_socktype)
  254         printf(" SOCK_%s", socktypename(hints.ai_socktype));
  255     if (hints.ai_protocol)
  256         printf(" IPPROTO_%s", protoname(hints.ai_protocol));
  257     printf(" }):\n");
  258 
  259     err = getaddrinfo(hname, port, &hints, &ap);
  260     if (err) {
  261         printf("\terror => %s\n", eaistr(err));
  262         return 1;
  263     }
  264 
  265     for (ap2 = ap; ap2; ap2 = ap2->ai_next) {
  266         char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV];
  267         /* If we don't do this, even AIX's own getnameinfo will reject
  268            the sockaddr structures.  The sa_len field doesn't get set
  269            either, on AIX, but getnameinfo won't complain.  */
  270         if (ap2->ai_addr->sa_family == 0) {
  271             printf("BAD: sa_family zero! fixing...\n");
  272             ap2->ai_addr->sa_family = ap2->ai_family;
  273         } else if (ap2->ai_addr->sa_family != ap2->ai_family) {
  274             printf("BAD: sa_family != ai_family! fixing...\n");
  275             ap2->ai_addr->sa_family = ap2->ai_family;
  276         }
  277         if (getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof(hbuf),
  278                         pbuf, sizeof(pbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
  279             strlcpy(hbuf, "...", sizeof(hbuf));
  280             strlcpy(pbuf, "...", sizeof(pbuf));
  281         }
  282         printf("%p:\n"
  283                "\tfamily = %s\tproto = %-4s\tsocktype = %s\n",
  284                (void *) ap2, familyname(ap2->ai_family),
  285                protoname (ap2->ai_protocol),
  286                socktypename (ap2->ai_socktype));
  287         if (ap2->ai_canonname) {
  288             if (ap2->ai_canonname[0])
  289                 printf("\tcanonname = %s\n", ap2->ai_canonname);
  290             else
  291                 printf("BAD: ai_canonname is set but empty!\n");
  292         } else if (ap2 == ap && (hints.ai_flags & AI_CANONNAME)) {
  293             printf("BAD: first ai_canonname is null!\n");
  294         }
  295         printf("\taddr = %-28s\tport = %s\n", hbuf, pbuf);
  296 
  297         err = getnameinfo(ap2->ai_addr, ap2->ai_addrlen, hbuf, sizeof (hbuf),
  298                           pbuf, sizeof(pbuf), NI_NAMEREQD);
  299         if (err)
  300             printf("\tgetnameinfo(NI_NAMEREQD): %s\n", eaistr(err));
  301         else
  302             printf("\tgetnameinfo => %s, %s\n", hbuf, pbuf);
  303     }
  304     freeaddrinfo(ap);
  305     return 0;
  306 }