OpenVAS Libraries  9.0.3
nasl_builtin_openvas_tcp_scanner.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004 Michel Arboi <mikhail@nessus.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2,
6  * as published by the Free Software Foundation
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16  *
17  */
18 
19 #include <unistd.h> /* for close() */
20 #include <fcntl.h> /* for fcntl() */
21 #include <string.h> /* for strcmp() */
22 #include <stdio.h> /* for fprintf() */
23 #include <stdlib.h> /* for atoi() */
24 #include <sys/types.h> /* for socket() */
25 #include <sys/socket.h> /* for socket() */
26 #include <errno.h> /* for errno() */
27 #include <sys/time.h> /* for gettimeofday() */
28 #include <sys/resource.h> /* for getrlimit() */
29 #include <netdb.h> /* for getprotobyname() */
30 
31 #include <glib.h>
32 
33 #include "../misc/arglists.h" /* for struct arglist */
34 #include "../misc/plugutils.h" /* for find_in_path */
35 #include "../misc/prefs.h" /* for prefs_get */
36 #include "../misc/openvas_logging.h"
37 #include "../misc/network.h"
38 
39 #include "nasl_lex_ctxt.h"
40 
41 #ifdef LINUX
42 #include <netinet/tcp.h>
43 #include <netinet/ip.h>
44 #endif
45 #include <limits.h>
46 #include <math.h> /* for sqrt(), floor() */
47 
48 #if ! defined FD_SETSIZE || FD_SETSIZE > 1024
49 #define GRAB_MAX_SOCK 1024
50 #else
51 #define GRAB_MAX_SOCK FD_SETSIZE
52 #endif
53 
54 #if ! defined FD_SETSIZE || FD_SETSIZE > 32
55 #define GRAB_MIN_SOCK 32
56 #else
57 #define GRAB_MIN_SOCK FD_SETSIZE
58 #warn "FD_SETSIZE is lower than 32"
59 #endif
60 
61 #if ! defined FD_SETSIZE || FD_SETSIZE > 128
62 #define GRAB_MAX_SOCK_SAFE 128
63 #else
64 #define GRAB_MAX_SOCK_SAFE FD_SETSIZE
65 #warn "FD_SETSIZE is lower than 128"
66 #endif
67 
68 #define MAX_PASS_NB 16
69 
70 #ifndef MAXINT
71 #define MAXINT 0x7fffffffL
72 #endif
73 
74 typedef struct {
75  int fd;
76  struct timeval tictac; /* open time */
77  unsigned short port;
78  unsigned char state;
80 
81 #define DIFFTV(t1,t2) (t1.tv_sec - t2.tv_sec + (t1.tv_usec - t2.tv_usec) / 1000000)
82 #define DIFFTVu(t1,t2) ((t1.tv_sec - t2.tv_sec) * 1000000.0 + (t1.tv_usec - t2.tv_usec))
83 
84 #define GRAB_SOCKET_UNUSED 0
85 #define GRAB_SOCKET_OPENING 1
86 #define GRAB_SOCKET_OPEN 2
87 
88 #define GRAB_PORT_UNKNOWN 0
89 #define GRAB_PORT_CLOSED 1
90 #define GRAB_PORT_OPEN 2
91 #define GRAB_PORT_SILENT 3
92 #define GRAB_PORT_REJECTED 4
93 #define GRAB_PORT_NOT_TESTED 254
94 #define GRAB_PORT_TESTING 255
95 
96 #ifndef DEBUG
97 #define DEBUG 0
98 #endif
99 #if DEBUG > 2
100 # define DISPLAY
101 #endif
102 #define COMPUTE_RTT
103 /*
104  * RTT is always estimated (at least, the maximum is remembered)
105  * If you want to enable the "statistics", define COMPUTE_RTT and link
106  * the plugin with libm (we need sqrt)
107  */
108 /* Linux re-sends a SYN packet after 3 s
109  * anyway, I don't think that we can have a RTT bigger than 2 s
110  */
111 #define MAX_SANE_RTT 2000000 /* micro-seconds */
112 
113 static int
114 my_socket_close(int s)
115 {
116 #ifndef SO_LINGER
117  if (shutdown(s, 2) < 0)
118 #if DEBUG > 0
119  perror("shutdown")
120 #endif
121  ;
122 #endif
123  return close(s);
124 }
125 
126 static int std_port(int port)
127 {
128  return 0;
133 }
134 
135 static int
136 double_check_std_ports(unsigned char* ports_states)
137 {
138  int port, tbd_nb = 0;
139 
140  for (port = 1; port <= 65535; port ++)
141  if (std_port(port) && ports_states[port] == GRAB_PORT_SILENT)
142  {
143  ports_states[port] = GRAB_PORT_UNKNOWN;
144  tbd_nb ++;
145  }
146  else if (ports_states[port] == GRAB_PORT_UNKNOWN)
147  {
148  log_legacy_write ("openvas_tcp_scanner: bug in double_check_std_ports!"
149  " Unknown port %d status", port);
150  tbd_nb ++;
151  }
152 #if DEBUG > 0
153  log_legacy_write ("opanvas_tcp_scanner: double_check_std_ports found %d"
154  " filtered standard ports\n", tbd_nb);
155 #endif
156  return tbd_nb;
157 }
158 
159 static int
160 banner_grab(const struct in6_addr *pia, const char* portrange,
161  const int read_timeout,
162  int min_cnx,
163  int max_cnx,
164  struct arglist *desc)
165 {
166  char buf[2048], kb[64];
167  int s, tcpproto, pass;
168  struct protoent *proto;
169  fd_set rfs, wfs, efs;
170  struct timeval timeout, ti;
171 #if DEBUG > 0
172  struct timeval ti1;
173 #endif
174  struct sockaddr_in sa;
175  struct sockaddr_in6 sa6;
176  int len;
177  int retval;
178  int port = 23;
179  int imax, i, j, scanned_ports, x, opt;
180  unsigned int optsz;
181  int minport;
182  unsigned char ports_states[65536];
183  grab_socket_t sockets[GRAB_MAX_SOCK];
184  int open_sock_nb, open_sock_max, open_sock_max2;
185  int unfiltered_ports_nb, filtered_ports_nb;
186  int dropped_nb, timeout_nb, dropped_flag = 0;
187  int old_filtered = -1, old_opened = -1;
188  int open_ports_nb, closed_ports_nb;
189  int untested_ports_nb, total_ports_nb;
190 #if DEBUG > 1
191  int done_ports_nb;
192 #endif
193  int cnx_max[3], rtt_max[3], rtt_min[3], ping_rtt = 0;
194 #if defined COMPUTE_RTT
195  double rtt_sum[3], rtt_sum2[3];
196  int rtt_nb[3];
197  static const char *rtt_type[] = {"unfiltered", "open", "closed" };
198 #endif
199  time_t start_time = time(NULL), start_time_1pass, end_time;
200  long diff_time, diff_time1;
201  int rst_rate_limit_flag = 0, doublecheck_flag = 0;
202 #if defined COMPUTE_RTT
203  double mean, sd = -1.0, emax = -1.0;
204 #endif
205 
206  proto = getprotobyname("tcp");
207  if (proto == NULL)
208  {
209  perror("tcp");
210  return -1;
211  }
212  tcpproto = proto->p_proto;
213 
214  for (i = 0; i < sizeof(ports_states) / sizeof(*ports_states); i ++)
215  ports_states[i] = GRAB_PORT_NOT_TESTED;
216  scanned_ports = 0;
217  for (i = 0; i < 3; i ++)
218  {
219 #if defined COMPUTE_RTT
220  rtt_sum[i] = rtt_sum2[i] = 0.0;
221  rtt_nb[i] = 0;
222 #endif
223  rtt_max[i] = cnx_max[i] = 0;
224  rtt_min[i] = MAXINT;
225  }
226 
227 
228  {
229  char *k;
230  int type = 0;
231  k = plug_get_key (desc, "/tmp/ping/RTT", &type, 0);
232  if (type == ARG_STRING && k != NULL)
233  ping_rtt = atoi(k);
234  else if (type == ARG_INT)
235  ping_rtt = GPOINTER_TO_SIZE(k);
236  else if (type >= 0)
237  log_legacy_write ("openvas_tcp_scanner: unknown key type %d", type);
238  g_free (k);
239  if (ping_rtt < 0 || ping_rtt > MAX_SANE_RTT)
240  ping_rtt = 0;
241 #if DEBUG > 0
242  else
243  log_legacy_write ("openvas_tcp_scanner(%s): ping_rtt=%g s",
244  inet_ntoa(*pia), ping_rtt / 1e6);
245 #endif
246  }
247 
248  {
249  char *p, *q;
250  int po1, po2 = 0;
251  p = (char*)portrange;
252  untested_ports_nb = 0;
253 
254  if (p)
255  while (*p != '\0')
256  {
257  while (*p == ',')
258  p ++;
259 
260  /* Scanner accepts only T:1-3,6,U:103-333,770 due to getpts. */
261 
262  if (*p == 'T' && p[1] && p[1] == ':')
263  /* Skip over the leading "T:". */
264  p += 2;
265  else if (*p == 'U' && p[1] && p[1] == ':')
266  /* "U:" for UDP. Skip the rest. */
267  break;
268 
269  if (*p == '-')
270  {
271  po1 = 1;
272  q = p + 1;
273  po2 = strtol(q, &p, 10);
274  if (q == p)
275  {
276  log_legacy_write ("openvas_tcp_scanner: Cannot parse '%s'",
277  p);
278  return -1;
279  }
280  }
281  else
282  {
283  po1 = strtol(p, &q, 10);
284  if (q == p)
285  {
286  log_legacy_write ("openvas_tcp_scanner: Cannot parse '%s'",
287  p);
288  return -1;
289  }
290  if (*q == ',')
291  {
292  p = q + 1;
293  po2 = po1;
294  }
295  else if (*q == '\0')
296  {
297  p = q;
298  po2 = po1;
299  }
300  else if (*q == '-')
301  {
302  if (q[1] == '\0')
303  {
304  po2 = 65535;
305  p = q+1;
306  }
307  else
308  {
309  po2 = strtol(q+1, &p, 10);
310  if (q+1 == p)
311  {
313  ("openvas_tcp_scanner: Cannot parse '%s'", p);
314  return -1;
315  }
316  }
317  }
318  }
319  for (i = po1; i <= po2; i ++)
320  {
321  ports_states[i] = GRAB_PORT_UNKNOWN;
322  untested_ports_nb ++;
323  }
324  }
325  else
326  {
327  log_legacy_write ("openvas_tcp_scanner: port list empty");
328  return -1;
329  }
330  }
331 
332  for (i = 0; i < max_cnx; i ++)
333  {
334  sockets[i].state = GRAB_SOCKET_UNUSED;
335  sockets[i].fd = -1;
336  }
337 
338  open_sock_nb = 0;
339  open_sock_max = min_cnx; open_sock_max2 = max_cnx;
340 
341  open_ports_nb = closed_ports_nb = filtered_ports_nb = unfiltered_ports_nb = 0;
342 
343  for (pass = 1; pass <= MAX_PASS_NB; pass ++)
344  {
345  int open_ports_nb1 = 0, closed_ports_nb1 = 0;
346  int wait_sock_nb = 0;
347 
348  minport = 1;
349  start_time_1pass = time(NULL);
350 #if DEBUG > 0
351  log_legacy_write ("openvas_tcp_scanner(%s): pass #%d: open_sock_max=%d\topen_sock_max2=%d\n", inet_ntoa(*pia), pass, open_sock_max, open_sock_max2);
352 #endif
353 
354  FD_ZERO(&rfs); FD_ZERO(&wfs); imax = -1;
355 
356  while (scanned_ports < 65535)
357  {
358  total_ports_nb = unfiltered_ports_nb + filtered_ports_nb + untested_ports_nb;
359 #if DEBUG > 0
360  log_legacy_write ("openvas_tcp_scanner(%s): %d / %d = %02d%% - %d ports remaining\n",
361  inet_ntoa(*pia),
362  unfiltered_ports_nb + filtered_ports_nb,
363  total_ports_nb,
364  (unfiltered_ports_nb + filtered_ports_nb) * 100 /
365  (total_ports_nb > 0 ? total_ports_nb : 1),
366  untested_ports_nb);
367 #endif
368  while (open_sock_nb < open_sock_max)
369  {
370  for (port = minport; port <= 65535 && ports_states[port] != GRAB_PORT_UNKNOWN; port ++)
371  ;
372  if (port > 65535)
373  break;
374  minport = port;
375 
376  ports_states[port] = GRAB_PORT_TESTING;
377 #if DEBUG > 2
378  log_legacy_write ("openvas_tcp_scanner: Trying %s:%d\n", inet_ntoa(*pia), port);
379 #endif
380  if(IN6_IS_ADDR_V4MAPPED(pia))
381  {
382  s = socket(PF_INET, SOCK_STREAM, tcpproto);
383  }
384  else
385  {
386  s = socket(PF_INET6, SOCK_STREAM, tcpproto);
387  }
388  if (s < 0)
389  {
390  if (errno == ENFILE) /* File table overflow */
391  {
392  open_sock_max = open_sock_max2 = open_sock_nb / 2 - 1;
393  /* NB: if open_sock_max2 < 0, the scanner aborts */
394 #if DEBUG > 0
395  /* DEBUG: otherwise, we print a less frigthtening message */
396  perror("socket");
397  log_legacy_write ("openvas_tcp_scanner(%s): Reducing the number of maximum open connections to %d [ENFILE]\n", inet_ntoa(*pia), open_sock_max);
398 #endif
399  continue;
400  }
401  else if (errno == EMFILE) /* Too many open files */
402  {
403  x = open_sock_nb / 16; /* 6.25% */
404  open_sock_max = open_sock_max2 =
405  open_sock_nb - (x > 0 ? x : 1);
406  /* NB: if open_sock_max2 < 0, the scanner aborts */
407 #if DEBUG > 0
408  /* DEBUG: otherwise, we print a less frigthtening message */
409  perror("socket");
410  log_legacy_write ("openvas_tcp_scanner(%s): Reducing the number of maximum open connections to %d [EMFILE]\n", inet_ntoa(*pia), open_sock_max);
411 #endif
412  continue;
413  }
414  else
415  {
416  perror("socket");
417  return -1;
418  }
419  }
420 #if defined FD_SETSIZE
421  if (s >= FD_SETSIZE)
422  {
423  open_sock_max --;
424  open_sock_max2 --;
425 #if DEBUG > 0
426  log_legacy_write ("openvas_tcp_scanner(%s): socket=%d > FD_SETSIZE=%d - reducing the number of maximum open connections to %d\n", inet_ntoa(*pia), s, FD_SETSIZE, open_sock_max);
427 #endif
428  if (close(s) < 0)
429  perror("close");
430  continue;
431  }
432 #endif
433 
434  if ((x = fcntl(s, F_GETFL)) < 0)
435  {
436  perror("fcntl(F_GETFL)");
437  return -1;
438  }
439  if (fcntl(s, F_SETFL, x | O_NONBLOCK) < 0)
440  {
441  perror("fcntl(F_SETFL)");
442  return -1;
443  }
444 
445 #ifdef SO_LINGER
446  {
447  struct linger l;
448 
449  l.l_onoff = 0; l.l_linger = 0;
450  if (setsockopt(s, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0)
451  perror("setsockopt(SO_LINGER)");
452  }
453 #endif
454 #if 0 /* defined TCP_NODELAY */
455  x = 1;
456  if (setsockopt(s, SOL_TCP, TCP_NODELAY, &x, sizeof(x)) < 0)
457  perror("setsockopt(TCP_NODELAY");
458 #endif
459 #if 0 /* defined TCP_QUICKACK */
460  x = 1;
461  if (setsockopt(s, SOL_TCP, TCP_QUICKACK, &x, sizeof(x)) < 0)
462  perror("setsockopt(TCP_QUICKACK");
463 #endif
464 #if defined LINUX && defined IPTOS_RELIABILITY
465  /*
466  * IP TOS (RFC791) is obsoleted by RFC2474
467  * RFC3168 deprecates IPTOS_MINCOST, as it conflicts with
468  * the "ECN capable" flags
469  */
470  x = IPTOS_RELIABILITY;
471  if (setsockopt(s, SOL_IP, IP_TOS, &x, sizeof(x)) < 0)
472  perror("setsockopt(IP_TOS");
473 #endif
474  if(IN6_IS_ADDR_V4MAPPED(pia))
475  {
476  sa.sin_addr.s_addr = pia->s6_addr32[3];
477  sa.sin_family = AF_INET;
478  sa.sin_port = htons(port);
479  len = sizeof(struct sockaddr_in);
480  retval = connect(s, (struct sockaddr*)&sa, len);
481  }
482  else
483  {
484  memcpy(&sa6.sin6_addr, pia, sizeof(struct in6_addr));
485  sa6.sin6_family = AF_INET6;
486  sa6.sin6_port = htons(port);
487  len = sizeof(struct sockaddr_in6);
488  retval = connect(s, (struct sockaddr*)&sa6, len);
489  }
490  if (retval < 0)
491  {
492  switch (errno)
493  {
494  case EINPROGRESS:
495  case EALREADY:
496  sockets[open_sock_nb].fd = s;
497  sockets[open_sock_nb].port = port;
498  sockets[open_sock_nb].state = GRAB_SOCKET_OPENING;
499  (void) gettimeofday(&sockets[open_sock_nb].tictac, NULL);
500  open_sock_nb ++;
501  FD_SET(s, &wfs);
502  if (s > imax) imax = s;
503  break;
504 
505  case EAGAIN:
506  x = open_sock_nb / 16; /* 6.25% */
507  open_sock_max = open_sock_max2 =
508  open_sock_nb - (x > 0 ? x : 1);
509  /* If open_sock_max2 < 0, the scanner aborts */
510 #if DEBUG > 0
511  log_legacy_write ("openvas_tcp_scanner(%s): Reducing the number of maximum open connections to %d [EAGAIN]\n", inet_ntoa(*pia), open_sock_max);
512 #endif
513  continue;
514 
515  case ECONNREFUSED:
516  ports_states[port] = GRAB_PORT_CLOSED;
517 #ifdef DISPLAY
518  printf(">>> %d: CLOSED\n", sockets[i].port);
519 #endif
520  my_socket_close(s);
521  unfiltered_ports_nb ++;
522  closed_ports_nb ++;
523  closed_ports_nb1 ++;
524  untested_ports_nb --;
525  continue;
526 
527  case ENETUNREACH:
528  case EHOSTUNREACH:
529  ports_states[port] = GRAB_PORT_REJECTED;
530 #ifdef DISPLAY
531  printf(">>> %d: FILTERED\n", sockets[i].port);
532 #endif
533  my_socket_close(s);
534  filtered_ports_nb ++;
535  untested_ports_nb --;
536  continue;
537 
538  default:
539  perror("connect");
540  return -1;
541  }
542  }
543  else /* This should not happen! */
544  {
545  sockets[open_sock_nb].fd = s;
546  sockets[open_sock_nb].port = port;
547  sockets[open_sock_nb].state = GRAB_SOCKET_OPEN;
548 #ifdef DISPLAY
549  printf(">>> %d: OPEN\n", sockets[i].port);
550 #endif
551  (void) gettimeofday(&sockets[open_sock_nb].tictac, NULL);
552  open_sock_nb ++;
553  ports_states[port] = GRAB_PORT_OPEN;
554  unfiltered_ports_nb ++;
555  open_ports_nb ++;
556  open_ports_nb1 ++;
557  wait_sock_nb ++;
558  untested_ports_nb --;
559  scanner_add_port(desc, port, "tcp");
560  }
561  if (imax >= 0)
562  {
563  timeout.tv_sec = timeout.tv_usec = 0;
564  if (select(imax + 1, NULL, &wfs, NULL, &timeout) > 0)
565  {
566 #if DEBUG > 1
567  log_legacy_write ("openvas_tcp_scanner(%s): select! Breaking loop (open_sock_nb=%d / %d)\n", inet_ntoa(*pia), open_sock_nb, open_sock_max);
568 #endif
569  break;
570  }
571  }
572  }
573 
574  if (open_sock_max2 <= 0) /* file table is full */
575  return -1;
576 
577  if (open_sock_nb == 0)
578  {
579 #if DEBUG > 0
580  log_legacy_write ("openvas_tcp_scanner(%s): No more open socket\n", inet_ntoa(*pia));
581 #endif
582  goto end;
583  }
584 
585  FD_ZERO(&rfs); FD_ZERO(&wfs); FD_ZERO(&efs); imax = -1;
586 
587  for (i = 0; i < open_sock_nb; i ++)
588  {
589  if (sockets[i].fd >= 0)
590  {
591  switch (sockets[i].state)
592  {
593  case GRAB_SOCKET_OPEN:
594  FD_SET(sockets[i].fd, &rfs);
595  break;
596  case GRAB_SOCKET_OPENING:
597  FD_SET(sockets[i].fd, &wfs);
598  break;
599  default:
600  break;
601  }
602  if (sockets[i].fd > imax)
603  imax = sockets[i].fd;
604  }
605  }
606 
607  if (imax < 0)
608  {
609  if (untested_ports_nb > 0)
610  {
611 #if DEBUG > 0
612  log_legacy_write ("openvas_tcp_scanner(%s): No socket! %d ports remaining\n", inet_ntoa(*pia), untested_ports_nb);
613 #endif
614  return -1;
615  }
616  else
617  {
618 #if DEBUG > 0
619  log_legacy_write ("openvas_tcp_scanner(%s): No socket! No port remaining\n", inet_ntoa(*pia));
620 #endif
621  goto end;
622  }
623  }
624 
625  timeout_nb = 0; dropped_nb = 0; dropped_flag = 0;
626 #if defined COMPUTE_RTT
627  if (rtt_nb[0] > 1)
628  {
629  /* All values are in micro-seconds */
630  int em, moy;
631 
632  mean = rtt_sum[0] / (double)rtt_nb[0];
633  if ((double)rtt_max[0] > mean)
634  {
635  sd = sqrt((rtt_sum2[0] / rtt_nb[0] - mean * mean) * (double)rtt_nb[0] / (rtt_nb[0] - 1));
636  emax = mean + 3 * sd;
637  em = floor(emax + 0.5);
638  moy = floor(rtt_sum[0] / rtt_nb[0] + 0.5);
639  if (em <= moy)
640  {
641 #if DEBUG > 0
642  log_legacy_write ("openvas_tcp_scanner: arithmetic overflow: %g -> %d\n", emax, em);
643 #endif
644  em = moy;
645  }
646  if (rtt_max[0] > em)
647  {
648 #if DEBUG > 0
649  log_legacy_write ("openvas_tcp_scanner(%s): rtt_nb=%d rtt_max = %g > %g (M=%g, SD=%g)\n", inet_ntoa(*pia), rtt_nb[0], (double)rtt_max[0] / 1e6, emax / 1e6, mean / 1e6, sd / 1e6);
650 #endif
651  rtt_max[0] = em;
652  }
653 #if DEBUG > 1
654  else
655  log_legacy_write ("openvas_tcp_scanner(%s): rtt_nb=%d rtt_max = %g < %g\n", inet_ntoa(*pia), rtt_nb[0], (double)rtt_max[0] / 1e6, emax / 1e6);
656 #endif
657  }
658  if (rtt_max[0] < rtt_min[0])
659  {
660 #if DEBUG > 0
661  log_legacy_write ("openvas_tcp_scanner(%s): absurdly low rtt_max=%g < rtt_min = %g\n", inet_ntoa(*pia), (double)rtt_max[0] / 1e6, (double)rtt_min[0] / 1e6);
662 #endif
663  rtt_max[0] = rtt_min[0];
664  }
665  }
666 #endif
667  /*
668  * Some randomness is added to the timeout so that not all
669  * scanners fire at the same time when several firewalled
670  * machines are scanned in parallel.
671  */
672  if (wait_sock_nb == 0)
673  if (rtt_max[0] > 0 || ping_rtt > 0)
674  {
675 #if DEBUG > 1
676  int y;
677 #endif
678  if (rtt_max[0] > 0)
679  x = rtt_max[0];
680  else
681  x = ping_rtt;
682 #if DEBUG > 1
683  y = x;
684 #endif
685 
686  if (doublecheck_flag)
687  {
688  x = 3 * x + 20000;
689  if (x > MAX_SANE_RTT) x = MAX_SANE_RTT;
690 #if DEBUG > 1
691  log_legacy_write ("openvas_tcp_scanner(%s): basic timeout increased from %g to %g because of \"double check\"\n", inet_ntoa(*pia), y/1e6, x/1e6);
692 #endif
693  }
694  if (x > 1000000) /* more that 1 s */
695  x += (unsigned)(lrand48() & 0x7FFFFFFF) % 100000;
696  else if (x > 20000) /* between 20 ms and 1 s */
697  x += (unsigned)(lrand48() & 0x7FFFFFFF) % 50000;
698  else /* less than 20 ms */
699  x = 20000 + (unsigned)(lrand48() & 0x7FFFFFFF) % 20000;
700  timeout.tv_sec = x / 1000000;
701  timeout.tv_usec = x % 1000000;
702 #if DEBUG > 2
703  log_legacy_write ("openvas_tcp_scanner(%s): timeout=%g -> %g\n",
704  inet_ntoa(*pia), y/1e6, x/1e6);
705 #endif
706  }
707  else
708  {
709  /* Max RTT = 2 s ? */
710  timeout.tv_sec = 2;
711  timeout.tv_usec = (unsigned)(lrand48() & 0x7FFFFFFF) % 250000;
712  }
713  else
714  {
715  timeout.tv_sec = read_timeout; /* * 2 ? */
716  timeout.tv_usec = (unsigned)(lrand48() & 0x7FFFFFFF) % 500000;
717  }
718 #if DEBUG > 1
719  if (rtt_max[0] > 0)
720  log_legacy_write ("openvas_tcp_scanner(%s): wait_sock_nb=%d - timeout=%u.%06u - RTT=%f/%f/%f/%f\n", inet_ntoa(*pia), wait_sock_nb, timeout.tv_sec, timeout.tv_usec, (double)rtt_min[0] / 1e6, rtt_sum[0] / 1e6 / (rtt_nb[0] > 0 ? rtt_nb[0] : 1), (double)rtt_max[0] / 1e6, (double)cnx_max[0] / 1e6);
721  else
722  log_legacy_write ("openvas_tcp_scanner(%s): wait_sock_nb=%d - timeout=%d.%06d\n", inet_ntoa(*pia), wait_sock_nb, timeout.tv_sec, timeout.tv_usec);
723 #endif
724 #if DEBUG > 0
725  gettimeofday(&ti1, NULL);
726 #endif
727  i = 0;
728  do
729  {
730  x = select(imax + 1, &rfs, &wfs, NULL, &timeout);
731 #if DEBUG > 0
732  if (errno == EINTR)
733  log_legacy_write ("openvas_tcp_scanner(%s): select interrupted (i=%d)\n", inet_ntoa(*pia), i);
734 #endif
735  }
736  while (i ++ < 10 && x < 0 && errno == EINTR);
737 
738  if (x < 0)
739  {
740  perror("select");
741  return -1;
742  }
743  else if (x == 0) /* timeout */
744  {
745 #if DEBUG > 1
746  log_legacy_write ("openvas_tcp_scanner(%s): select: timeout on all (%d) sockets!\n", inet_ntoa(*pia), imax - 1);
747 #endif
748  for (i = 0; i < open_sock_nb; i ++)
749  {
750  if (sockets[i].fd > 0)
751  {
752  my_socket_close(sockets[i].fd);
753  sockets[i].fd = -1;
754  switch (sockets[i].state)
755  {
756  case GRAB_SOCKET_OPENING:
757 #ifdef DISPLAY
758  printf(">> %d: TIMEOUT\n", sockets[i].port);
759 #endif
760  ports_states[sockets[i].port] = GRAB_PORT_SILENT;
761  filtered_ports_nb ++;
762  dropped_nb ++;
763  untested_ports_nb --;
764  break;
765  case GRAB_SOCKET_OPEN:
766 #ifdef DISPLAY
767  printf(">> %d: NO BANNER\n", sockets[i].port);
768 #endif
769  wait_sock_nb --;
770  break;
771  }
772  }
773  sockets[i].state = GRAB_SOCKET_UNUSED;
774  }
775  }
776  else /* something to do */
777  {
778  (void) gettimeofday(&ti, NULL);
779 #if DEBUG > 1
780  log_legacy_write ("openvas_tcp_scanner(%s): select replied in %f s [time=%d.%06d]\n", inet_ntoa(*pia), DIFFTVu(ti, ti1) / 1e6, ti.tv_sec, ti.tv_usec);
781 #endif
782  for (i = 0; i < open_sock_nb; i ++)
783  {
784  if (sockets[i].fd > 0) {
785  if (FD_ISSET(sockets[i].fd, &wfs))
786  {
787  opt = 0; optsz = sizeof(opt);
788  if (getsockopt(sockets[i].fd, SOL_SOCKET, SO_ERROR, &opt, &optsz) < 0)
789  {
790  perror("getsockopt");
791  return -1;
792  }
793 
794  x = DIFFTVu(ti, sockets[i].tictac);
795 #if DEBUG > 2
796  log_legacy_write ("openvas_tcp_scanner: RTT to %s:%d: %g s\n",
797  inet_ntoa(*pia), sockets[i].port, x / 1e6);
798 #endif
799  if (opt != 0)
800  {
801  errno = opt;
802 #if DEBUG > 2
803  perror("select->getsockopt");
804 #endif
805  if (x > cnx_max[2]) cnx_max[2] = x;
806  if (x < rtt_min[2]) rtt_min[2] = x;
807  if (x < MAX_SANE_RTT)
808  {
809  if (x > rtt_max[2]) rtt_max[2] = x;
810 #if defined COMPUTE_RTT
811  rtt_nb[2] ++;
812  rtt_sum[2] += (double)x;
813  rtt_sum2[2] += (double)x * (double)x;
814 #endif
815  }
816 
817  my_socket_close(sockets[i].fd);
818  sockets[i].fd = -1;
819  sockets[i].state = GRAB_SOCKET_UNUSED;
820 
821  untested_ports_nb --;
822  switch (opt)
823  {
824  case ENETUNREACH:
825  case EHOSTUNREACH:
826  ports_states[sockets[i].port] = GRAB_PORT_REJECTED;
827  filtered_ports_nb ++;
828 #ifdef DISPLAY
829  printf(">> %d: FILTERED\n", sockets[i].port);
830 #endif
831  break;
832 
833  case ECONNREFUSED:
834  default:
835  ports_states[sockets[i].port] = GRAB_PORT_CLOSED;
836  unfiltered_ports_nb ++;
837  closed_ports_nb ++;
838  closed_ports_nb1 ++;
839 #ifdef DISPLAY
840  printf(">> %d: CLOSED\n", sockets[i].port);
841 #endif
842  break;
843  }
844  }
845  else
846  {
847  sockets[i].state = GRAB_SOCKET_OPEN;
848 #ifdef DISPLAY
849  printf(">> %d: OPEN\n", sockets[i].port);
850 #endif
851  if (x > cnx_max[1]) cnx_max[1] = x;
852  if (x < rtt_min[1]) rtt_min[1] = x;
853  if (x < MAX_SANE_RTT)
854  {
855  if (x > rtt_max[1]) rtt_max[1] = x;
856 #if defined COMPUTE_RTT
857  rtt_nb[1] ++;
858  rtt_sum[1] += (double)x;
859  rtt_sum2[1] += (double)x * (double)x;
860 #endif
861  }
862 
863  unfiltered_ports_nb ++;
864  open_ports_nb ++;
865  open_ports_nb1 ++;
866  untested_ports_nb --;
867  ports_states[sockets[i].port] = GRAB_PORT_OPEN;
868  scanner_add_port(desc, sockets[i].port, "tcp");
869  wait_sock_nb ++;
870  snprintf(kb, sizeof(kb), "TCPScanner/CnxTime1000/%u", sockets[i].port);
871  plug_set_key(desc, kb, ARG_INT, GSIZE_TO_POINTER(x/1000));
872  snprintf(kb, sizeof(kb), "TCPScanner/CnxTime/%u", sockets[i].port);
873  plug_set_key(desc, kb, ARG_INT, GSIZE_TO_POINTER((x + 500000) / 1000000));
874  sockets[i].tictac = ti;
875  }
876  if (x > cnx_max[0]) cnx_max[0] = x;
877  if (x < rtt_min[0]) rtt_min[0] = x;
878  if (x < MAX_SANE_RTT)
879  {
880  if (x > rtt_max[0]) rtt_max[0] = x;
881 #if defined COMPUTE_RTT
882  rtt_nb[0] ++;
883  rtt_sum[0] += (double)x;
884  rtt_sum2[0] += (double)x * (double)x;
885 #endif
886  }
887  }
888  else if (FD_ISSET(sockets[i].fd, &rfs))
889  {
890  x = read(sockets[i].fd, buf, sizeof(buf)-1);
891  if (x > 0)
892  {
893  char buf2[sizeof(buf)*2+1];
894  int y, flag = 0;
895 
896  for (y = 0; y < x; y ++)
897  {
898  sprintf(buf2 + 2*y, "%02x", (unsigned char) buf[y]);
899  if (buf[y] == '\0') flag = 1;
900  }
901  buf2[2 * x - 1] = '\0';
902  if (flag)
903  {
904  snprintf(kb, sizeof(kb), "BannerHex/%u", sockets[i].port);
905  plug_set_key(desc, kb, ARG_STRING, buf2);
906  }
907 
908  buf[x] = '\0';
909  snprintf(kb, sizeof(kb), "Banner/%u", sockets[i].port);
910  plug_set_key(desc, kb, ARG_STRING, buf);
911 #ifdef DISPLAY
912  printf("Banner for port %u: %s\n", sockets[i].port, buf);
913 #endif
914  x = DIFFTVu(ti, sockets[i].tictac) / 1000;
915  snprintf(kb, sizeof(kb), "TCPScanner/RwTime1000/%u", sockets[i].port);
916  plug_set_key(desc, kb, ARG_INT, GSIZE_TO_POINTER(x));
917  snprintf(kb, sizeof(kb), "TCPScanner/RwTime/%u", sockets[i].port);
918  plug_set_key(desc, kb, ARG_INT, GSIZE_TO_POINTER((x + 500) / 1000));
919  }
920 #if DEBUG > 0
921  else
922  perror("read");
923 #endif
924  wait_sock_nb --;
925  my_socket_close(sockets[i].fd);
926  sockets[i].fd = -1;
927  sockets[i].state = GRAB_SOCKET_UNUSED;
928  }
929  }
930  }
931  }
932 
933  (void) gettimeofday(&ti, NULL);
934  for (i = 0; i < open_sock_nb; i ++)
935  if (sockets[i].fd >= 0 && DIFFTV(ti, sockets[i].tictac) >= read_timeout)
936  {
937 #if DEBUG > 0
938  log_legacy_write ("openvas_tcp_scanner(%s): pass #%d: timeout on port %u: %d\n", inet_ntoa(*pia), pass, sockets[i].port, DIFFTV(ti, sockets[i].tictac));
939 #endif
940  switch(sockets[i].state)
941  {
942  case GRAB_SOCKET_OPEN:
943 #ifdef DISPLAY
944  printf(">> %u: NO BANNER\n", sockets[i].port);
945 #endif
946  timeout_nb ++;
947  wait_sock_nb --;
948  snprintf(kb, sizeof(kb), "/tmp/NoBanner/%u", sockets[i].port);
949  plug_set_key(desc, kb, ARG_INT, (void *) 1);
950  break;
951  case GRAB_SOCKET_OPENING:
952 #ifdef DISPLAY
953  printf(">> %d: TIMEOUT\n", sockets[i].port);
954 #endif
955  ports_states[sockets[i].port] = GRAB_PORT_SILENT;
956  filtered_ports_nb ++;
957  dropped_nb ++;
958  untested_ports_nb --;
959  break;
960  default:
961  log_legacy_write ("openvas_tcp_scanner: Unhandled case %d at %s:%d\n", sockets[i].state, __FILE__, __LINE__);
962  break;
963  }
964  my_socket_close(sockets[i].fd); sockets[i].fd = -1;
965  sockets[i].state = GRAB_SOCKET_UNUSED;
966  }
967 
968 #if DEBUG > 1
969  x = open_sock_max;
970  log_legacy_write ("openvas_tcp_scanner(%s): open_sock_max=%d timeout_nb=%d dropped_nb=%d\n", inet_ntoa(*pia), open_sock_max, timeout_nb, dropped_nb);
971  done_ports_nb = unfiltered_ports_nb + filtered_ports_nb;
972  if (done_ports_nb > 0 && total_ports_nb > 0)
973  {
974  int dt = time(NULL) - start_time_1pass;
975  log_legacy_write ("openvas_tcp_scanner(%s): pass #%d: time spent so far = %d s - estimated total time = %d s - estimated time remaining = %d s\n",
976  inet_ntoa(*pia), pass,
977  dt,
978  dt * total_ports_nb / done_ports_nb,
979  dt * (total_ports_nb - done_ports_nb) / done_ports_nb);
980  }
981 #endif
982  if (dropped_nb > 0 &&
983  dropped_nb >= (open_sock_nb * 3) / 4 &&
984  (dropped_nb < filtered_ports_nb
985  || dropped_nb > unfiltered_ports_nb))
986  {
987  /* firewalled machine? */
988 #if DEBUG > 1
989  log_legacy_write ("openvas_tcp_scanner(%s): %d connections dropped. Firewall?\n", inet_ntoa(*pia), dropped_nb);
990 #endif
991  open_sock_max += dropped_nb;
992  if (open_sock_max2 < max_cnx) open_sock_max2 ++;
993 #if 0
994  dropped_flag = 0;
995 #endif
996  }
997  else if (dropped_nb > 0)
998  {
999  dropped_flag = 1;
1000  open_sock_max -= (dropped_nb + 2) / 3;
1001  if (open_sock_max < min_cnx) open_sock_max = min_cnx;
1002  open_sock_max2 = (open_sock_max + 3 * open_sock_max2) / 4;
1003 #if 0
1004  if (open_sock_max2 <= min_cnx)
1005  if (open_sock_max2 > 0)
1006  min_cnx = open_sock_max2;
1007  else
1008  open_sock_max2 = min_cnx;
1009 #endif
1010 #if DEBUG > 0
1011  if (min_cnx < open_sock_max)
1012  log_legacy_write ("openvas_tcp_scanner(%s): %d connections dropped. Slowing down - min_cnx=%d - open_sock_nb=%d - open_sock_max=%d - open_sock_max2=%d\n", inet_ntoa(*pia), dropped_nb, min_cnx, open_sock_nb, open_sock_max, open_sock_max2);
1013 #endif
1014  }
1015  else if (dropped_nb == 0 && dropped_flag)
1016  {
1017  /* re-increase number of open sockets */
1018  open_sock_max ++;
1019 #if 0
1020  open_sock_max2 ++;
1021 #endif
1022  }
1023  open_sock_max += timeout_nb;
1024  if (open_sock_max > open_sock_max2)
1025  {
1026 #if DEBUG > 2
1027  log_legacy_write ("openvas_tcp_scanner(%s): open_sock_max=%d > %d\n",
1028  inet_ntoa(*pia), open_sock_max, open_sock_max2);
1029 #endif
1030  open_sock_max = open_sock_max2;
1031  }
1032  if (open_sock_max < min_cnx)
1033  {
1034 #if DEBUG > 2
1035  log_legacy_write ("openvas_tcp_scanner(%s): open_sock_max=%d < %d\n",
1036  inet_ntoa(*pia), open_sock_max, min_cnx);
1037 #endif
1038  open_sock_max = min_cnx;
1039  }
1040 #if DEBUG > 1
1041  if (x != open_sock_max)
1042  log_legacy_write ("openvas_tcp_scanner(%s): open_sock_max=%d (old value %d)\n", inet_ntoa(*pia), open_sock_max, x);
1043 #endif
1044  for (i = 0; i < open_sock_nb; )
1045  if (sockets[i].state == GRAB_SOCKET_UNUSED || sockets[i].fd < 0)
1046  {
1047  for (j = i +1;
1048  j < open_sock_nb && (sockets[j].state == GRAB_SOCKET_UNUSED || sockets[j].fd < 0);
1049  j ++)
1050  ;
1051  if (j < open_sock_nb)
1052  memmove(sockets+i, sockets+j, sizeof(*sockets) * (max_cnx - j));
1053  open_sock_nb -= j - i;
1054  }
1055  else
1056  i ++;
1057  }
1058 
1059  end:
1060  end_time = time(NULL);
1061  diff_time1 = end_time - start_time_1pass;
1062  diff_time = end_time - start_time;
1063 #if DEBUG > 0
1064  log_legacy_write ("openvas_tcp_scanner(%s): pass #%d ran in %d s - filtered_ports_nb=%d closed_ports_nb=%d open_ports_nb=%d\n", inet_ntoa(*pia), pass, diff_time1, filtered_ports_nb, closed_ports_nb, open_ports_nb);
1065 #endif
1066  if (dropped_flag ||
1067  (pass == 1 && filtered_ports_nb > 10 && closed_ports_nb > 10) ||
1068  (pass > 1 && filtered_ports_nb > 0))
1069  {
1070  if (doublecheck_flag && rst_rate_limit_flag && open_ports_nb == old_opened)
1071  {
1072 #if DEBUG > 0
1073  log_legacy_write ("openvas_tcp_scanner(%s): Same number of open ports! Stopping now\n", inet_ntoa(*pia));
1074 #endif
1075  break;
1076  }
1077  old_opened = open_ports_nb;
1078 
1079  doublecheck_flag = 0;
1080 #if DEBUG > 0
1081  log_legacy_write ("openvas_tcp_scanner(%s): pass #%d: Suspicious number of filtered ports (%d) or closed ports (%d) - running another time\n", inet_ntoa(*pia), pass, filtered_ports_nb, closed_ports_nb);
1082 #endif
1083  if (filtered_ports_nb == old_filtered)
1084  {
1085 #if DEBUG > 0
1086  log_legacy_write ("openvas_tcp_scanner(%s): Same number of filtered ports! Stopping now\n", inet_ntoa(*pia));
1087 #endif
1088  break;
1089  }
1090 
1091  if (pass > 1 && open_ports_nb1 == 0 &&
1092  closed_ports_nb1 >= min_cnx &&
1093  /*
1094  * Default value is 100 RST per second on OpenBSD,
1095  * 200 on FreeBSD and 40 on Solaris
1096  */
1097  /* 1st check on this pass only */
1098  closed_ports_nb1 >= (diff_time1 + 1) * 10 &&
1099  closed_ports_nb1 < (diff_time1 + 1) * 201 &&
1100  /* 2nd check on all passes */
1101  closed_ports_nb >= (diff_time + 1) * 10 &&
1102  closed_ports_nb < (diff_time + 1) * 201)
1103  {
1104  /* BSD-like system */
1105  int break_flag = (open_sock_max2 <= GRAB_MAX_SOCK_SAFE) || rst_rate_limit_flag;
1106  int tbd = break_flag && !doublecheck_flag ? double_check_std_ports(ports_states) : 0;
1107  if (tbd > 0)
1108  {
1109  doublecheck_flag = 1;
1110  break_flag = 0;
1111  }
1112 #if DEBUG > 0
1113  log_legacy_write ("openvas_tcp_scanner(%s): system seems to be limiting RST rate - %s - min_cnx=%d - closed_ports_nb1=%d - diff_time1=%d - closed_ports_nb=%d - diff_time=%d\n", inet_ntoa(*pia), break_flag ? "Stopping immediately" : doublecheck_flag ? "Double checking standard ports" : "Running one last pass", min_cnx, closed_ports_nb1, diff_time1, closed_ports_nb, diff_time);
1114 #endif
1115  rst_rate_limit_flag ++ ;
1116  if (break_flag) break;
1117  }
1118 #if DEBUG > 1
1119  log_legacy_write ("openvas_tcp_scanner(%s): min_cnx=%d - open_ports_nb1=%d - closed_ports_nb1=%d - diff_time1=%d - closed_ports_nb=%d - diff_time=%d\n", inet_ntoa(*pia), min_cnx, open_ports_nb1, closed_ports_nb1, diff_time1, closed_ports_nb, diff_time);
1120 #endif
1121 
1122  /*
1123  * With doublecheck_flag, the range of tested port is different, so
1124  * we'd better count the number of filtered ports
1125  */
1126  old_filtered = 0;
1127  for (port = 1; port <= 65535; port ++)
1128  if (ports_states[port] == GRAB_PORT_SILENT)
1129  {
1130  ports_states[port] = GRAB_PORT_UNKNOWN;
1131  old_filtered ++;
1132  }
1133 #if DEBUG > 1
1134  if (old_filtered != filtered_ports_nb)
1135  log_legacy_write ("openvas_tcp_scanner(%s): old_filtered=%d filtered_ports_nb=%d\n", inet_ntoa(*pia), old_filtered, filtered_ports_nb);
1136 #endif
1137  untested_ports_nb = old_filtered;
1138  filtered_ports_nb = 0;
1139  open_sock_max = min_cnx / (pass + 1);
1140  if (open_sock_max < 1)
1141  open_sock_max = 1;
1142  if (! dropped_flag)
1143  {
1144  open_sock_max2 *= 2;
1145  open_sock_max2 /= 3;
1146  }
1147  else if (rst_rate_limit_flag)
1148  {
1149  if (open_sock_max2 > GRAB_MAX_SOCK_SAFE)
1150  open_sock_max2 = GRAB_MAX_SOCK_SAFE;
1151  if (open_sock_max > GRAB_MAX_SOCK_SAFE)
1152  open_sock_max = GRAB_MAX_SOCK_SAFE;
1153  }
1154  else
1155  if (open_sock_max2 <= open_sock_max)
1156  open_sock_max2 = open_sock_max * 2;
1157  }
1158  else if (filtered_ports_nb > 0)
1159  {
1160  int tbd_nb = 0;
1161  doublecheck_flag = 1;
1162  /* Double check standard ports, just to avoid being ridiculous */
1163 
1164  if ((tbd_nb = double_check_std_ports(ports_states)) == 0)
1165  {
1166 #if DEBUG > 0
1167  log_legacy_write ("openvas_tcp_scanner(%s): pass #%d - No filtered standard ports - stopping\n", inet_ntoa(*pia), pass);
1168 #endif
1169  break;
1170  }
1171 #if DEBUG > 0
1172  else
1173  log_legacy_write ("openvas_tcp_scanner(%s): pass #%d - Double checking %d standard ports\n", inet_ntoa(*pia), pass, tbd_nb);
1174 #endif
1175  old_filtered = untested_ports_nb = tbd_nb;
1176  filtered_ports_nb = 0;
1177  open_sock_max = min_cnx / pass;
1178  if (open_sock_max2 <= open_sock_max)
1179  open_sock_max2 = open_sock_max * 2;
1180  if (open_sock_max2 > GRAB_MAX_SOCK_SAFE)
1181  open_sock_max2 = GRAB_MAX_SOCK_SAFE;
1182  if (open_sock_max > GRAB_MAX_SOCK_SAFE)
1183  open_sock_max = GRAB_MAX_SOCK_SAFE;
1184 
1185  }
1186  else
1187  break;
1188  } /* for pass = ... */
1189 
1190  if (pass > MAX_PASS_NB)
1191  {
1192  pass --;
1193  /*log_legacy_write ("openvas_tcp_scanner(%s): gave up after %d pass\n",
1194  inet_ntoa(*pia), pass);*/
1195  filtered_ports_nb = old_filtered;
1196  }
1197 
1198  plug_set_key(desc, "TCPScanner/NbPasses", ARG_INT, GSIZE_TO_POINTER(pass));
1199 
1200 #if DEBUG > 0
1201  log_legacy_write ("openvas_tcp_scanner(%s): ran in %d pass(es) in %d s - min_cnx=%d max_cnx=%d read_timeout=%d - open_ports_nb=%d closed_ports_nb=%d filtered_ports_nb=%d - rtt_min=%f rtt_max=%f cnx_max=%f\n", inet_ntoa(*pia), pass, diff_time, min_cnx, max_cnx, read_timeout, open_ports_nb, closed_ports_nb, filtered_ports_nb, rtt_min[0] / 1e6, rtt_max[0] / 1e6, cnx_max[0] / 1e6);
1202 #endif
1203 
1204 #if defined COMPUTE_RTT
1205  for (i = 0; i < 3; i ++)
1206  if (rtt_nb[i] > 0)
1207  {
1208  char rep[64];
1209  double mean, sd = -1.0, emax = -1.0;
1210 
1211  /* Convert from micro-seconds to seconds */
1212  rtt_sum[i] /= 1e6; rtt_sum2[i] /= 1e12;
1213 
1214  mean = rtt_sum[i] / rtt_nb[i];
1215 #if 1
1216  snprintf(rep, sizeof(rep), "%6g", mean);
1217  snprintf(kb, sizeof(kb), "TCPScanner/%s/MeanRTT", rtt_type[i]);
1218  plug_set_key(desc, kb, ARG_STRING, rep);
1219  x = floor(mean * 1000 + 0.5);
1220  snprintf(kb, sizeof(kb), "TCPScanner/%s/MeanRTT1000", rtt_type[i]);
1221  plug_set_key(desc, kb, ARG_INT, GSIZE_TO_POINTER(x));
1222  /* rtt_max is integer (uS) */
1223  snprintf(kb, sizeof(kb), "TCPScanner/%s/MaxRTT1000", rtt_type[i]);
1224  plug_set_key(desc, kb, ARG_INT, GSIZE_TO_POINTER((rtt_max[i] + 500)/1000));
1225  snprintf(rep, sizeof(rep), "%6g", (rtt_max[i] + 500000.0) / 1000000.0);
1226  snprintf(kb, sizeof(kb), "TCPScanner/%s/MaxRTT", rtt_type[i]);
1227  plug_set_key(desc, kb, ARG_STRING, rep);
1228 #endif
1229  if (rtt_nb[i] > 1)
1230  {
1231  sd = sqrt((rtt_sum2[i] / rtt_nb[i] - mean * mean) * rtt_nb[i] / (rtt_nb[i] - 1));
1232  emax = mean + 3 * sd;
1233 #if 1
1234  snprintf(rep, sizeof(rep), "%6g", sd);
1235  snprintf(kb, sizeof(kb), "TCPScanner/%s/SDRTT", rtt_type[i]);
1236  plug_set_key(desc, kb, ARG_STRING, rep);
1237  x = floor(sd * 1000 + 0.5);
1238  snprintf(kb, sizeof(kb), "TCPScanner/%s/SDRTT1000", rtt_type[i]);
1239  plug_set_key(desc, kb, ARG_INT, GSIZE_TO_POINTER(x));
1240  snprintf(rep, sizeof(rep), "%6g", emax);
1241  snprintf(kb, sizeof(kb), "TCPScanner/%s/EstimatedMaxRTT", rtt_type[i]);
1242  plug_set_key(desc, kb, ARG_STRING, rep);
1243  x = floor(emax * 1000 + 0.5);
1244  snprintf(kb, sizeof(kb), "TCPScanner/%s/EstimatedMaxRTT1000", rtt_type[i]);
1245  plug_set_key(desc, kb, ARG_INT, GSIZE_TO_POINTER(x));
1246 #endif
1247  }
1248 #if DEBUG > 0
1249  if (rtt_nb[i] > 0)
1250  log_legacy_write ("openvas_tcp_scanner: Mean RTT to %s = %g - [%g, %g] - SD = %g - +3SD = %g [%d %s ports]\n",
1251  inet_ntoa(*pia), mean,
1252  rtt_min[i] / 1e6, cnx_max[i] / 1e6,
1253  sd, emax, rtt_nb[i], rtt_type[i]);
1254 #endif
1255  }
1256 #endif
1257  plug_set_key(desc, "TCPScanner/OpenPortsNb", ARG_INT, GSIZE_TO_POINTER(open_ports_nb));
1258  plug_set_key(desc, "TCPScanner/ClosedPortsNb", ARG_INT, GSIZE_TO_POINTER(closed_ports_nb));
1259  plug_set_key(desc, "TCPScanner/FilteredPortsNb", ARG_INT, GSIZE_TO_POINTER(filtered_ports_nb));
1260  plug_set_key(desc, "TCPScanner/RSTRateLimit", ARG_INT, GSIZE_TO_POINTER( rst_rate_limit_flag));
1261  if (untested_ports_nb <= 0)
1262  plug_set_key(desc, "Host/full_scan", ARG_INT, GSIZE_TO_POINTER(1));
1263  plug_set_key(desc, "Host/num_ports_scanned", ARG_INT,
1264  GSIZE_TO_POINTER((total_ports_nb - untested_ports_nb)));
1265  return 0;
1266 }
1267 
1268 tree_cell *
1270 {
1271  struct arglist *desc = lexic->script_infos;
1272  struct host_info *hostinfo = arg_get_value(desc, "HOSTNAME");
1273  const char * port_range = prefs_get ("port_range");
1274  const char * p;
1275  struct in6_addr *p_addr;
1276  int timeout = 0, max_cnx, min_cnx, x;
1277  int safe_checks = prefs_get_bool ("safe_checks");
1278 
1279  p = prefs_get ("checks_read_timeout");
1280  if (p != NULL) timeout = atoi(p);
1281  if (timeout <= 0)
1282  timeout = 5;
1283 #if DEBUG > 0
1284  log_legacy_write ("openvas_tcp_scanner: safe_checks=%d checks_read_timeout=%d\n", safe_checks, timeout);
1285 #endif
1286 
1287  {
1288  int max_host = 0, max_checks = 0, cur_sys_fd = 0, max_sys_fd = 0;
1289  struct rlimit rlim;
1290  FILE *fp;
1291  int i;
1292  double loadavg[3], maxloadavg = -1.0;
1293 #if DEBUG == 0
1294  int stderr_fd = dup(2);
1295  int devnull_fd = open("/dev/null", O_WRONLY);
1296  /* Avoid error messages from sysctl */
1297  dup2(devnull_fd, 2);
1298 #endif
1299 
1300  p = prefs_get ("max_hosts");
1301  if (p != NULL) max_host = atoi(p);
1302  if (max_host <= 0) max_host = 15;
1303 
1304  p = prefs_get ("max_checks");
1305  if (p != NULL) max_checks = atoi(p);
1306  if (max_checks <= 0 || max_checks > 5)
1307  {
1308  max_checks = 5; /* bigger values do not make sense */
1309 #if DEBUG > 0
1310  log_legacy_write ("openvas_tcp_scanner: max_checks forced to %d\n", max_checks);
1311 #endif
1312  }
1313 
1314  min_cnx = 8 * max_checks;
1315  if (safe_checks)
1316  max_cnx = 24 * max_checks;
1317  else
1318  max_cnx = 80 * max_checks;
1319 
1320  getloadavg(loadavg, 3);
1321  for (i = 0; i < 3; i ++)
1322  if (loadavg[i] > maxloadavg) maxloadavg = loadavg[i];
1323 
1324  if (max_sys_fd <= 0)
1325  {
1326  if ( find_in_path("sysctl", 0) != NULL )
1327  fp = popen("sysctl fs.file-nr", "r");
1328  else
1329  fp = NULL;
1330 
1331  if (fp != NULL)
1332  {
1333  if (fscanf(fp, "%*s = %*d %d %d", &cur_sys_fd, &max_sys_fd) == 1)
1334  max_sys_fd -= cur_sys_fd;
1335  else
1336  max_sys_fd = 0;
1337  pclose(fp);
1338  }
1339  }
1340  if (max_sys_fd <= 0)
1341  {
1342  if ( find_in_path("sysctl", 0) )
1343  fp = popen("sysctl fs.file-max", "r");
1344  else
1345  fp = NULL;
1346 
1347  if (fp != NULL)
1348  {
1349  if (fscanf(fp, "%*s = %d", &max_sys_fd) < 1)
1350  max_sys_fd = 0;
1351  pclose(fp);
1352  }
1353  }
1354 
1355  if (max_sys_fd <= 0)
1356  {
1357  if ( find_in_path("sysctl", 0) )
1358  fp = popen("sysctl kern.maxfiles", "r");
1359  else
1360  fp = NULL;
1361 
1362  if (fp != NULL)
1363  {
1364  if (fscanf(fp, "%*s = %d", &max_sys_fd) < 1)
1365  max_sys_fd = 0;
1366  pclose(fp);
1367  }
1368  }
1369 
1370  /* Restore stderr */
1371 #if DEBUG == 0
1372  close(devnull_fd);
1373  dup2(stderr_fd, 2);
1374  close(stderr_fd);
1375 #endif
1376 
1377  if (maxloadavg >= 0.0)
1378  {
1379 #if DEBUG > 0
1380  int x = max_cnx;
1381 #endif
1382  max_cnx /= (1.0 + maxloadavg);
1383 #if DEBUG > 0
1384  /* Useless, as stderr is temporarily closed */
1385  log_legacy_write ("openvas_tcp_scanner: max_cnx reduced from %d to %d because of maxloadavg=%f\n", x, max_cnx, maxloadavg);
1386 #endif
1387  }
1388 
1389 
1390 
1391 #if DEBUG > 0
1392  log_legacy_write ("openvas_tcp_scanner: max_sys_fd=%d\n", max_sys_fd);
1393 #endif
1394  if (max_sys_fd <= 0) max_sys_fd = 16384; /* reasonable default */
1395  /* Let's leave at least 1024 FD for other processes */
1396  if (max_sys_fd < 1024)
1397  x = GRAB_MIN_SOCK;
1398  else
1399  {
1400  max_sys_fd -= 1024;
1401  x = max_sys_fd / max_host;
1402  }
1403  if (max_cnx > x) max_cnx = x;
1404 #if 0
1405  log_legacy_write ("min_cnx = %d ; max_cnx = %d\n", min_cnx, max_cnx);
1406 #endif
1407  if (max_cnx > GRAB_MAX_SOCK) max_cnx = GRAB_MAX_SOCK;
1408  if (max_cnx < GRAB_MIN_SOCK) max_cnx = GRAB_MIN_SOCK;
1409 
1410  if (safe_checks && max_cnx > GRAB_MAX_SOCK_SAFE)
1411  max_cnx = GRAB_MAX_SOCK_SAFE;
1412 
1413  if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
1414  perror("getrlimit(RLIMIT_NOFILE)");
1415  else
1416  {
1417  /* value = one greater than the maximum file descriptor number */
1418  if (rlim.rlim_cur != RLIM_INFINITY && max_cnx >= rlim.rlim_cur)
1419  max_cnx = rlim.rlim_cur - 1;
1420  }
1421  x = max_cnx / 2;
1422  if (min_cnx > x) min_cnx = x > 0 ? x : 1;
1423 #if DEBUG > 0
1424  log_legacy_write ("openvas_tcp_scanner: min_cnx = %d ; max_cnx = %d\n", min_cnx, max_cnx);
1425 #endif
1426  }
1427 
1428  p_addr = hostinfo->ip;
1429  if( p_addr == NULL )
1430  return NULL; // TODO: before it returned "1";
1431  if (banner_grab(p_addr, port_range, timeout, min_cnx, max_cnx, desc) < 0)
1432  return NULL; // TODO: before it returned "1";
1433  plug_set_key(desc, "Host/scanned", ARG_INT, (void*)1);
1434  plug_set_key(desc, "Host/scanners/openvas_tcp_scanner", ARG_INT, (void*)1);
1435  return NULL;
1436 }
#define ARG_INT
Definition: arglists.h:40
#define RLIM_INFINITY
Definition: popen.c:32
#define GRAB_PORT_REJECTED
void plug_set_key(struct arglist *args, char *name, int type, const void *value)
Definition: plugutils.c:658
void * plug_get_key(struct arglist *args, char *name, int *type, int single)
Definition: plugutils.c:767
#define GRAB_MAX_SOCK_SAFE
#define DIFFTV(t1, t2)
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
const gchar * prefs_get(const gchar *key)
Get a string preference value via a key.
Definition: prefs.c:86
#define DIFFTVu(t1, t2)
#define GRAB_SOCKET_UNUSED
Top-level KB. This is to be inherited by KB implementations.
Definition: kb.h:102
Definition: nasl_tree.h:105
#define GRAB_PORT_SILENT
struct in6_addr * ip
Definition: network.h:61
#define GRAB_PORT_CLOSED
tree_cell * safe_checks(lex_ctxt *lexic)
#define GRAB_PORT_NOT_TESTED
char * find_in_path(char *name, int safe)
Definition: plugutils.c:1041
void scanner_add_port(struct arglist *args, int port, char *proto)
Definition: plugutils.c:703
tree_cell * plugin_run_openvas_tcp_scanner(lex_ctxt *lexic)
struct timeval timeval(unsigned long val)
#define GRAB_PORT_TESTING
#define GRAB_PORT_UNKNOWN
#define ARG_STRING
Definition: arglists.h:38
#define GRAB_SOCKET_OPEN
#define GRAB_SOCKET_OPENING
struct arglist * script_infos
Definition: nasl_lex_ctxt.h:39
void * arg_get_value(struct arglist *args, const char *name)
Definition: arglists.c:252
int prefs_get_bool(const gchar *key)
Get a boolean expression of a preference value via a key.
Definition: prefs.c:109
#define GRAB_PORT_OPEN