"Fossies" - the Fresh Open Source Software Archive

Member "pidentd-3.0.19/src/ibench.c" (20 Jan 1999, 5577 Bytes) of package /linux/misc/old/pidentd-3.0.19.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. For more information about "ibench.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 ** ibench.c - a small benchmarking/stress-testing program for IDENT servers.
    3 **
    4 ** Copyright (c) 1997-1999 Peter Eriksson <pen@lysator.liu.se>
    5 **
    6 ** This program is free software; you can redistribute it and/or
    7 ** modify it as you wish - as long as you don't claim that you wrote
    8 ** it.
    9 **
   10 ** This program is distributed in the hope that it will be useful,
   11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   13 **
   14 **
   15 ** Please note that this program *should* be run on the same machine
   16 ** as the IDENT server you wish to test. It assumes it can connect to
   17 ** it via the loopback interface.
   18 **
   19 ** If you specify a server address using the -rADDR option, then
   20 ** the lookups will be for the *servers* username (normally "nobody"),
   21 ** and not the username "ibench" runs as.
   22 */
   23 
   24 #include "config.h"
   25 
   26 #include <stdio.h>
   27 #include <errno.h>
   28 #include <signal.h>
   29 
   30 #ifdef HAVE_UNISTD_H
   31 #include <unistd.h>
   32 #endif
   33 
   34 #include <stdlib.h>
   35 #include <time.h>
   36 #include <pwd.h>
   37 #include <string.h>
   38 #include <sys/types.h>
   39 
   40 #ifndef SYS_SOCKET_H_INCLUDED
   41 #define SYS_SOCKET_H_INCLUDED
   42 #include <sys/socket.h>
   43 #endif
   44 
   45 #include <netinet/in.h>
   46 #include <arpa/inet.h>
   47 
   48 #include "pidentd.h"
   49 
   50 
   51 static struct sockaddr_in host_sin;
   52 static char *username;
   53 static int rev_flag = 0;
   54 static volatile int abort_test = 0;
   55 static int ntests = 0;
   56 static int ignore_reply = 0;
   57 
   58 
   59 static RETSIGTYPE
   60 sigint_handler(int sig)
   61 {
   62     abort_test = 1;
   63 }
   64 
   65 
   66 /*
   67 ** Perform an IDENT lookup.
   68 ** Returns: -1 in case of a network or system error
   69 **           0 if all was OK
   70 **           1 if the reply was malformed
   71 **           2 if the reply was with the wrong username
   72 */
   73 static int
   74 run_test(void)
   75 {
   76     int fd, buflen;
   77     socklen_t len;
   78     struct sockaddr_in our, sin;
   79     char buf[1024], buf2[1024];
   80     
   81 
   82     ++ntests;
   83     
   84     sin = host_sin;
   85 
   86     fd = socket(AF_INET, SOCK_STREAM, 0);
   87     if (fd < 0)
   88     {
   89     if (errno != EINTR)
   90         perror("socket");
   91     return -1;
   92     }
   93     
   94     if (connect(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0)
   95     {
   96     if (errno != EINTR)
   97         perror("connect");
   98     goto Fail;
   99     }
  100 
  101     len = sizeof(our);
  102     if (getsockname(fd, (struct sockaddr *) &our, &len) < 0)
  103     {
  104     if (errno != EINTR)
  105         perror("getsockname");
  106     goto Fail;
  107     }
  108 
  109 #ifdef HAVE_SNPRINTF
  110     if (rev_flag)
  111     snprintf(buf, sizeof(buf),
  112          "%d , %d\r\n", ntohs(sin.sin_port), ntohs(our.sin_port));
  113     else
  114     snprintf(buf, sizeof(buf),
  115          "%d , %d\r\n", ntohs(our.sin_port), ntohs(sin.sin_port));
  116 #else
  117     if (rev_flag)
  118     sprintf(buf, "%d , %d\r\n", ntohs(sin.sin_port), ntohs(our.sin_port));
  119     else
  120     sprintf(buf, "%d , %d\r\n", ntohs(our.sin_port), ntohs(sin.sin_port));
  121 #endif
  122     
  123     if (write(fd, buf, strlen(buf)) < 0)
  124     {
  125     if (errno != EINTR)
  126         perror("write");
  127     goto Fail;
  128     }
  129 
  130     if (shutdown(fd, 1) < 0)
  131     {
  132     if (errno != EINTR)
  133         perror("shutdown");
  134     goto Fail;
  135     }
  136     
  137     buflen = read(fd, buf, sizeof(buf));
  138     if (buflen < 0)
  139     {
  140     if (errno != EINTR)
  141         perror("read");
  142     goto Fail;
  143     }
  144     
  145     close(fd);
  146     
  147     buf[buflen] = '\0';
  148 
  149     buflen = sscanf(buf, " %*d , %*d : USERID : %*s :%[^\r\n]", buf2);
  150 
  151     if (buflen != 1)
  152     {
  153     fprintf(stderr, "Malformed reply (%d): %s\n", buflen, buf);
  154     return 1;
  155     }
  156 
  157     if (!ignore_reply && strcmp(buf2, username) != 0)
  158     {
  159     fprintf(stderr, "Incorrect username: %s != %s\n", buf2, username);
  160     return 2;
  161     }
  162 
  163     return 0;
  164     
  165   Fail:
  166     close(fd);
  167     return -1;
  168 }
  169 
  170 void usage(FILE *fp)
  171 {
  172     fputs("Usage: ibench [-h] [-i] [-rADDR] [<seconds> [<port> [<username>]]]\n",
  173       fp);
  174     fputs("\t-h\tDisplay this information.\n", fp);
  175     fputs("\t-i\tIgnore the IDENT response.\n", fp);
  176     fputs("\t-rADDR\tPerform a reverse lookup against a remote server.\n", fp);
  177 }
  178 
  179 
  180 int
  181 main(int argc,
  182      char *argv[])
  183 {
  184     int i, test_len, len, ecode;
  185     time_t start, stop;
  186     struct passwd *pp;
  187     
  188 
  189     memset(&host_sin, 0, sizeof(host_sin));
  190     host_sin.sin_family = AF_INET;
  191     host_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
  192     
  193     for (i = 1; i < argc && argv[i][0] == '-'; i++)
  194     switch (argv[i][1])
  195     {
  196       case 'h':
  197         usage(stdout);
  198         exit(EXIT_SUCCESS);
  199 
  200       case 'r':
  201         rev_flag = 1;
  202         host_sin.sin_addr.s_addr = inet_addr(argv[1]+2);
  203         username = "nobody";
  204         break;
  205 
  206       case 'i':
  207         ignore_reply = 1;
  208         break;
  209         
  210       default:
  211         usage(stderr);
  212         exit(EXIT_FAILURE);
  213     }
  214     
  215     if (i < argc)
  216     test_len = atoi(argv[i++]);
  217     else
  218     test_len = 60;
  219 
  220     if (i < argc)
  221     host_sin.sin_port = htons(atoi(argv[i++]));
  222     else
  223     host_sin.sin_port = htons(IPPORT_IDENT);
  224 
  225     if (i < argc)
  226     username = argv[i++];
  227     else
  228     {
  229     pp = getpwuid(getuid());
  230     username = pp->pw_name;
  231     }
  232 
  233     if (i < argc)
  234     {
  235     fprintf(stderr, "ibench: extranous arguments\n");
  236     usage(stderr);
  237     exit(EXIT_FAILURE);
  238     }
  239     
  240     time(&start);
  241     ntests = 0;
  242     ecode = 0;
  243     
  244     signal(SIGINT, sigint_handler);
  245 
  246     printf("Test started, will run for %d seconds (or press Ctrl-C to terminate).\n", test_len);
  247     
  248     do
  249     {
  250     if (abort_test || (ecode = run_test()))
  251     {
  252         time(&stop);
  253         break;
  254     }
  255     
  256     time(&stop);
  257     }
  258     while (stop - start < test_len);
  259 
  260     len = stop-start;
  261     if (len == 0)
  262     len = 1;
  263 
  264     if (ecode == 0 || (ecode == -1 && abort_test))
  265     {
  266     printf("Test OK: %d requests in %d seconds (%d requests/s)\n",
  267            ntests, len, ntests/len);
  268     exit(EXIT_SUCCESS);
  269     }
  270     else
  271     {
  272     printf("Test FAILED after %d requests in %d seconds (%d requests/s)\n",
  273            ntests, len, ntests/len);
  274     exit(EXIT_FAILURE);
  275     }
  276 }