OpenVAS Scanner 23.32.3
nasl_builtin_openvas_tcp_scanner.c File Reference
#include "../misc/network.h"
#include "../misc/plugutils.h"
#include "nasl_builtin_plugins.h"
#include "nasl_lex_ctxt.h"
#include <errno.h>
#include <fcntl.h>
#include <glib.h>
#include <gvm/base/logging.h>
#include <gvm/base/prefs.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <limits.h>
#include <math.h>
Include dependency graph for nasl_builtin_openvas_tcp_scanner.c:

Go to the source code of this file.

Data Structures

struct  grab_socket_t

Macros

#define GRAB_MAX_SOCK   1024
#define GRAB_MIN_SOCK   32
#define GRAB_MAX_SOCK_SAFE   128
#define MAX_PASS_NB   16
#define MAXINT   0x7fffffffL
#define G_LOG_DOMAIN   "lib nasl"
 GLib logging domain.
#define DIFFTV(t1, t2)
#define DIFFTVu(t1, t2)
#define GRAB_SOCKET_UNUSED   0
#define GRAB_SOCKET_OPENING   1
#define GRAB_SOCKET_OPEN   2
#define GRAB_PORT_UNKNOWN   0
#define GRAB_PORT_CLOSED   1
#define GRAB_PORT_OPEN   2
#define GRAB_PORT_SILENT   3
#define GRAB_PORT_REJECTED   4
#define GRAB_PORT_NOT_TESTED   254
#define GRAB_PORT_TESTING   255
#define COMPUTE_RTT
#define MAX_SANE_RTT   2000000 /* micro-seconds */

Functions

static int my_socket_close (int s)
static int std_port (int port)
static int double_check_std_ports (unsigned char *ports_states)
static int banner_grab (const struct in6_addr *pia, const char *portrange, const int read_timeout, int min_cnx, int max_cnx, struct script_infos *desc)
tree_cellplugin_run_openvas_tcp_scanner (lex_ctxt *lexic)

Macro Definition Documentation

◆ COMPUTE_RTT

#define COMPUTE_RTT

Definition at line 91 of file nasl_builtin_openvas_tcp_scanner.c.

◆ DIFFTV

#define DIFFTV ( t1,
t2 )
Value:
(t1.tv_sec - t2.tv_sec + (t1.tv_usec - t2.tv_usec) / 1000000)

Definition at line 74 of file nasl_builtin_openvas_tcp_scanner.c.

74#define DIFFTV(t1, t2) \
75 (t1.tv_sec - t2.tv_sec + (t1.tv_usec - t2.tv_usec) / 1000000)

Referenced by banner_grab().

◆ DIFFTVu

#define DIFFTVu ( t1,
t2 )
Value:
((t1.tv_sec - t2.tv_sec) * 1000000.0 + (t1.tv_usec - t2.tv_usec))

Definition at line 76 of file nasl_builtin_openvas_tcp_scanner.c.

76#define DIFFTVu(t1, t2) \
77 ((t1.tv_sec - t2.tv_sec) * 1000000.0 + (t1.tv_usec - t2.tv_usec))

Referenced by banner_grab().

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "lib nasl"

GLib logging domain.

Definition at line 64 of file nasl_builtin_openvas_tcp_scanner.c.

◆ GRAB_MAX_SOCK

#define GRAB_MAX_SOCK   1024

◆ GRAB_MAX_SOCK_SAFE

#define GRAB_MAX_SOCK_SAFE   128

◆ GRAB_MIN_SOCK

#define GRAB_MIN_SOCK   32

Definition at line 41 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by plugin_run_openvas_tcp_scanner().

◆ GRAB_PORT_CLOSED

#define GRAB_PORT_CLOSED   1

Definition at line 84 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

◆ GRAB_PORT_NOT_TESTED

#define GRAB_PORT_NOT_TESTED   254

Definition at line 88 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

◆ GRAB_PORT_OPEN

#define GRAB_PORT_OPEN   2

Definition at line 85 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

◆ GRAB_PORT_REJECTED

#define GRAB_PORT_REJECTED   4

Definition at line 87 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

◆ GRAB_PORT_SILENT

#define GRAB_PORT_SILENT   3

Definition at line 86 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab(), and double_check_std_ports().

◆ GRAB_PORT_TESTING

#define GRAB_PORT_TESTING   255

Definition at line 89 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

◆ GRAB_PORT_UNKNOWN

#define GRAB_PORT_UNKNOWN   0

Definition at line 83 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab(), and double_check_std_ports().

◆ GRAB_SOCKET_OPEN

#define GRAB_SOCKET_OPEN   2

Definition at line 81 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

◆ GRAB_SOCKET_OPENING

#define GRAB_SOCKET_OPENING   1

Definition at line 80 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

◆ GRAB_SOCKET_UNUSED

#define GRAB_SOCKET_UNUSED   0

Definition at line 79 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

◆ MAX_PASS_NB

#define MAX_PASS_NB   16

Definition at line 54 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

◆ MAX_SANE_RTT

#define MAX_SANE_RTT   2000000 /* micro-seconds */

Definition at line 100 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

◆ MAXINT

#define MAXINT   0x7fffffffL

Definition at line 57 of file nasl_builtin_openvas_tcp_scanner.c.

Referenced by banner_grab().

Function Documentation

◆ banner_grab()

int banner_grab ( const struct in6_addr * pia,
const char * portrange,
const int read_timeout,
int min_cnx,
int max_cnx,
struct script_infos * desc )
static

Definition at line 144 of file nasl_builtin_openvas_tcp_scanner.c.

