"Fossies" - the Fresh Open Source Software Archive

Member "scanssh-2.1/scanssh.c" (21 Nov 2004, 31480 Bytes) of package /linux/privat/old/scanssh-2.1.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 /*
    2  * ScanSSH - simple SSH version scanner
    3  *
    4  * Copyright 2000-2004 (c) Niels Provos <provos@citi.umich.edu>
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. The name of the author may not be used to endorse or promote products
   16  *    derived from this software without specific prior written permission.
   17  *
   18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   28  */
   29 
   30 #include <sys/types.h>
   31 
   32 #ifdef HAVE_CONFIG_H
   33 #include "config.h"
   34 #endif
   35 
   36 #include <sys/socket.h>
   37 #include <sys/wait.h>
   38 #include <sys/time.h>
   39 #include <sys/resource.h>
   40 #include <sys/queue.h>
   41 #include <sys/tree.h>
   42 
   43 #include <netinet/in.h>
   44 #include <arpa/inet.h>
   45 
   46 #include <stdio.h>
   47 #include <stdlib.h>
   48 #include <string.h>
   49 #include <signal.h>
   50 #include <errno.h>
   51 #include <err.h>
   52 #include <fcntl.h>
   53 #include <netdb.h>
   54 #include <pcap.h>
   55 #include <unistd.h>
   56 #include <md5.h>
   57 #include <stdarg.h>
   58 #include <assert.h>
   59 
   60 #include <event.h>
   61 #include <dnet.h>
   62 
   63 #include "scanssh.h"
   64 #include "exclude.h"
   65 #include "xmalloc.h"
   66 #include "interface.h"
   67 
   68 #ifndef howmany
   69 #define howmany(x,y)    (((x) + ((y) - 1)) / (y))
   70 #endif
   71 
   72 #ifdef DEBUG
   73 int debug = 0;
   74 #define DFPRINTF(x) if (debug) fprintf x
   75 #define DNFPRINTF(y, x) if (debug >= y) fprintf x
   76 #else
   77 #define DFPRINTF(x)
   78 #define DNFPRINTF(y, x)
   79 #endif
   80 
   81 struct address_node {
   82     TAILQ_ENTRY (address_node) an_next;
   83 
   84     struct addr an_start;
   85     struct addr an_end;
   86     int an_bits;
   87 };
   88 
   89 struct generate {
   90     TAILQ_ENTRY (generate) gen_next;
   91 
   92     TAILQ_HEAD (an_list, address_node) gen_anqueue;
   93 
   94     int gen_flags;
   95 
   96     uint32_t gen_seed;      /* Seed for PRNG */
   97 
   98     uint32_t gen_bits;
   99     uint32_t gen_start;
  100     uint32_t gen_iterate;
  101     uint32_t gen_end;
  102     uint32_t gen_current;
  103     uint32_t gen_n;     /* successful generations */
  104     uint32_t gen_max;
  105 
  106 
  107     struct port *gen_ports;
  108     int gen_nports;
  109 };
  110 
  111 int populate(struct argument **, int *);
  112 int next_address(struct generate *, struct addr *);
  113 
  114 /* Globals */
  115 struct interface *ss_inter;
  116 rand_t *ss_rand;
  117 ip_t   *ss_ip;
  118 
  119 /* SOCKS servers via which we can scan */
  120 struct socksq socks_host;
  121 
  122 struct scanner **ss_scanners = NULL;
  123 int ss_nscanners = 0;
  124 
  125 struct argument *args;      /* global list of addresses */
  126 int entries;            /* number of remaining addresses */
  127 
  128 int ssh_sendident;      /* should we send ident to ssh server? */
  129 
  130 struct port *ss_ports = NULL;   /* global list of ports to be scanned */
  131 int ss_nports = 0;
  132 
  133 int ss_nhosts = 0;      /* Number of addresses generated */
  134 
  135 pcap_t *pd;
  136 int rndexclude = 1;
  137 struct timeval syn_start;
  138 int syn_rate = 100;
  139 int syn_nsent = 0;
  140 
  141 int max_scanqueue_size = MAXSCANQUEUESZ;
  142 
  143 struct address_slot slots[MAXSLOTS];
  144 
  145 #define MAX_PROCESSES   30
  146 
  147 int commands[MAX_PROCESSES];
  148 int results[MAX_PROCESSES];
  149 
  150 TAILQ_HEAD (gen_list, generate) genqueue;
  151 struct queue_list readyqueue;
  152 
  153 /* Structure for probes */
  154 static SPLAY_HEAD(syntree, argument) synqueue;
  155 
  156 int
  157 argumentcompare(struct argument *a, struct argument *b)
  158 {
  159     return (addr_cmp(&a->addr, &b->addr));
  160 }
  161 
  162 SPLAY_PROTOTYPE(syntree, argument, a_node, argumentcompare);
  163 SPLAY_GENERATE(syntree, argument, a_node, argumentcompare);
  164 
  165 #define synlist_empty()     (synqueuesz == 0)
  166 
  167 int synqueuesz;
  168 
  169 struct address_slot *
  170 slot_get(void)
  171 {
  172     int i;
  173     struct address_slot *slot;
  174 
  175     for (i = 0; i < MAXSLOTS; i++)
  176         if (slots[i].slot_base == NULL)
  177             break;
  178 
  179     if (i >= MAXSLOTS)
  180         return (NULL);
  181     
  182     slot = &slots[i];
  183 
  184     if (slot->slot_base == NULL) {
  185         slot->slot_size = EXPANDEDARGS;
  186         slot->slot_base = xmalloc(EXPANDEDARGS * sizeof(struct argument));
  187         memset(slot->slot_base, 0,
  188                slot->slot_size * sizeof(struct argument));
  189     }
  190 
  191     return (slot);
  192 }
  193 
  194 /* We need to call this to free up our memory */
  195 
  196 void
  197 slot_free(struct address_slot *slot)
  198 {
  199     slot->slot_ref--;
  200     if (slot->slot_ref)
  201         return;
  202 
  203     slot->slot_size = 0;
  204     free(slot->slot_base);
  205     slot->slot_base = NULL;
  206 }
  207 
  208 void
  209 argument_free(struct argument *arg)
  210 {
  211     if (arg->a_ports != NULL && arg->a_hasports) {
  212         int i;
  213 
  214         for (i = 0; i < arg->a_nports; i++) {
  215             struct port_scan *ps = arg->a_ports[i].scan;
  216             if (ps != NULL) {
  217                 event_del(&ps->ev);
  218                 free(ps);
  219             }
  220         }
  221         free(arg->a_ports);
  222         arg->a_ports = NULL;
  223     }
  224 
  225     if (arg->a_res != NULL) {
  226         free(arg->a_res);
  227         arg->a_res = NULL;
  228     }
  229 
  230     slot_free(arg->a_slot);
  231 }
  232 
  233 void
  234 synlist_init(void)
  235 {
  236     SPLAY_INIT(&synqueue);
  237     synqueuesz = 0;
  238 }
  239 
  240 /* Inserts an address into the syn tree and schedules a retransmit */
  241 
  242 int
  243 synlist_insert(struct argument *arg)
  244 {
  245     struct timeval tv;
  246 
  247     timerclear(&tv);
  248     tv.tv_sec = (arg->a_retry/2 + 1) * SYNWAIT;
  249     tv.tv_usec = rand_uint32(ss_rand) % 1000000L;
  250 
  251     evtimer_add(&arg->ev, &tv);
  252 
  253     /* Insert the node into our tree */
  254     assert(SPLAY_FIND(syntree, &synqueue, arg) == NULL);
  255     SPLAY_INSERT(syntree, &synqueue, arg);
  256 
  257     synqueuesz++;
  258 
  259     return (0);
  260 }
  261 
  262 void
  263 synlist_remove(struct argument *arg)
  264 {
  265     SPLAY_REMOVE(syntree, &synqueue, arg);
  266     evtimer_del(&arg->ev);
  267     synqueuesz--;
  268 }
  269 
  270 int
  271 synlist_probe(struct argument *arg, uint16_t port)
  272 {
  273         return (synprobe_send(&ss_inter->if_ent.intf_addr,
  274             &arg->addr, port, &arg->a_seqnr));
  275 }
  276 
  277 int
  278 synprobe_send(struct addr *src, struct addr *dst,
  279     uint16_t port, uint32_t *seqnr)
  280 {
  281     static uint8_t pkt[1500];
  282     struct tcp_hdr *tcp;
  283     uint iplen;
  284     int res;
  285 
  286     DFPRINTF((stderr, "Sending probe to %s:%d\n", addr_ntoa(dst), port));
  287 
  288     tcp = (struct tcp_hdr *)(pkt + IP_HDR_LEN);
  289     tcp_pack_hdr(tcp, rand_uint16(ss_rand), port, 
  290         *seqnr, 0, 
  291         TH_SYN, 0x8000, 0);
  292 
  293     iplen = IP_HDR_LEN + (tcp->th_off << 2);
  294 
  295     /* Src and Dst are reversed both for ip and tcp */
  296     ip_pack_hdr(pkt, 0, iplen,
  297         rand_uint16(ss_rand),
  298         IP_DF, 64,
  299         IP_PROTO_TCP, src->addr_ip, dst->addr_ip);
  300 
  301     ip_checksum(pkt, iplen);
  302     
  303     if ((res = ip_send(ss_ip, pkt, iplen)) != iplen) {
  304         warn("%s: ip_send(%d): %s", __func__, res, addr_ntoa(dst));
  305         return (-1);
  306     }
  307 
  308     return (0);
  309 }
  310 
  311 void
  312 sigchld_handler(int sig)
  313 {
  314         int save_errno = errno;
  315     int status;
  316     wait(&status);
  317         signal(SIGCHLD, sigchld_handler);
  318         errno = save_errno;
  319 }
  320 
  321 void
  322 printres(struct argument *exp, uint16_t port, char *result)
  323 {
  324     fprintf(stdout, "%s:%d %s\n",
  325         addr_ntoa(&exp->addr), port, result);
  326     fflush(stdout);
  327 }
  328 
  329 void
  330 postres(struct argument *arg, const char *fmt, ...)
  331 {
  332     static char buffer[1024];
  333     va_list ap;
  334 
  335     va_start(ap, fmt);
  336     vsnprintf(buffer, sizeof(buffer), fmt, ap);
  337     va_end(ap);
  338 
  339     if (arg->a_res != NULL)
  340         free(arg->a_res);
  341     if ((arg->a_res = strdup(buffer)) == NULL)
  342         err(1, "%s: strdup", __func__);
  343 }
  344 
  345 /*
  346  * Called when a syn probe times out and we might have to repeat it
  347  */
  348 
  349 void
  350 ss_timeout(int fd, short what, void *parameter)
  351 {
  352     struct argument *arg = parameter;
  353     struct timeval tv;
  354 
  355     if (arg->a_retry < SYNRETRIES) {
  356         arg->a_retry++;
  357         /*
  358          * If this probe fails we are not reducing the retry counter,
  359          * as some of the failures might repeat always, like a host
  360          * on the local network not being reachable or some unrouteable
  361          * address space.
  362          */
  363         if (synlist_probe(arg, arg->a_ports[0].port) == 0)
  364             syn_nsent++;
  365     } else {
  366         printres(arg, arg->a_ports[0].port, "<timeout>");
  367         synlist_remove(arg);
  368         argument_free(arg);
  369         return;
  370     }
  371 
  372     timerclear(&tv);
  373     tv.tv_sec = (arg->a_retry/2 + 1) * SYNWAIT;
  374     tv.tv_usec = rand_uint32(ss_rand) % 1000000L;
  375     
  376     evtimer_add(&arg->ev, &tv);
  377 }
  378 
  379 void
  380 ss_recv_cb(uint8_t *ag, const struct pcap_pkthdr *pkthdr, const uint8_t *pkt)
  381 {
  382     struct interface *inter = (struct interface *)ag;
  383     struct ip_hdr *ip;
  384     struct tcp_hdr *tcp = NULL;
  385     struct addr addr;
  386     struct argument *arg, tmp;
  387     ushort iplen, iphlen;
  388 
  389     /* Everything below assumes that the packet is IPv4 */
  390     if (pkthdr->caplen < inter->if_dloff + IP_HDR_LEN)
  391         return;
  392 
  393     pkt += inter->if_dloff;
  394     ip = (struct ip_hdr *)pkt;
  395 
  396     iplen = ntohs(ip->ip_len);
  397     if (pkthdr->caplen - inter->if_dloff < iplen)
  398         return;
  399 
  400     iphlen = ip->ip_hl << 2;
  401     if (iphlen > iplen)
  402         return;
  403     if (iphlen < sizeof(struct ip_hdr))
  404         return;
  405 
  406     addr_pack(&addr, ADDR_TYPE_IP, IP_ADDR_BITS, &ip->ip_src, IP_ADDR_LEN);
  407 
  408     if (iplen < iphlen + TCP_HDR_LEN)
  409         return;
  410 
  411     tcp = (struct tcp_hdr *)(pkt + iphlen);
  412 
  413     /* See if we get results from our syn probe */
  414     tmp.addr = addr;
  415     if ((arg = SPLAY_FIND(syntree, &synqueue, &tmp)) != NULL) {
  416         struct port *port;
  417         /* Check if the result is coming from the right port */
  418         port = ports_find(arg, ntohs(tcp->th_sport));
  419         if (port == NULL)
  420             return;
  421 
  422         if (!arg->a_hasports)
  423             ports_setup(arg, arg->a_ports, arg->a_nports);
  424 
  425         if (tcp->th_flags & TH_RST) {
  426             printres(arg, port->port, "<refused>");
  427             ports_remove(arg, port->port);
  428             if (arg->a_nports == 0) {
  429                 synlist_remove(arg);
  430                 argument_free(arg);
  431                 return;
  432             }
  433         } else {
  434             ports_markchecked(arg, port);
  435         }
  436 
  437         if (ports_isalive(arg) == 1) {
  438             synlist_remove(arg);
  439             scanhost_ready(arg);
  440         }
  441     }
  442 }
  443 
  444 void
  445 scanssh_init(void)
  446 {
  447     TAILQ_INIT(&readyqueue);
  448     synlist_init();
  449 }
  450 
  451 void
  452 usage(char *name)
  453 {
  454     fprintf(stderr, 
  455         "%s: [-VIERhp] [-s scanners] [-n ports] [-e excludefile] [-i if] [-b alias] <IP address|network>...\n\n"
  456         "\t-V          print version number of scanssh,\n"
  457         "\t-I          do not send identification string,\n"
  458         "\t-E          exit if exclude file is missing,\n"
  459         "\t-R          do not honor exclude file for random addresses,\n"
  460         "\t-p          proxy detection mode; set scanners and ports,\n"
  461         "\t-n <port>   the port number to scan.\n"
  462         "\t-e <file>   exclude the IP addresses and networks in <file>,\n"
  463         "\t-b <alias>  specifies the IP alias to connect from,\n"
  464         "\t-i <if>     specifies the local interface,\n"
  465         "\t-h          this message.\n"
  466         "\t-s <modes>  uses the following modules for scanning:\n",
  467         name);
  468     scanner_print("\t\t");
  469 }
  470 
  471 void
  472 generate_free(struct generate *gen)
  473 {
  474     struct address_node *node;
  475 
  476     /* Remove generator and attached addr nodes */
  477     for (node = TAILQ_FIRST(&gen->gen_anqueue);
  478          node;
  479          node = TAILQ_FIRST(&gen->gen_anqueue)) {
  480         TAILQ_REMOVE(&gen->gen_anqueue, node, an_next);
  481         xfree(node);
  482     }
  483 
  484     TAILQ_REMOVE(&genqueue, gen, gen_next);
  485     xfree(gen);
  486 }
  487 
  488 /*
  489  * Given an IP prefix and mask create all addresses contained
  490  * excluding any addresses specified in the exclude queues.
  491  */
  492 
  493 int
  494 populate(struct argument **pargs, int *nargs)
  495 {
  496     struct generate *gen;
  497     struct addr addr;
  498     struct address_slot *slot = NULL;
  499     struct argument *args;
  500     int count;
  501 
  502     uint32_t i = 0;
  503 
  504     if (!TAILQ_FIRST(&genqueue))
  505         return (-1);
  506 
  507     if ((slot = slot_get()) == NULL)
  508         return (-1);
  509 
  510     args = slot->slot_base;
  511     count = slot->slot_size;
  512 
  513     while (TAILQ_FIRST(&genqueue) && count) {
  514         struct port *ports;
  515         int nports;
  516 
  517         gen = TAILQ_FIRST(&genqueue);
  518         ports = gen->gen_ports;
  519         nports = gen->gen_nports;
  520 
  521         
  522         /* Initalize generator */
  523         if (!gen->gen_current) {
  524             if (gen->gen_flags & FLAGS_USERANDOM)
  525                 rndsboxinit(gen->gen_seed);
  526 
  527             gen->gen_current = gen->gen_start;
  528         }
  529 
  530         while (count) {
  531             if (next_address(gen, &addr) == -1) {
  532                 generate_free(gen);
  533                 break;
  534             }
  535 
  536             DFPRINTF((stderr, "New address: %s\n",
  537                      addr_ntoa(&addr)));
  538 
  539             /* Set up a new address for scanning */
  540             memset(&args[i], 0, sizeof(struct argument));
  541             args[i].addr = addr;
  542             args[i].a_slot = slot;
  543             args[i].a_scanner = ss_scanners[0];
  544             args[i].a_scanneroff = 0;
  545             args[i].a_seqnr = rand_uint32(ss_rand);
  546 
  547             /*
  548              * If we have a local port range from the generator
  549              * use that.  Otherwise, use the ports that have
  550              * been supplied globally.
  551              */
  552             if (ports != NULL) {
  553                 args[i].a_ports = ports;
  554                 args[i].a_nports = nports;
  555             } else {
  556                 args[i].a_ports = ss_ports;
  557                 args[i].a_nports = ss_nports;
  558             }
  559 
  560             evtimer_set(&args[i].ev, ss_timeout, &args[i]);
  561 
  562             slot->slot_ref++;
  563             ss_nhosts++;
  564 
  565             count--;
  566             i++;
  567         }
  568     }
  569 
  570     *pargs = args;
  571     *nargs = i;
  572 
  573     return (0);
  574 }
  575 
  576 int
  577 address_from_offset(struct address_node *an, uint32_t offset,
  578     struct addr *addr)
  579 {
  580     ip_addr_t start, end;
  581     for (; an; an = TAILQ_NEXT(an, an_next)) {
  582         *addr = an->an_start;
  583         start = ntohl(an->an_start.addr_ip);
  584         end = ntohl(an->an_end.addr_ip);
  585         if (start + offset <= end)
  586             break;
  587         offset -= end - start + 1;
  588     }
  589 
  590     if (an == NULL)
  591         return (-1);
  592 
  593     addr->addr_ip = htonl(start + offset);
  594 
  595     return (0);
  596 }
  597 
  598 /*
  599  * get the next address, keep state.
  600  */
  601 
  602 int
  603 next_address(struct generate *gen, struct addr *addr)
  604 {
  605     struct addr ipv4addr, tmp;
  606     uint32_t offset;
  607     int done = 0, random;
  608 
  609     /* Check if generator has been exhausted */
  610     if (gen->gen_n >= gen->gen_max)
  611         return (-1);
  612 
  613     random = gen->gen_flags & FLAGS_USERANDOM;
  614 
  615     do {
  616         /* Get offset into address range */
  617         if (random)
  618             offset = rndgetaddr(gen->gen_bits,
  619                 gen->gen_current);
  620         else
  621             offset = gen->gen_current;
  622         
  623         gen->gen_current += gen->gen_iterate;
  624         
  625         if (address_from_offset(TAILQ_FIRST(&gen->gen_anqueue),
  626             offset, &ipv4addr) == -1)
  627             continue;
  628         
  629         if (!random || rndexclude) {
  630             tmp = exclude(ipv4addr, &excludequeue);
  631             if (addr_cmp(&ipv4addr, &tmp)) {
  632                 if (random) {
  633                     if (gen->gen_flags & FLAGS_SUBTRACTEXCLUDE)
  634                         gen->gen_max--;
  635 
  636                     continue;
  637                 }
  638 
  639                 /* In linear mode, we can skip these */
  640                 offset = gen->gen_current;
  641                 offset += ntohl(tmp.addr_ip) - ntohl(ipv4addr.addr_ip);
  642                 if (offset < gen->gen_current) {
  643                     gen->gen_current = gen->gen_end;
  644                     break;
  645                 }
  646                 gen->gen_current = offset;
  647                 
  648                 if (gen->gen_iterate == 1)
  649                     continue;
  650 
  651                 /* Adjust for splits */
  652                 offset /= gen->gen_iterate;
  653                 offset *= gen->gen_iterate;
  654 
  655                 offset += gen->gen_start;
  656 
  657                 if (offset < gen->gen_current)
  658                     offset += gen->gen_iterate;
  659                 if (offset < gen->gen_current) {
  660                     gen->gen_current = gen->gen_end;
  661                     break;
  662                 }
  663 
  664                 gen->gen_current = offset;
  665                 continue;
  666             }
  667         }
  668         
  669         if (random) {
  670             tmp = exclude(ipv4addr, &rndexclqueue);
  671             if (addr_cmp(&ipv4addr, &tmp)) {
  672                 if (gen->gen_flags & FLAGS_SUBTRACTEXCLUDE)
  673                     gen->gen_max--;
  674                 continue;
  675             }
  676         }
  677         
  678         /* We have an address */
  679         done = 1;
  680     } while ((gen->gen_current < gen->gen_end) && 
  681         (gen->gen_n < gen->gen_max) && !done);
  682 
  683     if (!done)
  684         return (-1);
  685 
  686     gen->gen_n += gen->gen_iterate;
  687 
  688     *addr = ipv4addr;
  689 
  690     return (0);
  691 }
  692 
  693 struct address_node *
  694 address_node_get(char *line)
  695 {
  696     struct address_node *an;
  697 
  698     /* Allocate an address node */
  699     an = xmalloc(sizeof(struct address_node));
  700     memset(an, 0, sizeof(struct address_node));
  701     if (addr_pton(line, &an->an_start) == -1) {
  702         fprintf(stderr, "Can not parse %s\n", line);
  703         goto error;
  704     }
  705     /* Working around libdnet bug */
  706     if (strcmp(line, "0.0.0.0/0") == 0)
  707         an->an_start.addr_bits = 0;
  708 
  709     an->an_bits = an->an_start.addr_bits;
  710 
  711     addr_bcast(&an->an_start, &an->an_end);
  712     an->an_start.addr_bits = IP_ADDR_BITS;
  713     an->an_end.addr_bits = IP_ADDR_BITS;
  714 
  715     return (an);
  716 
  717  error:
  718     free(an);
  719     return (NULL);
  720 }
  721 
  722 /*
  723  * Creates a generator from a command line
  724  * [split(x/n)/][random(x,s)/][(]<address/mask> .... [)]
  725  */
  726 
  727 int
  728 generate_split(struct generate *gen, char **pline)
  729 {
  730     char *line, *end;
  731 
  732     line = *pline;
  733 
  734     if ((end = strstr(line, ")/")) == NULL ||
  735         strchr(line, '/') < end) {
  736         fprintf(stderr, "Split not terminated correctly: %s\n", line);
  737         return (-1);
  738     }
  739 
  740     line =  strsep(pline, "/");
  741 
  742     /* Generate a random scan entry */
  743     if (sscanf(line, "split(%d,%d)/",
  744            &gen->gen_start, &gen->gen_iterate) != 2)
  745         return (-1);
  746         
  747     if (!gen->gen_start || gen->gen_start > gen->gen_iterate) {
  748         fprintf(stderr, "Invalid start/iterate pair: %d/%d\n",
  749             gen->gen_start, gen->gen_iterate);
  750         return (-1);
  751     }
  752 
  753     /* Internally, we start counting at 0 */
  754     gen->gen_start--;
  755 
  756     return (0);
  757 }
  758 
  759 /*
  760  * Creates a generator from a command line
  761  * [split(x/n)/][random(x,s)/][(]<address/mask> .... [)]
  762  */
  763 
  764 int
  765 generate_random(struct generate *gen, char **pline)
  766 {
  767     int i;
  768     char seed[31], *line, *end;
  769 
  770     line = *pline;
  771 
  772     if ((end = strstr(line, ")/")) == NULL ||
  773         strchr(line, '/') < end) {
  774         fprintf(stderr, "Random not terminated correctly: %s\n", line);
  775         return (-1);
  776     }
  777 
  778     line = strsep(pline, "/");
  779 
  780     /* Generate a random scan entry */
  781     seed[0] = '\0';
  782     if (sscanf(line, "random(%d,%30s)/", &gen->gen_max, seed) < 1)
  783         return (-1);
  784         
  785     /* Generate seed from string */
  786     if (strlen(seed)) {
  787         MD5_CTX ctx;
  788         uint8_t digest[16];
  789         uint32_t *tmp = (uint32_t *)digest;
  790 
  791         MD5Init(&ctx);
  792         MD5Update(&ctx, seed, strlen(seed));
  793         MD5Final(digest, &ctx);
  794 
  795         gen->gen_seed = 0;
  796         for (i = 0; i < 4; i ++)
  797             gen->gen_seed ^= *tmp++;
  798                 
  799     } else
  800         gen->gen_seed = rand_uint32(ss_rand);
  801 
  802     gen->gen_flags |= FLAGS_USERANDOM;
  803 
  804     /* If the random numbers exhaust all possible addresses,
  805      * we need to subtract those addresses from the count
  806      * that can not be generated because they were excluded
  807      */
  808     if (!gen->gen_max)
  809         gen->gen_flags |= FLAGS_SUBTRACTEXCLUDE;
  810 
  811     return (0);
  812 }
  813 
  814 int
  815 generate(char *line)
  816 {
  817     struct generate *gen;
  818     struct address_node *an;
  819     uint32_t count, tmp;
  820     char *p;
  821     int bits, i, done;
  822 
  823     gen = xmalloc(sizeof(struct generate));
  824     memset(gen, 0, sizeof(struct generate));
  825     TAILQ_INIT(&gen->gen_anqueue);
  826 
  827     /* Insert in generator queue, on failure generate_free removes it */
  828     TAILQ_INSERT_TAIL(&genqueue, gen, gen_next);
  829 
  830     /* Check for port ranges */
  831     p = strsep(&line, ":");
  832     if (line != NULL) {
  833         if (ports_parse(line,
  834             &gen->gen_ports, &gen->gen_nports) == -1) {
  835             fprintf(stderr, "Bad port range: %s\n", line);
  836             goto fail;
  837         }
  838     }
  839     line = p;
  840 
  841     done = 0;
  842     while (!done) {
  843         done = 1;
  844         if (strncmp(line, "random(", 7) == 0) {
  845             if (gen->gen_flags & FLAGS_USERANDOM) {
  846                 fprintf(stderr,
  847                     "Random already specified: %s\n",
  848                     line);
  849                 goto fail;
  850             }
  851             if (generate_random(gen, &line) == -1)
  852                 goto fail;
  853 
  854             done = 0;
  855         } else if (strncmp(line, "split(", 6) == 0) {
  856             if (gen->gen_iterate) {
  857                 fprintf(stderr,
  858                     "Split already specified: %s\n",
  859                     line);
  860                 goto fail;
  861             }
  862             if (generate_split(gen, &line) == -1)
  863                 goto fail;
  864 
  865             done = 0;
  866         }
  867     }
  868 
  869     /* If no special split is specified, always iterated by 1 */
  870     if (!gen->gen_iterate)
  871         gen->gen_iterate = 1;
  872 
  873     if (line[0] == '(') {
  874         char *end;
  875         
  876         line++;
  877         if ((end = strchr(line, ')')) == NULL) {
  878             fprintf(stderr, "Missing ')' in line: %s\n", line);
  879             goto fail;
  880         }
  881         *end = '\0';
  882         
  883     }
  884 
  885     while (line && (p = strsep(&line, " "))) {
  886         if ((an = address_node_get(p)) == NULL)
  887             goto fail;
  888 
  889         TAILQ_INSERT_TAIL(&gen->gen_anqueue, an, an_next);
  890     }
  891 
  892     /* Try to find out the effective bit range */
  893     count = 0;
  894     for (an = TAILQ_FIRST(&gen->gen_anqueue); an;
  895          an = TAILQ_NEXT(an, an_next)) {
  896         bits = an->an_bits;
  897         if (bits == 0) {
  898             count = -1;
  899             break;
  900         }
  901 
  902         if (count + (1 << (32 - bits)) < count) {
  903             count = -1;
  904             break;
  905         }
  906 
  907         count += 1 << (32 - bits);
  908     }
  909 
  910     /* Try to convert count into a network mask */
  911     bits = 0;
  912     tmp = count;
  913     for (i = -1; tmp; tmp >>= 1, i++) {
  914         if (tmp & 1)
  915             bits++;
  916     }
  917 
  918     /* a count of 01100, results in bits = 29, but it should be 28 */
  919     gen->gen_bits = 32 - i;
  920     if (bits > 1)
  921         gen->gen_bits--;
  922     bits = gen->gen_bits;
  923 
  924     if (gen->gen_flags & FLAGS_USERANDOM) {
  925         if (bits == 0)
  926             gen->gen_end = -1;
  927         else 
  928             gen->gen_end = 1 << (32 - bits);
  929     } else
  930         gen->gen_end = count;
  931 
  932     if (gen->gen_max == 0)
  933         gen->gen_max = count;
  934 
  935     return (0);
  936  fail:
  937     if (gen)
  938         generate_free(gen);
  939 
  940     return (-1);
  941 }
  942 
  943 int
  944 probe_haswork(void)
  945 {
  946     return (TAILQ_FIRST(&genqueue) || entries || !synlist_empty());
  947 }
  948 
  949 void
  950 probe_send(int fd, short what, void *parameter)
  951 {
  952     struct event *ev = parameter;
  953     struct timeval tv;
  954     int ntotal, nprobes, nsent;
  955     extern int scan_nhosts;
  956 
  957     /* Schedule the next probe */
  958     if (probe_haswork()) {
  959         timerclear(&tv);
  960         tv.tv_usec = 1000000L / syn_rate;
  961         evtimer_add(ev, &tv);
  962     } else if (TAILQ_FIRST(&readyqueue) == NULL && !scan_nhosts) {
  963         struct timeval tv;
  964 
  965         /* Terminate the event loop */
  966         timerclear(&tv);
  967         tv.tv_sec = 2;
  968         event_loopexit(&tv);
  969     }
  970 
  971     gettimeofday(&tv, NULL);
  972     timersub(&tv, &syn_start, &tv);
  973 
  974     ntotal = tv.tv_sec * syn_rate + (tv.tv_usec * syn_rate) / 1000000L;
  975     nprobes = ntotal - syn_nsent;
  976 
  977     nsent = 0;
  978     while ((TAILQ_FIRST(&genqueue) || entries) && nsent < nprobes) {
  979         /* Create new entries, if we need them */
  980         if (!entries && TAILQ_FIRST(&genqueue)) {
  981             if (populate(&args, &entries) == -1) {
  982                 /* 
  983                  * We fail if we have used up our memory.
  984                  * We also need to consume our number of
  985                  * sent packets.
  986                  */
  987                 syn_nsent = ntotal;
  988                 entries = 0;
  989                 break;
  990             }
  991             continue;
  992         }
  993 
  994         entries--;
  995         args[entries].a_retry = 0;
  996 
  997         if (TAILQ_FIRST(&socks_host) == NULL) {
  998             synlist_insert(&args[entries]);
  999 
 1000             /* 
 1001              * On failure, synlist_insert already scheduled
 1002              * a retransmit.
 1003              */
 1004             synlist_probe(&args[entries],
 1005                 args[entries].a_ports[0].port);
 1006         } else {
 1007             struct argument *arg = &args[entries];
 1008             if (!arg->a_hasports)
 1009                 ports_setup(arg, arg->a_ports, arg->a_nports);
 1010             scanhost_ready(arg);
 1011         }
 1012 
 1013         nsent++;
 1014         syn_nsent++;
 1015     }
 1016 }
 1017 
 1018 int
 1019 parse_socks_host(char *optarg)
 1020 {
 1021     char *host;
 1022     while ((host = strsep(&optarg, ",")) != NULL) {
 1023         /*
 1024          * Parse the address of a SOCKS proxy that we are
 1025          * using for all connections.
 1026          */
 1027         struct socks_host *single_host;
 1028 
 1029         char *address = strsep(&host, ":");
 1030         if (host == NULL || *host == '\0')
 1031             return (-1);
 1032 
 1033         single_host = calloc(1, sizeof(struct socks_host));
 1034         if (single_host == NULL)
 1035             err(1, "calloc");
 1036         if (addr_pton(address, &single_host->host) == -1)
 1037             return (-1);
 1038 
 1039         if ((single_host->port = atoi(host)) == 0)
 1040             return (-1);
 1041 
 1042         TAILQ_INSERT_TAIL(&socks_host, single_host, next);
 1043     }
 1044 
 1045     return (0);
 1046 }
 1047 
 1048 int
 1049 main(int argc, char **argv)
 1050 {
 1051     struct event ev_send;
 1052     char *name, *dev = NULL, *scanner = "ssh";
 1053     char *default_ports = "22";
 1054     int ch;
 1055     struct timeval tv, tv_start, tv_end;
 1056     struct rlimit rl;
 1057     int failonexclude = 0;
 1058     int milliseconds;
 1059 
 1060     ssh_sendident = 1;
 1061 
 1062     TAILQ_INIT(&socks_host);
 1063 
 1064     name = argv[0];
 1065     while ((ch = getopt(argc, argv, "VIhdpm:u:s:i:e:n:r:ER")) != -1)
 1066         switch(ch) {
 1067         case 'V':
 1068             fprintf(stderr, "ScanSSH %s\n", VERSION);
 1069             exit(0);
 1070 #ifdef DEBUG
 1071         case 'd':
 1072             debug++;
 1073             break;
 1074 #endif
 1075         case 'I':
 1076             ssh_sendident = 0;
 1077             break;
 1078         case 'p':
 1079             scanner = "http-proxy,http-connect,socks5,socks4,telnet-proxy,ssh";
 1080             default_ports = "23,22,80,81,808,1080,1298,3128,6588,4480,8080,8081,8000,8100,9050";
 1081             break;
 1082         case 'm':
 1083             max_scanqueue_size = atoi(optarg);
 1084             if (max_scanqueue_size == 0) {
 1085                 usage(name);
 1086                 exit(1);
 1087             }
 1088             break;
 1089         case 'u': 
 1090             if (parse_socks_host(optarg) == -1) {
 1091                 usage(name);
 1092                 exit(1);
 1093             }
 1094             break;
 1095         case 's':
 1096             scanner = optarg;
 1097             break;
 1098         case 'i':
 1099             dev = optarg;
 1100             break;
 1101         case 'n':
 1102             if (ports_parse(optarg, &ss_ports, &ss_nports) == -1) {
 1103                 usage(name);
 1104                 exit(1);
 1105             }
 1106             break;
 1107         case 'e':
 1108             excludefile = optarg;
 1109             /* FALLTHROUGH */
 1110         case 'E':
 1111             failonexclude = 1;
 1112             break;
 1113         case 'R':
 1114             rndexclude=0;
 1115             break;
 1116         case 'r':
 1117             syn_rate = atoi(optarg);
 1118             if (syn_rate == 0) {
 1119                 fprintf(stderr, "Bad syn probe rate: %s\n",
 1120                     optarg);
 1121                 usage(name);
 1122                 exit(1);
 1123             }
 1124             break;
 1125         case 'h':
 1126         default:
 1127             usage(name);
 1128             exit(1);
 1129         }
 1130 
 1131     argc -= optind;
 1132     argv += optind;
 1133 
 1134     if (scanner_parse(scanner) == -1)
 1135         errx(1, "bad scanner: %s", scanner);
 1136 
 1137     if ((ss_rand = rand_open()) == NULL)
 1138         err(1, "rand_open");
 1139 
 1140     if ((ss_ip = ip_open()) == NULL)
 1141         err(1, "ip_open");
 1142 
 1143     scanssh_init();
 1144     
 1145     event_init();
 1146 
 1147     interface_initialize();
 1148 
 1149     /* Initialize the specified interfaces */
 1150     interface_init(dev, 0, NULL,
 1151         "(tcp[13] & 18 = 18 or tcp[13] & 4 = 4)");
 1152 
 1153     /* Raising file descriptor limits */
 1154     rl.rlim_max = RLIM_INFINITY;
 1155     rl.rlim_cur = RLIM_INFINITY;
 1156     if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
 1157         /* Linux does not seem to like this */
 1158         if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
 1159             err(1, "getrlimit: NOFILE");
 1160         rl.rlim_cur = rl.rlim_max;
 1161         if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
 1162             err(1, "setrlimit: NOFILE");
 1163     }
 1164 
 1165     /* Raising the memory limits */
 1166     rl.rlim_max = RLIM_INFINITY;
 1167     rl.rlim_cur = MAXSLOTS * EXPANDEDARGS * sizeof(struct argument) * 2;
 1168     if (setrlimit(RLIMIT_DATA, &rl) == -1) {
 1169         /* Linux does not seem to like this */
 1170         if (getrlimit(RLIMIT_DATA, &rl) == -1)
 1171             err(1, "getrlimit: DATA");
 1172         rl.rlim_cur = rl.rlim_max;
 1173         if (setrlimit(RLIMIT_DATA, &rl) == -1)
 1174             err(1, "setrlimit: DATA");
 1175     }
 1176     
 1177        
 1178     /* revoke privs */
 1179 #ifdef HAVE_SETEUID
 1180         seteuid(getuid());
 1181 #endif /* HAVE_SETEUID */
 1182         setuid(getuid());
 1183 
 1184     /* Set up our port ranges */
 1185     if (ss_nports == 0) {
 1186         if (ports_parse(default_ports, &ss_ports, &ss_nports) == -1)
 1187             errx(1, "Error setting up port list");
 1188     }
 1189 
 1190     if (setupexcludes() == -1 && failonexclude) {
 1191         warn("fopen: %s", excludefile);
 1192         exit(1);
 1193     }
 1194 
 1195     memset(slots, 0, sizeof(slots));
 1196 
 1197     TAILQ_INIT(&genqueue);
 1198 
 1199     while (argc) {
 1200         if (generate(argv[0]) == -1)
 1201             warnx("generate failed on %s", argv[0]);
 1202 
 1203         argv++;
 1204         argc--;
 1205     }
 1206 
 1207     if (!TAILQ_FIRST(&genqueue))
 1208         errx(1, "nothing to scan");
 1209 
 1210     gettimeofday(&syn_start, NULL);
 1211 
 1212     evtimer_set(&ev_send, probe_send, &ev_send);
 1213     timerclear(&tv);
 1214     tv.tv_usec = 1000000L / syn_rate;
 1215     evtimer_add(&ev_send, &tv);
 1216 
 1217     gettimeofday(&tv_start, NULL);
 1218 
 1219     event_dispatch();
 1220 
 1221     /* Measure our effective host scan rate */
 1222 
 1223     gettimeofday(&tv_end, NULL);
 1224 
 1225     timersub(&tv_end, &tv_start, &tv_end);
 1226 
 1227     milliseconds = tv_end.tv_sec * 1000 + tv_end.tv_usec % 1000;
 1228 
 1229     fprintf(stderr, "Effective host scan rate: %.2f hosts/s\n",
 1230         (float)ss_nhosts / (float) milliseconds * 1000.0);
 1231 
 1232     return (1);
 1233 }
 1234 
 1235 void
 1236 ports_timeout(int fd, short what, void *parameter)
 1237 {
 1238     struct port_scan *ps = parameter;
 1239     struct argument *arg = ps->arg;
 1240     struct timeval tv;
 1241 
 1242     if (ps->count < SYNRETRIES) {
 1243         ps->count++;
 1244         /*
 1245          * If this probe fails we are not reducing the retry counter,
 1246          * as some of the failures might repeat always, like a host
 1247          * on the local network not being reachable or some unrouteable
 1248          * address space,
 1249          */
 1250         if (synlist_probe(arg, ps->port) == -1)
 1251             goto reschedule;
 1252 
 1253         syn_nsent++;
 1254     } else {
 1255         printres(arg, ps->port, "<timeout>");
 1256         ports_remove(arg, ps->port);
 1257         if (arg->a_nports == 0) {
 1258             synlist_remove(arg);
 1259             argument_free(arg);
 1260             return;
 1261         }
 1262         return;
 1263     }
 1264 
 1265  reschedule:
 1266     timerclear(&tv);
 1267     tv.tv_sec += (arg->a_retry/2 + 1) * SYNWAIT;
 1268     tv.tv_usec = rand_uint32(ss_rand) % 1000000L;
 1269     
 1270     evtimer_add(&arg->ev, &tv);
 1271 }
 1272 
 1273 /* Mark a port as checked - meaning that we can connect to it */
 1274 
 1275 void
 1276 ports_markchecked(struct argument *arg, struct port *port)
 1277 {
 1278     struct port_scan *ps = port->scan;
 1279 
 1280     DNFPRINTF(2, (stderr, "%s: %s:%d marked alive\n",
 1281               __func__, addr_ntoa(&arg->addr), port->port));
 1282 
 1283     if (ps == NULL) {
 1284         /* Populates scan structures */
 1285         ports_isalive(arg);
 1286 
 1287         /* This argument has a new memory area now */
 1288         port = ports_find(arg, port->port);
 1289         ps = port->scan;
 1290     }
 1291 
 1292     event_del(&ps->ev);
 1293     ps->flags |= PORT_CHECKED;
 1294 }
 1295 
 1296 /* Checks if all ports for this host have been checked to be alive */
 1297 
 1298 int
 1299 ports_isalive(struct argument *arg)
 1300 {
 1301     struct port_scan *ps;
 1302     int i;
 1303 
 1304     /* We already populated the structures */
 1305     if (arg->a_ports[0].scan != NULL) {
 1306         for (i = 0; i < arg->a_nports; i++)
 1307             if (!(arg->a_ports[i].scan->flags & PORT_CHECKED))
 1308                 return (0);
 1309         for (i = 0; i < arg->a_nports; i++) {
 1310             ps = arg->a_ports[i].scan;
 1311             event_del(&ps->ev);
 1312             free(ps);
 1313             arg->a_ports[i].scan = NULL;
 1314         }
 1315         return (1);
 1316     }
 1317 
 1318     /* This host was newly detected as alive */
 1319     for (i = 0; i < arg->a_nports; i++) {
 1320         struct timeval tv;
 1321 
 1322         if ((ps = calloc(1, sizeof(struct port_scan))) == NULL)
 1323             err(1, "%s: calloc");
 1324         arg->a_ports[i].scan = ps;
 1325 
 1326         ps->arg = arg;
 1327         ps->port = arg->a_ports[i].port;
 1328         evtimer_set(&ps->ev, ports_timeout, ps);
 1329 
 1330         timerclear(&tv);
 1331         tv.tv_usec = rand_uint32(ss_rand) % 1000000L;
 1332         
 1333         evtimer_add(&ps->ev, &tv);
 1334     }
 1335 
 1336     return (0);
 1337 }
 1338 
 1339 /* Copy the ports list to the argument and use it for scanning */
 1340 
 1341 int
 1342 ports_setup(struct argument *arg, struct port *ports, int nports)
 1343 {
 1344     arg->a_hasports = 1;
 1345     arg->a_nports = nports;
 1346     if ((arg->a_ports = calloc(nports, sizeof(struct port))) == NULL)
 1347         err(1, "%s: calloc", __func__);
 1348 
 1349     memcpy(arg->a_ports, ports, nports * sizeof(struct port));
 1350 
 1351     return (0);
 1352 }
 1353 
 1354 struct port *
 1355 ports_find(struct argument *arg, uint16_t port)
 1356 {
 1357     int i;
 1358 
 1359     for (i = 0; i < arg->a_nports; i++)
 1360         if (arg->a_ports[i].port == port)
 1361             return (&arg->a_ports[i]);
 1362 
 1363     return (NULL);
 1364 }
 1365 
 1366 /* Remove one port from the list and reduce the number of available ports */
 1367 
 1368 int
 1369 ports_remove(struct argument *arg, uint16_t port)
 1370 {
 1371     int i;
 1372 
 1373     for (i = 0; i < arg->a_nports; i++) {
 1374         if (arg->a_ports[i].port == port) {
 1375             /* Deallocate the scan structure if necessary */
 1376             if (arg->a_ports[i].scan != NULL) {
 1377                 event_del(&arg->a_ports[i].scan->ev);
 1378                 free(arg->a_ports[i].scan);
 1379             }
 1380             arg->a_nports--;
 1381             if (i < arg->a_nports) {
 1382                 arg->a_ports[i] = arg->a_ports[arg->a_nports];
 1383             } else if (arg->a_nports == 0) {
 1384                 free (arg->a_ports);
 1385                 arg->a_ports = NULL;
 1386             }
 1387             return (0);
 1388         }
 1389     }
 1390 
 1391     return (-1);
 1392 }
 1393 
 1394 /* Parse the list of ports and put them into an array */
 1395 
 1396 int
 1397 ports_parse(char *argument, struct port **pports, int *pnports)
 1398 {
 1399     char buf[1024], *line = buf;
 1400     char *p, *e;
 1401     int size, count, val;
 1402     struct port *ports = *pports;
 1403     struct port port;
 1404 
 1405     strlcpy(buf, argument, sizeof(buf));
 1406 
 1407     memset(&port, 0, sizeof(port));
 1408 
 1409     count = 0;
 1410     size = 0;
 1411     while ((p = strsep(&line, ",")) != NULL) {
 1412         val = strtoul(p, &e, 10);
 1413         if (p[0] == '\0' || *e != '\0')
 1414             return (-1);
 1415         if (val <= 0 || val > 65535)
 1416             return (-1);
 1417 
 1418         if (count >= size) {
 1419             struct port *tmpports;
 1420             if (size == 0)
 1421                 size = 10;
 1422             else
 1423                 size <<= 1;
 1424 
 1425             tmpports = realloc(ports, size*sizeof(struct port));
 1426             if (tmpports == NULL)
 1427                 err(1, "realloc");
 1428             ports = tmpports;
 1429             memset(&ports[count], 0,
 1430                 (size - count) * sizeof(struct port));
 1431         }
 1432 
 1433         port.port = val;
 1434         ports[count++] = port;
 1435     }
 1436 
 1437     if (count == 0)
 1438         return (-1);
 1439 
 1440     *pports = ports;
 1441     *pnports = count;
 1442     return (0);
 1443 }
 1444 
 1445 /* Parse the list of scanners and put them into an array */
 1446 
 1447 int
 1448 scanner_parse(char *argument)
 1449 {
 1450     char buf[1024], *line = buf;
 1451     char *p;
 1452     int size, count;
 1453     struct scanner *scanner;
 1454 
 1455     strlcpy(buf, argument, sizeof(buf));
 1456 
 1457     count = 0;
 1458     size = 0;
 1459     while ((p = strsep(&line, ",")) != NULL) {
 1460         if ((scanner = scanner_find(p)) == NULL)
 1461             return (-1);
 1462 
 1463         if (count >= size) {
 1464             struct scanner **tmpscanners;
 1465             if (size == 0)
 1466                 size = 10;
 1467             else
 1468                 size <<= 1;
 1469 
 1470             tmpscanners = realloc(ss_scanners,
 1471                 size * sizeof(struct scanner *));
 1472             if (tmpscanners == NULL)
 1473                 err(1, "realloc");
 1474             ss_scanners = tmpscanners;
 1475             memset(&ss_scanners[count], 0,
 1476                 (size - count) * sizeof(struct scanner *));
 1477         }
 1478         ss_scanners[count++] = scanner;
 1479     }
 1480 
 1481     if (count == 0)
 1482         return (-1);
 1483 
 1484     ss_nscanners = count;
 1485     return (0);
 1486 }