147{
148 char buf[2048], kb[64];
149 int s, tcpproto, pass;
150 struct protoent *proto;
151 fd_set rfs, wfs, efs;
152 struct timeval timeout, ti;
153 struct sockaddr_in sa;
154 struct sockaddr_in6 sa6;
155 int len;
156 int retval;
157 int port = 23;
158 int imax, i, j, scanned_ports, x, opt;
159 unsigned int optsz;
160 int minport;
161 unsigned char ports_states[65536];
163 int open_sock_nb, open_sock_max, open_sock_max2;
164 int unfiltered_ports_nb, filtered_ports_nb;
165 int dropped_nb, timeout_nb, dropped_flag = 0;
166 int old_filtered = -1, old_opened = -1;
167 int open_ports_nb, closed_ports_nb;
168 int untested_ports_nb, total_ports_nb;
169 int cnx_max[3], rtt_max[3], rtt_min[3], ping_rtt = 0;
170#if defined COMPUTE_RTT
171 double rtt_sum[3], rtt_sum2[3];
172 int rtt_nb[3];
173 static const char *rtt_type[] = {"unfiltered", "open", "closed"};
174#endif
175 time_t start_time = time (NULL), start_time_1pass, end_time;
176 long diff_time, diff_time1;
177 int rst_rate_limit_flag = 0, doublecheck_flag = 0;
178#if defined COMPUTE_RTT
179 double mean, sd = -1.0, emax = -1.0;
180#endif
181
182 proto = getprotobyname ("tcp");
183 if (proto == NULL)
184 {
185 perror ("tcp");
186 return -1;
187 }
188 tcpproto = proto->p_proto;
189
190 for (i = 0; i < (int) (sizeof (ports_states) / sizeof (*ports_states)); i++)
191 ports_states[i] = GRAB_PORT_NOT_TESTED;
192 scanned_ports = 0;
193 for (i = 0; i < 3; i++)
194 {
195#if defined COMPUTE_RTT
196 rtt_sum[i] = rtt_sum2[i] = 0.0;
197 rtt_nb[i] = 0;
198#endif
199 rtt_max[i] = cnx_max[i] = 0;
200 rtt_min[i] = MAXINT;
201 }
202
203 {
204 char *k;
205 int type = 0;
206 k = plug_get_key (desc, "/tmp/ping/RTT", &type, NULL, 0);
207 if (type == ARG_STRING && k != NULL)
208 ping_rtt = atoi (k);
209 else if (type == ARG_INT)
210 ping_rtt = GPOINTER_TO_SIZE (k);
211 else if (type >= 0)
212 g_message ("openvas_tcp_scanner: unknown key type %d", type);
213 g_free (k);
214 if (ping_rtt < 0 || ping_rtt > MAX_SANE_RTT)
215 ping_rtt = 0;
216 }
217
218 {
219 char *p, *q;
220 int po1, po2 = 0;
221 p = (char *) portrange;
222 untested_ports_nb = 0;
223
224 if (p)
225 while (*p != '\0')
226 {
227 while (*p == ',')
228 p++;
229
230 /* Scanner accepts only T:1-3,6,U:103-333,770 due to getpts. */
231
232 if (*p == 'T' && p[1] && p[1] == ':')
233 /* Skip over the leading "T:". */
234 p += 2;
235 else if (*p == 'U' && p[1] && p[1] == ':')
236 /* "U:" for UDP. Skip the rest. */
237 break;
238
239 if (*p == '-')
240 {
241 po1 = 1;
242 q = p + 1;
243 po2 = strtol (q, &p, 10);
244 if (q == p)
245 {
246 g_message ("openvas_tcp_scanner: Cannot parse '%s'", p);
247 return -1;
248 }
249 }
250 else
251 {
252 po1 = strtol (p, &q, 10);
253 if (q == p)
254 {
255 g_message ("openvas_tcp_scanner: Cannot parse '%s'", p);
256 return -1;
257 }
258 if (*q == ',')
259 {
260 p = q + 1;
261 po2 = po1;
262 }
263 else if (*q == '\0')
264 {
265 p = q;
266 po2 = po1;
267 }
268 else if (*q == '-')
269 {
270 if (q[1] == '\0')
271 {
272 po2 = 65535;
273 p = q + 1;
274 }
275 else
276 {
277 po2 = strtol (q + 1, &p, 10);
278 if (q + 1 == p)
279 {
280 g_message ("openvas_tcp_scanner: Cannot parse '%s'",
281 p);
282 return -1;
283 }
284 }
285 }
286 }
287 for (i = po1; i <= po2; i++)
288 {
289 ports_states[i] = GRAB_PORT_UNKNOWN;
290 untested_ports_nb++;
291 }
292 }
293 else
294 {
295 g_message ("openvas_tcp_scanner: port list empty");
296 return -1;
297 }
298 }
299
300 for (i = 0; i < max_cnx; i++)
301 {
302 sockets[i].state = GRAB_SOCKET_UNUSED;
303 sockets[i].fd = -1;
304 }
305
306 open_sock_nb = 0;
307 open_sock_max = min_cnx;
308 open_sock_max2 = max_cnx;
309
310 open_ports_nb = closed_ports_nb = filtered_ports_nb = unfiltered_ports_nb = 0;
311
312 for (pass = 1; pass <= MAX_PASS_NB; pass++)
313 {
314 int open_ports_nb1 = 0, closed_ports_nb1 = 0;
315 int wait_sock_nb = 0;
316
317 minport = 1;
318 start_time_1pass = time (NULL);
319 FD_ZERO (&rfs);
320 FD_ZERO (&wfs);
321 imax = -1;
322
323 while (scanned_ports < 65535)
324 {
325 total_ports_nb =
326 unfiltered_ports_nb + filtered_ports_nb + untested_ports_nb;
327 while (open_sock_nb < open_sock_max)
328 {
329 for (port = minport;
330 port <= 65535 && ports_states[port] != GRAB_PORT_UNKNOWN;
331 port++)
332 ;
333 if (port > 65535)
334 break;
335 minport = port;
336
337 ports_states[port] = GRAB_PORT_TESTING;
338 if (IN6_IS_ADDR_V4MAPPED (pia))
339 {
340 s = socket (PF_INET, SOCK_STREAM, tcpproto);
341 }
342 else
343 {
344 s = socket (PF_INET6, SOCK_STREAM, tcpproto);
345 }
346 if (s < 0)
347 {
348 if (errno == ENFILE) /* File table overflow */
349 {
350 open_sock_max = open_sock_max2 = open_sock_nb / 2 - 1;
351 /* NB: if open_sock_max2 < 0, the scanner aborts */
352 /* DEBUG: otherwise, we print a less frigthtening message
353 */
354 continue;
355 }
356 else if (errno == EMFILE) /* Too many open files */
357 {
358 x = open_sock_nb / 16; /* 6.25% */
359 open_sock_max = open_sock_max2 =
360 open_sock_nb - (x > 0 ? x : 1);
361 /* NB: if open_sock_max2 < 0, the scanner aborts */
362 /* DEBUG: otherwise, we print a less frigthtening message
363 */
364 continue;
365 }
366 else
367 {
368 perror ("socket");
369 return -1;
370 }
371 }
372#if defined FD_SETSIZE
373 if (s >= FD_SETSIZE)
374 {
375 open_sock_max--;
376 open_sock_max2--;
377 if (close (s) < 0)
378 perror ("close");
379 continue;
380 }
381#endif
382
383 if ((x = fcntl (s, F_GETFL)) < 0)
384 {
385 perror ("fcntl(F_GETFL)");
386 close (s);
387 return -1;
388 }
389 if (fcntl (s, F_SETFL, x | O_NONBLOCK) < 0)
390 {
391 perror ("fcntl(F_SETFL)");
392 close (s);
393 return -1;
394 }
395
396#ifdef SO_LINGER
397 {
398 struct linger l;
399
400 l.l_onoff = 0;
401 l.l_linger = 0;
402 if (setsockopt (s, SOL_SOCKET, SO_LINGER, &l, sizeof (l)) < 0)
403 perror ("setsockopt(SO_LINGER)");
404 }
405#endif
406#if defined LINUX && defined IPTOS_RELIABILITY
407 /*
408 * IP TOS (RFC791) is obsoleted by RFC2474
409 * RFC3168 deprecates IPTOS_MINCOST, as it conflicts with
410 * the "ECN capable" flags
411 */
412 x = IPTOS_RELIABILITY;
413 if (setsockopt (s, SOL_IP, IP_TOS, &x, sizeof (x)) < 0)
414 perror ("setsockopt(IP_TOS");
415#endif
416 bzero (&sa, sizeof (sa));
417 bzero (&sa6, sizeof (sa6));
418 if (IN6_IS_ADDR_V4MAPPED (pia))
419 {
420 sa.sin_addr.s_addr = pia->s6_addr32[3];
421 sa.sin_family = AF_INET;
422 sa.sin_port = htons (port);
423 len = sizeof (struct sockaddr_in);
424 retval = connect (s, (struct sockaddr *) &sa, len);
425 }
426 else
427 {
428 memcpy (&sa6.sin6_addr, pia, sizeof (struct in6_addr));
429 sa6.sin6_family = AF_INET6;
430 sa6.sin6_port = htons (port);
431 len = sizeof (struct sockaddr_in6);
432 retval = connect (s, (struct sockaddr *) &sa6, len);
433 }
434 if (retval < 0)
435 {
436 switch (errno)
437 {
438 case EINPROGRESS:
439 case EALREADY:
440 sockets[open_sock_nb].fd = s;
441 sockets[open_sock_nb].port = port;
442 sockets[open_sock_nb].state = GRAB_SOCKET_OPENING;
443 (void) gettimeofday (&sockets[open_sock_nb].tictac, NULL);
444 open_sock_nb++;
445 FD_SET (s, &wfs);
446 if (s > imax)
447 imax = s;
448 break;
449
450 case EAGAIN:
451 x = open_sock_nb / 16; /* 6.25% */
452 open_sock_max = open_sock_max2 =
453 open_sock_nb - (x > 0 ? x : 1);
454 /* If open_sock_max2 < 0, the scanner aborts */
455 continue;
456
457 case ECONNREFUSED:
458 ports_states[port] = GRAB_PORT_CLOSED;
459 my_socket_close (s);
460 unfiltered_ports_nb++;
461 closed_ports_nb++;
462 closed_ports_nb1++;
463 untested_ports_nb--;
464 continue;
465
466 case ENETUNREACH:
467 case EHOSTUNREACH:
468 ports_states[port] = GRAB_PORT_REJECTED;
469 my_socket_close (s);
470 filtered_ports_nb++;
471 untested_ports_nb--;
472 continue;
473
474 default:
475 perror ("connect");
476 return -1;
477 }
478 }
479 else /* This should not happen! */
480 {
481 sockets[open_sock_nb].fd = s;
482 sockets[open_sock_nb].port = port;
483 sockets[open_sock_nb].state = GRAB_SOCKET_OPEN;
484 (void) gettimeofday (&sockets[open_sock_nb].tictac, NULL);
485 open_sock_nb++;
486 ports_states[port] = GRAB_PORT_OPEN;
487 unfiltered_ports_nb++;
488 open_ports_nb++;
489 open_ports_nb1++;
490 wait_sock_nb++;
491 untested_ports_nb--;
492 scanner_add_port (desc, port, "tcp");
493 }
494 if (imax >= 0)
495 {
496 timeout.tv_sec = timeout.tv_usec = 0;
497 if (select (imax + 1, NULL, &wfs, NULL, &timeout) > 0)
498 break;
499 }
500 }
501
502 if (open_sock_max2 <= 0) /* file table is full */
503 return -1;
504
505 if (open_sock_nb == 0)
506 goto end;
507
508 FD_ZERO (&rfs);
509 FD_ZERO (&wfs);
510 FD_ZERO (&efs);
511 imax = -1;
512
513 for (i = 0; i < open_sock_nb; i++)
514 {
515 if (sockets[i].fd >= 0)
516 {
517 switch (sockets[i].state)
518 {
519 case GRAB_SOCKET_OPEN:
520 FD_SET (sockets[i].fd, &rfs);
521 break;
523 FD_SET (sockets[i].fd, &wfs);
524 break;
525 default:
526 break;
527 }
528 if (sockets[i].fd > imax)
529 imax = sockets[i].fd;
530 }
531 }
532
533 if (imax < 0)
534 {
535 if (untested_ports_nb > 0)
536 return -1;
537 else
538 goto end;
539 }
540
541 timeout_nb = 0;
542 dropped_nb = 0;
543 dropped_flag = 0;
544#if defined COMPUTE_RTT
545 if (rtt_nb[0] > 1)
546 {
547 /* All values are in micro-seconds */
548 int em, moy;
549
550 mean = rtt_sum[0] / (double) rtt_nb[0];
551 if ((double) rtt_max[0] > mean)
552 {
553 sd = sqrt ((rtt_sum2[0] / rtt_nb[0] - mean * mean)
554 * (double) rtt_nb[0] / (rtt_nb[0] - 1));
555 emax = mean + 3 * sd;
556 em = floor (emax + 0.5);
557 moy = floor (rtt_sum[0] / rtt_nb[0] + 0.5);
558 if (em <= moy)
559 em = moy;
560 if (rtt_max[0] > em)
561 rtt_max[0] = em;
562 }
563 if (rtt_max[0] < rtt_min[0])
564 rtt_max[0] = rtt_min[0];
565 }
566#endif
567 /*
568 * Some randomness is added to the timeout so that not all
569 * scanners fire at the same time when several firewalled
570 * machines are scanned in parallel.
571 */
572 if (wait_sock_nb == 0)
573 if (rtt_max[0] > 0 || ping_rtt > 0)
574 {
575 if (rtt_max[0] > 0)
576 x = rtt_max[0];
577 else
578 x = ping_rtt;
579
580 if (doublecheck_flag)
581 {
582 x = 3 * x + 20000;
583 if (x > MAX_SANE_RTT)
584 x = MAX_SANE_RTT;
585 }
586 if (x > 1000000) /* more that 1 s */
587 x += (unsigned) (lrand48 () & 0x7FFFFFFF) % 100000;
588 else if (x > 20000) /* between 20 ms and 1 s */
589 x += (unsigned) (lrand48 () & 0x7FFFFFFF) % 50000;
590 else /* less than 20 ms */
591 x = 20000 + (unsigned) (lrand48 () & 0x7FFFFFFF) % 20000;
592 timeout.tv_sec = x / 1000000;
593 timeout.tv_usec = x % 1000000;
594 }
595 else
596 {
597 /* Max RTT = 2 s ? */
598 timeout.tv_sec = 2;
599 timeout.tv_usec = (unsigned) (lrand48 () & 0x7FFFFFFF) % 250000;
600 }
601 else
602 {
603 timeout.tv_sec = read_timeout; /* * 2 ? */
604 timeout.tv_usec = (unsigned) (lrand48 () & 0x7FFFFFFF) % 500000;
605 }
606 i = 0;
607 do
608 x = select (imax + 1, &rfs, &wfs, NULL, &timeout);
609 while (i++ < 10 && x < 0 && errno == EINTR);
610
611 if (x < 0)
612 {
613 perror ("select");
614 return -1;
615 }
616 else if (x == 0) /* timeout */
617 {
618 for (i = 0; i < open_sock_nb; i++)
619 {
620 if (sockets[i].fd > 0)
621 {
622 my_socket_close (sockets[i].fd);
623 sockets[i].fd = -1;
624 switch (sockets[i].state)
625 {
627 ports_states[sockets[i].port] = GRAB_PORT_SILENT;
628 filtered_ports_nb++;
629 dropped_nb++;
630 untested_ports_nb--;
631 break;
632 case GRAB_SOCKET_OPEN:
633 wait_sock_nb--;
634 break;
635 }
636 }
637 sockets[i].state = GRAB_SOCKET_UNUSED;
638 }
639 }
640 else /* something to do */
641 {
642 (void) gettimeofday (&ti, NULL);
643 for (i = 0; i < open_sock_nb; i++)
644 {
645 if (sockets[i].fd > 0)
646 {
647 if (FD_ISSET (sockets[i].fd, &wfs))
648 {
649 opt = 0;
650 optsz = sizeof (opt);
651 if (getsockopt (sockets[i].fd, SOL_SOCKET, SO_ERROR,
652 &opt, &optsz)
653 < 0)
654 {
655 perror ("getsockopt");
656 return -1;
657 }
658
659 x = DIFFTVu (ti, sockets[i].tictac);
660 if (opt != 0)
661 {
662 errno = opt;
663 if (x > cnx_max[2])
664 cnx_max[2] = x;
665 if (x < rtt_min[2])
666 rtt_min[2] = x;
667 if (x < MAX_SANE_RTT)
668 {
669 if (x > rtt_max[2])
670 rtt_max[2] = x;
671#if defined COMPUTE_RTT
672 rtt_nb[2]++;
673 rtt_sum[2] += (double) x;
674 rtt_sum2[2] += (double) x * (double) x;
675#endif
676 }
677
678 my_socket_close (sockets[i].fd);
679 sockets[i].fd = -1;
680 sockets[i].state = GRAB_SOCKET_UNUSED;
681
682 untested_ports_nb--;
683 switch (opt)
684 {
685 case ENETUNREACH:
686 case EHOSTUNREACH:
687 ports_states[sockets[i].port] =
689 filtered_ports_nb++;
690 break;
691
692 case ECONNREFUSED:
693 default:
694 ports_states[sockets[i].port] =
696 unfiltered_ports_nb++;
697 closed_ports_nb++;
698 closed_ports_nb1++;
699 break;
700 }
701 }
702 else
703 {
704 sockets[i].state = GRAB_SOCKET_OPEN;
705 if (x > cnx_max[1])
706 cnx_max[1] = x;
707 if (x < rtt_min[1])
708 rtt_min[1] = x;
709 if (x < MAX_SANE_RTT)
710 {
711 if (x > rtt_max[1])
712 rtt_max[1] = x;
713#if defined COMPUTE_RTT
714 rtt_nb[1]++;
715 rtt_sum[1] += (double) x;
716 rtt_sum2[1] += (double) x * (double) x;
717#endif
718 }
719
720 unfiltered_ports_nb++;
721 open_ports_nb++;
722 open_ports_nb1++;
723 untested_ports_nb--;
724 ports_states[sockets[i].port] = GRAB_PORT_OPEN;
725 scanner_add_port (desc, sockets[i].port, "tcp");
726 wait_sock_nb++;
727 snprintf (kb, sizeof (kb),
728 "TCPScanner/CnxTime1000/%u",
729 sockets[i].port);
730 plug_set_key (desc, kb, ARG_INT,
731 GSIZE_TO_POINTER (x / 1000));
732 snprintf (kb, sizeof (kb),
733 "TCPScanner/CnxTime/%u",
734 sockets[i].port);
736 desc, kb, ARG_INT,
737 GSIZE_TO_POINTER ((x + 500000) / 1000000));
738 sockets[i].tictac = ti;
739 }
740 if (x > cnx_max[0])
741 cnx_max[0] = x;
742 if (x < rtt_min[0])
743 rtt_min[0] = x;
744 if (x < MAX_SANE_RTT)
745 {
746 if (x > rtt_max[0])
747 rtt_max[0] = x;
748#if defined COMPUTE_RTT
749 rtt_nb[0]++;
750 rtt_sum[0] += (double) x;
751 rtt_sum2[0] += (double) x * (double) x;
752#endif
753 }
754 }
755 else if (FD_ISSET (sockets[i].fd, &rfs))
756 {
757 x = read (sockets[i].fd, buf, sizeof (buf) - 1);
758 if (x > 0)
759 {
760 char buf2[sizeof (buf) * 2 + 1];
761 int y, flag = 0;
762
763 for (y = 0; y < x; y++)
764 {
765 sprintf (buf2 + 2 * y, "%02x",
766 (unsigned char) buf[y]);
767 if (buf[y] == '\0')
768 flag = 1;
769 }
770 buf2[2 * x - 1] = '\0';
771 if (flag)
772 {
773 snprintf (kb, sizeof (kb), "BannerHex/%u",
774 sockets[i].port);
775 plug_set_key (desc, kb, ARG_STRING, buf2);
776 }
777
778 buf[x] = '\0';
779 snprintf (kb, sizeof (kb), "Banner/%u",
780 sockets[i].port);
781 plug_set_key (desc, kb, ARG_STRING, buf);
782 x = DIFFTVu (ti, sockets[i].tictac) / 1000;
783 snprintf (kb, sizeof (kb),
784 "TCPScanner/RwTime1000/%u",
785 sockets[i].port);
786 plug_set_key (desc, kb, ARG_INT,
787 GSIZE_TO_POINTER (x));
788 snprintf (kb, sizeof (kb), "TCPScanner/RwTime/%u",
789 sockets[i].port);
791 desc, kb, ARG_INT,
792 GSIZE_TO_POINTER ((x + 500) / 1000));
793 }
794 wait_sock_nb--;
795 my_socket_close (sockets[i].fd);
796 sockets[i].fd = -1;
797 sockets[i].state = GRAB_SOCKET_UNUSED;
798 }
799 }
800 }
801 }
802
803 (void) gettimeofday (&ti, NULL);
804 for (i = 0; i < open_sock_nb; i++)
805 if (sockets[i].fd >= 0
806 && DIFFTV (ti, sockets[i].tictac) >= read_timeout)
807 {
808 switch (sockets[i].state)
809 {
810 case GRAB_SOCKET_OPEN:
811 timeout_nb++;
812 wait_sock_nb--;
813 snprintf (kb, sizeof (kb), "/tmp/NoBanner/%u",
814 sockets[i].port);
815 plug_set_key (desc, kb, ARG_INT, (void *) 1);
816 break;
818 ports_states[sockets[i].port] = GRAB_PORT_SILENT;
819 filtered_ports_nb++;
820 dropped_nb++;
821 untested_ports_nb--;
822 break;
823 default:
824 g_message (
825 "openvas_tcp_scanner: Unhandled case %d at %s:%d",
826 sockets[i].state, __FILE__, __LINE__);
827 break;
828 }
829 my_socket_close (sockets[i].fd);
830 sockets[i].fd = -1;
831 sockets[i].state = GRAB_SOCKET_UNUSED;
832 }
833
834 if (dropped_nb > 0 && dropped_nb >= (open_sock_nb * 3) / 4
835 && (dropped_nb < filtered_ports_nb
836 || dropped_nb > unfiltered_ports_nb))
837 {
838 /* firewalled machine? */
839 open_sock_max += dropped_nb;
840 if (open_sock_max2 < max_cnx)
841 open_sock_max2++;
842 }
843 else if (dropped_nb > 0)
844 {
845 dropped_flag = 1;
846 open_sock_max -= (dropped_nb + 2) / 3;
847 if (open_sock_max < min_cnx)
848 open_sock_max = min_cnx;
849 open_sock_max2 = (open_sock_max + 3 * open_sock_max2) / 4;
850 }
851 else if (dropped_nb == 0 && dropped_flag)
852 {
853 /* re-increase number of open sockets */
854 open_sock_max++;
855 }
856 open_sock_max += timeout_nb;
857 if (open_sock_max > open_sock_max2)
858 {
859 open_sock_max = open_sock_max2;
860 }
861 if (open_sock_max < min_cnx)
862 open_sock_max = min_cnx;
863 for (i = 0; i < open_sock_nb;)
864 if (sockets[i].state == GRAB_SOCKET_UNUSED || sockets[i].fd < 0)
865 {
866 for (j = i + 1; j < open_sock_nb
867 && (sockets[j].state == GRAB_SOCKET_UNUSED
868 || sockets[j].fd < 0);
869 j++)
870 ;
871 if (j < open_sock_nb)
872 memmove (sockets + i, sockets + j,
873 sizeof (*sockets) * (max_cnx - j));
874 open_sock_nb -= j - i;
875 }
876 else
877 i++;
878 }
879
880 end:
881 end_time = time (NULL);
882 diff_time1 = end_time - start_time_1pass;
883 diff_time = end_time - start_time;
884 if (dropped_flag
885 || (pass == 1 && filtered_ports_nb > 10 && closed_ports_nb > 10)
886 || (pass > 1 && filtered_ports_nb > 0))
887 {
888 if (doublecheck_flag && rst_rate_limit_flag
889 && open_ports_nb == old_opened)
890 break;
891 old_opened = open_ports_nb;
892
893 doublecheck_flag = 0;
894 if (filtered_ports_nb == old_filtered)
895 break;
896
897 if (pass > 1 && open_ports_nb1 == 0 && closed_ports_nb1 >= min_cnx &&
898 /*
899 * Default value is 100 RST per second on OpenBSD,
900 * 200 on FreeBSD and 40 on Solaris
901 */
902 /* 1st check on this pass only */
903 closed_ports_nb1 >= (diff_time1 + 1) * 10
904 && closed_ports_nb1 < (diff_time1 + 1) * 201 &&
905 /* 2nd check on all passes */
906 closed_ports_nb >= (diff_time + 1) * 10
907 && closed_ports_nb < (diff_time + 1) * 201)
908 {
909 /* BSD-like system */
910 int break_flag =
911 (open_sock_max2 <= GRAB_MAX_SOCK_SAFE) || rst_rate_limit_flag;
912 int tbd = break_flag && !doublecheck_flag
913 ? double_check_std_ports (ports_states)
914 : 0;
915 if (tbd > 0)
916 {
917 doublecheck_flag = 1;
918 break_flag = 0;
919 }
920 rst_rate_limit_flag++;
921 if (break_flag)
922 break;
923 }
924 /*
925 * With doublecheck_flag, the range of tested port is different, so
926 * we'd better count the number of filtered ports
927 */
928 old_filtered = 0;
929 for (port = 1; port <= 65535; port++)
930 if (ports_states[port] == GRAB_PORT_SILENT)
931 {
932 ports_states[port] = GRAB_PORT_UNKNOWN;
933 old_filtered++;
934 }
935 untested_ports_nb = old_filtered;
936 filtered_ports_nb = 0;
937 open_sock_max = min_cnx / (pass + 1);
938 if (open_sock_max < 1)
939 open_sock_max = 1;
940 if (!dropped_flag)
941 {
942 open_sock_max2 *= 2;
943 open_sock_max2 /= 3;
944 }
945 else if (rst_rate_limit_flag)
946 {
947 if (open_sock_max2 > GRAB_MAX_SOCK_SAFE)
948 open_sock_max2 = GRAB_MAX_SOCK_SAFE;
949 if (open_sock_max > GRAB_MAX_SOCK_SAFE)
950 open_sock_max = GRAB_MAX_SOCK_SAFE;
951 }
952 else if (open_sock_max2 <= open_sock_max)
953 open_sock_max2 = open_sock_max * 2;
954 }
955 else if (filtered_ports_nb > 0)
956 {
957 int tbd_nb = 0;
958 doublecheck_flag = 1;
959 /* Double check standard ports, just to avoid being ridiculous */
960
961 if ((tbd_nb = double_check_std_ports (ports_states)) == 0)
962 break;
963 old_filtered = untested_ports_nb = tbd_nb;
964 filtered_ports_nb = 0;
965 open_sock_max = min_cnx / pass;
966 if (open_sock_max2 <= open_sock_max)
967 open_sock_max2 = open_sock_max * 2;
968 if (open_sock_max2 > GRAB_MAX_SOCK_SAFE)
969 open_sock_max2 = GRAB_MAX_SOCK_SAFE;
970 if (open_sock_max > GRAB_MAX_SOCK_SAFE)
971 open_sock_max = GRAB_MAX_SOCK_SAFE;
972 }
973 else
974 break;
975 } /* for pass = ... */
976
977 if (pass > MAX_PASS_NB)
978 {
979 pass--;
980 filtered_ports_nb = old_filtered;
981 }
982
983 plug_set_key (desc, "TCPScanner/NbPasses", ARG_INT, GSIZE_TO_POINTER (pass));
984
985#if defined COMPUTE_RTT
986 for (i = 0; i < 3; i++)
987 if (rtt_nb[i] > 0)
988 {
989 char rep[64];
990 double crtt_mean, crtt_sd = -1.0, crtt_emax = -1.0;
991
992 /* Convert from micro-seconds to seconds */
993 rtt_sum[i] /= 1e6;
994 rtt_sum2[i] /= 1e12;
995
996 crtt_mean = rtt_sum[i] / rtt_nb[i];
997 snprintf (rep, sizeof (rep), "%6g", crtt_mean);
998 snprintf (kb, sizeof (kb), "TCPScanner/%s/MeanRTT", rtt_type[i]);
999 plug_set_key (desc, kb, ARG_STRING, rep);
1000 x = floor (crtt_mean * 1000 + 0.5);
1001 snprintf (kb, sizeof (kb), "TCPScanner/%s/MeanRTT1000", rtt_type[i]);
1002 plug_set_key (desc, kb, ARG_INT, GSIZE_TO_POINTER (x));
1003 /* rtt_max is integer (uS) */
1004 snprintf (kb, sizeof (kb), "TCPScanner/%s/MaxRTT1000", rtt_type[i]);
1005 plug_set_key (desc, kb, ARG_INT,
1006 GSIZE_TO_POINTER ((rtt_max[i] + 500) / 1000));
1007 snprintf (rep, sizeof (rep), "%6g",
1008 (rtt_max[i] + 500000.0) / 1000000.0);
1009 snprintf (kb, sizeof (kb), "TCPScanner/%s/MaxRTT", rtt_type[i]);
1010 plug_set_key (desc, kb, ARG_STRING, rep);
1011 if (rtt_nb[i] > 1)
1012 {
1013 crtt_sd = sqrt ((rtt_sum2[i] / rtt_nb[i] - crtt_mean * crtt_mean)
1014 * rtt_nb[i] / (rtt_nb[i] - 1));
1015 crtt_emax = crtt_mean + 3 * crtt_sd;
1016 snprintf (rep, sizeof (rep), "%6g", crtt_sd);
1017 snprintf (kb, sizeof (kb), "TCPScanner/%s/SDRTT", rtt_type[i]);
1018 plug_set_key (desc, kb, ARG_STRING, rep);
1019 x = floor (crtt_sd * 1000 + 0.5);
1020 snprintf (kb, sizeof (kb), "TCPScanner/%s/SDRTT1000", rtt_type[i]);
1021 plug_set_key (desc, kb, ARG_INT, GSIZE_TO_POINTER (x));
1022 snprintf (rep, sizeof (rep), "%6g", crtt_emax);
1023 snprintf (kb, sizeof (kb), "TCPScanner/%s/EstimatedMaxRTT",
1024 rtt_type[i]);
1025 plug_set_key (desc, kb, ARG_STRING, rep);
1026 x = floor (crtt_emax * 1000 + 0.5);
1027 snprintf (kb, sizeof (kb), "TCPScanner/%s/EstimatedMaxRTT1000",
1028 rtt_type[i]);
1029 plug_set_key (desc, kb, ARG_INT, GSIZE_TO_POINTER (x));
1030 }
1031 }
1032#endif
1033 plug_set_key (desc, "TCPScanner/OpenPortsNb", ARG_INT,
1034 GSIZE_TO_POINTER (open_ports_nb));
1035 plug_set_key (desc, "TCPScanner/ClosedPortsNb", ARG_INT,
1036 GSIZE_TO_POINTER (closed_ports_nb));
1037 plug_set_key (desc, "TCPScanner/FilteredPortsNb", ARG_INT,
1038 GSIZE_TO_POINTER (filtered_ports_nb));
1039 plug_set_key (desc, "TCPScanner/RSTRateLimit", ARG_INT,
1040 GSIZE_TO_POINTER (rst_rate_limit_flag));
1041 if (untested_ports_nb <= 0)
1042 plug_set_key (desc, "Host/full_scan", ARG_INT, GSIZE_TO_POINTER (1));
1043 plug_set_key (desc, "Host/num_ports_scanned", ARG_INT,
1044 GSIZE_TO_POINTER ((total_ports_nb - untested_ports_nb)));
1045 return 0;
1046}
#define DIFFTV(t1, t2)
#define GRAB_PORT_TESTING
#define DIFFTVu(t1, t2)
#define GRAB_PORT_UNKNOWN
#define GRAB_MAX_SOCK_SAFE
#define GRAB_PORT_REJECTED
#define GRAB_SOCKET_OPENING
static int my_socket_close(int s)
static int double_check_std_ports(unsigned char *ports_states)
#define GRAB_SOCKET_UNUSED
#define GRAB_PORT_NOT_TESTED
static struct timeval timeval(unsigned long val)
uint8_t len
void scanner_add_port(struct script_infos *args, int port, char *proto)
Definition plugutils.c:1146
void plug_set_key(struct script_infos *args, char *name, int type, const void *value)
Definition plugutils.c:1055
void * plug_get_key(struct script_infos *args, char *name, int *type, size_t *len, int single)
Get values from a kb under the given key name.
Definition plugutils.c:1226
#define ARG_STRING
Definition plugutils.h:19
#define ARG_INT
Definition plugutils.h:20

References ARG_INT, ARG_STRING, DIFFTV, DIFFTVu, double_check_std_ports(), grab_socket_t::fd, GRAB_MAX_SOCK, GRAB_MAX_SOCK_SAFE, GRAB_PORT_CLOSED, GRAB_PORT_NOT_TESTED, GRAB_PORT_OPEN, GRAB_PORT_REJECTED, GRAB_PORT_SILENT, GRAB_PORT_TESTING, GRAB_PORT_UNKNOWN, GRAB_SOCKET_OPEN, GRAB_SOCKET_OPENING, GRAB_SOCKET_UNUSED, len, MAX_PASS_NB, MAX_SANE_RTT, MAXINT, my_socket_close(), plug_get_key(), plug_set_key(), grab_socket_t::port, scanner_add_port(), grab_socket_t::state, and timeval().

Referenced by plugin_run_openvas_tcp_scanner().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ double_check_std_ports()

int double_check_std_ports ( unsigned char * ports_states)
static

Definition at line 123 of file nasl_builtin_openvas_tcp_scanner.c.

124{
125 int port, tbd_nb = 0;
126
127 for (port = 1; port <= 65535; port++)
128 if (std_port (port) && ports_states[port] == GRAB_PORT_SILENT)
129 {
130 ports_states[port] = GRAB_PORT_UNKNOWN;
131 tbd_nb++;
132 }
133 else if (ports_states[port] == GRAB_PORT_UNKNOWN)
134 {
135 g_message ("openvas_tcp_scanner: bug in double_check_std_ports!"
136 " Unknown port %d status",
137 port);
138 tbd_nb++;
139 }
140 return tbd_nb;
141}
static int std_port(int port)

References GRAB_PORT_SILENT, GRAB_PORT_UNKNOWN, and std_port().

Referenced by banner_grab().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ my_socket_close()

int my_socket_close ( int s)
static

Definition at line 103 of file nasl_builtin_openvas_tcp_scanner.c.

104{
105#ifndef SO_LINGER
106 shutdown (s, 2);
107#endif
108 return close (s);
109}

Referenced by banner_grab().

Here is the caller graph for this function:

◆ plugin_run_openvas_tcp_scanner()

tree_cell * plugin_run_openvas_tcp_scanner ( lex_ctxt * lexic)

Definition at line 1049 of file nasl_builtin_openvas_tcp_scanner.c.

1050{
1051 struct script_infos *desc = lexic->script_infos;
1052 const char *port_range = prefs_get ("port_range");
1053 const char *p;
1054 struct in6_addr *p_addr;
1055 unsigned int timeout = 0, max_cnx, min_cnx, x;
1056 int safe_checks = prefs_get_bool ("safe_checks");
1057
1058 p = prefs_get ("checks_read_timeout");
1059 if (p != NULL)
1060 timeout = atoi (p);
1061 if (timeout <= 0)
1062 timeout = 5;
1063 {
1064 int max_host = 0, max_checks = 0, cur_sys_fd = 0, max_sys_fd = 0;
1065 struct rlimit rlim;
1066 FILE *fp;
1067 int i;
1068 double loadavg[3], maxloadavg = -1.0;
1069 int stderr_fd = dup (2);
1070 int devnull_fd = open ("/dev/null", O_WRONLY);
1071 /* Avoid error messages from sysctl */
1072 if (devnull_fd <= 0)
1073 {
1074 if (stderr_fd != -1)
1075 close (stderr_fd);
1076 return NULL;
1077 }
1078 dup2 (devnull_fd, 2);
1079
1080 p = prefs_get ("max_hosts");
1081 if (p != NULL)
1082 max_host = atoi (p);
1083 if (max_host <= 0)
1084 max_host = 15;
1085
1086 p = prefs_get ("max_checks");
1087 if (p != NULL)
1088 max_checks = atoi (p);
1089 if (max_checks <= 0 || max_checks > 5)
1090 {
1091 max_checks = 5; /* bigger values do not make sense */
1092 g_debug ("openvas_tcp_scanner: max_checks forced to %d", max_checks);
1093 }
1094
1095 min_cnx = 8 * max_checks;
1096 if (safe_checks)
1097 max_cnx = 24 * max_checks;
1098 else
1099 max_cnx = 80 * max_checks;
1100
1101 getloadavg (loadavg, 3);
1102 for (i = 0; i < 3; i++)
1103 if (loadavg[i] > maxloadavg)
1104 maxloadavg = loadavg[i];
1105
1106 if (max_sys_fd <= 0)
1107 {
1108 fp = popen ("sysctl fs.file-nr", "r");
1109 if (fp != NULL)
1110 {
1111 if (fscanf (fp, "%*s = %*d %d %d", &cur_sys_fd, &max_sys_fd) == 1)
1112 max_sys_fd -= cur_sys_fd;
1113 else
1114 max_sys_fd = 0;
1115 pclose (fp);
1116 }
1117 }
1118 if (max_sys_fd <= 0)
1119 {
1120 fp = popen ("sysctl fs.file-max", "r");
1121 if (fp != NULL)
1122 {
1123 if (fscanf (fp, "%*s = %d", &max_sys_fd) < 1)
1124 max_sys_fd = 0;
1125 pclose (fp);
1126 }
1127 }
1128
1129 if (max_sys_fd <= 0)
1130 {
1131 fp = popen ("sysctl kern.maxfiles", "r");
1132 if (fp != NULL)
1133 {
1134 if (fscanf (fp, "%*s = %d", &max_sys_fd) < 1)
1135 max_sys_fd = 0;
1136 pclose (fp);
1137 }
1138 }
1139
1140 /* Restore stderr */
1141 close (devnull_fd);
1142 dup2 (stderr_fd, 2);
1143 close (stderr_fd);
1144
1145 if (maxloadavg >= 0.0)
1146 max_cnx /= (1.0 + maxloadavg);
1147
1148 if (max_sys_fd <= 0)
1149 max_sys_fd = 16384; /* reasonable default */
1150 /* Let's leave at least 1024 FD for other processes */
1151 if (max_sys_fd < 1024)
1152 x = GRAB_MIN_SOCK;
1153 else
1154 {
1155 max_sys_fd -= 1024;
1156 x = max_sys_fd / max_host;
1157 }
1158 if (max_cnx > x)
1159 max_cnx = x;
1160 if (max_cnx > GRAB_MAX_SOCK)
1161 max_cnx = GRAB_MAX_SOCK;
1162 if (max_cnx < GRAB_MIN_SOCK)
1163 max_cnx = GRAB_MIN_SOCK;
1164
1165 if (safe_checks && max_cnx > GRAB_MAX_SOCK_SAFE)
1166 max_cnx = GRAB_MAX_SOCK_SAFE;
1167
1168 if (getrlimit (RLIMIT_NOFILE, &rlim) < 0)
1169 perror ("getrlimit(RLIMIT_NOFILE)");
1170 else
1171 {
1172 /* value = one greater than the maximum file descriptor number */
1173 if (rlim.rlim_cur != RLIM_INFINITY && max_cnx >= rlim.rlim_cur)
1174 max_cnx = rlim.rlim_cur - 1;
1175 }
1176 x = max_cnx / 2;
1177 if (min_cnx > x)
1178 min_cnx = x > 0 ? x : 1;
1179 }
1180
1181 p_addr = desc->ip;
1182 if (p_addr == NULL)
1183 return NULL; // TODO: before it returned "1";
1184 if (banner_grab (p_addr, port_range, timeout, min_cnx, max_cnx, desc) < 0)
1185 return NULL; // TODO: before it returned "1";
1186 plug_set_key (desc, "Host/scanned", ARG_INT, (void *) 1);
1187 plug_set_key (desc, "Host/scanners/openvas_tcp_scanner", ARG_INT, (void *) 1);
1188 return NULL;
1189}
static int banner_grab(const struct in6_addr *pia, const char *portrange, const int read_timeout, int min_cnx, int max_cnx, struct script_infos *desc)
tree_cell * safe_checks(lex_ctxt *lexic)
struct in6_addr * ip
Definition scanneraux.h:37
struct script_infos * script_infos

References ARG_INT, banner_grab(), GRAB_MAX_SOCK, GRAB_MAX_SOCK_SAFE, GRAB_MIN_SOCK, script_infos::ip, plug_set_key(), safe_checks(), and struct_lex_ctxt::script_infos.

Here is the call graph for this function:

◆ std_port()

int std_port ( int port)
static
Todo
: We are not able anymore to judge whether a port is a standard port. Previously a port was believed to be a standard port when it occurred in the currently configured list of ports. This needs to be resolved.

Definition at line 112 of file nasl_builtin_openvas_tcp_scanner.c.

113{
114 (void) port;
115 return 0;
120}

Referenced by double_check_std_ports().

Here is the caller graph for this function: