diff options
| author | Root THC | 2026-02-24 12:42:47 +0000 |
|---|---|---|
| committer | Root THC | 2026-02-24 12:42:47 +0000 |
| commit | c9cbeced5b3f2bdd7407e29c0811e65954132540 (patch) | |
| tree | aefc355416b561111819de159ccbd86c3004cf88 /other/b-scan/tmp/src/bscan.c | |
| parent | 073fe4bf9fca6bf40cef2886d75df832ef4b6fca (diff) | |
initial
Diffstat (limited to 'other/b-scan/tmp/src/bscan.c')
| -rw-r--r-- | other/b-scan/tmp/src/bscan.c | 851 |
1 files changed, 851 insertions, 0 deletions
diff --git a/other/b-scan/tmp/src/bscan.c b/other/b-scan/tmp/src/bscan.c new file mode 100644 index 0000000..ed49d1b --- /dev/null +++ b/other/b-scan/tmp/src/bscan.c | |||
| @@ -0,0 +1,851 @@ | |||
| 1 | /* | ||
| 2 | * This is unpublished proprietary source code. | ||
| 3 | * | ||
| 4 | * The contents of these coded instructions, statements and computer | ||
| 5 | * programs may not be disclosed to third parties, copied or duplicated in | ||
| 6 | * any form, in whole or in part, without the prior written permission of | ||
| 7 | * the author. | ||
| 8 | * (that includes you hack.co.za and other lame kid sites who dont | ||
| 9 | * get the point what hacking is about. damn kids.) | ||
| 10 | * | ||
| 11 | * (C) COPYRIGHT by me, 2000 | ||
| 12 | * All Rights Reserved | ||
| 13 | */ | ||
| 14 | |||
| 15 | |||
| 16 | #include <stdlib.h> | ||
| 17 | #include <math.h> | ||
| 18 | #include <bscan/bscan.h> | ||
| 19 | #include <bscan/snarf.h> | ||
| 20 | #include <bscan/tty.h> | ||
| 21 | #include <bscan/system.h> | ||
| 22 | #include <bscan/restore.h> | ||
| 23 | #include <bscan/module.h> | ||
| 24 | #include <bscan/version.h> | ||
| 25 | #include <bscan/cf_prse.h> | ||
| 26 | #include <sys/types.h> | ||
| 27 | #include <signal.h> | ||
| 28 | #include <math.h> | ||
| 29 | #include <libnet.h> | ||
| 30 | |||
| 31 | #ifdef HAVE_DLSYM | ||
| 32 | extern const int modcount; | ||
| 33 | extern const struct _mods mods[MAX_MODULES]; | ||
| 34 | #endif | ||
| 35 | |||
| 36 | unsigned char packet[1024]; | ||
| 37 | struct _opt *opt; | ||
| 38 | |||
| 39 | #define OPTS "XOVhavr:C:L:M:m:l:d:p:i:s:f:o:" | ||
| 40 | |||
| 41 | static unsigned long int gennextip (void); | ||
| 42 | static unsigned long int gennext_spreadip (void); | ||
| 43 | static unsigned long int gennext_random (void); | ||
| 44 | |||
| 45 | /* | ||
| 46 | * make static mac entry in arp-table. | ||
| 47 | * We use system() here [setting mac entry is heavily system dependent] | ||
| 48 | */ | ||
| 49 | int | ||
| 50 | setarp (uint32_t ip, u_char * mac) | ||
| 51 | { | ||
| 52 | char buf[128]; | ||
| 53 | u_char *p = (u_char *) mac; | ||
| 54 | |||
| 55 | snprintf (buf, sizeof (buf) - 1, | ||
| 56 | "arp -s %s %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", int_ntoa (ip), | ||
| 57 | p[0], p[1], p[2], p[3], p[4], p[5]); | ||
| 58 | /* put all your IFL fun in here ! this is the major security hole | ||
| 59 | you were looking for.... */ | ||
| 60 | |||
| 61 | return (system (buf)); | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
| 65 | /* | ||
| 66 | * delete the mac entry from the arp-table. | ||
| 67 | * we use system() again | ||
| 68 | */ | ||
| 69 | int | ||
| 70 | unsetarp (uint32_t ip) | ||
| 71 | { | ||
| 72 | char buf[128]; | ||
| 73 | |||
| 74 | snprintf (buf, sizeof (buf) - 1, "arp -d %s", int_ntoa (ip)); | ||
| 75 | /* put all your IFL fun in here ! this is the major security hole | ||
| 76 | you were looking for.... */ | ||
| 77 | |||
| 78 | return (system (buf)); | ||
| 79 | } | ||
| 80 | |||
| 81 | |||
| 82 | static void | ||
| 83 | usage (int code, char *fmt, ...) | ||
| 84 | { | ||
| 85 | char buf[1024]; | ||
| 86 | va_list ap; | ||
| 87 | u_char *p = (u_char *) opt->spf_smac; | ||
| 88 | int c; | ||
| 89 | |||
| 90 | printf (VERSION "\n"); | ||
| 91 | printf (" b-scan -s <spoofed source ip> [options] <host/network> ...\n"); | ||
| 92 | printf (" format of <host/network>:\n"); | ||
| 93 | printf (" <host>, 10.23.0.1 or\n"); | ||
| 94 | printf (" <start ip>-<end ip>, 10.23.0.1-10.23.255.254 or\n"); | ||
| 95 | printf (" <start network/mask>, 10.23.0.1/16\n\n"); | ||
| 96 | printf ("Options:\n"); | ||
| 97 | printf (" -r <restore.bscan>\n"); | ||
| 98 | #ifdef HAVE_DLSYM | ||
| 99 | printf (" -L <module.so, shared library file>\n"); | ||
| 100 | #endif | ||
| 101 | printf (" -f <hostlist, one ip/line>\n"); | ||
| 102 | printf (" -s <spoofed ip address on your LOCAL (!) network>\n"); | ||
| 103 | printf (" -m <mac>, make a static arp-entry and spoof from this mac.\n"); | ||
| 104 | printf | ||
| 105 | (" -M <mac>, dont make the static arpentry but spoof from this mac.\n"); | ||
| 106 | printf (" Add the mac to your arp-table manually (arp -s ip mac),\n"); | ||
| 107 | printf (" If no mac is given default mac is used:\n"); | ||
| 108 | printf (" MAC : %x:%x:%x:%x:%x:%x\n", p[0], p[1], p[2], p[3], p[4], | ||
| 109 | p[5]); | ||
| 110 | printf (" -i <ethernet interface>, default eth0\n"); | ||
| 111 | printf | ||
| 112 | (" -X spreadmode [non-sequential, experimental but recommended]\n"); | ||
| 113 | printf (" -O output ip's, dont scan\n"); | ||
| 114 | printf | ||
| 115 | (" -l <pps> limit packets per second, default 1000, 0 = unlimited\n"); | ||
| 116 | printf | ||
| 117 | (" -d <delay> w8 delay seconds for outstanding packets, default 10\n"); | ||
| 118 | printf (" -C <configuration file>\n"); | ||
| 119 | printf (" -v verbose output\n\n"); | ||
| 120 | printf ("Example:\n"); | ||
| 121 | printf ("# bscan -s 10.1.6.6 -i eth2 -L \"modules/mod_banner.so\" -X 2.4.1.0-2.4.9.9\n"); | ||
| 122 | |||
| 123 | #ifdef HAVE_DLSYM | ||
| 124 | for (c = 0; c < modcount; c++) | ||
| 125 | mods[c].musage (); | ||
| 126 | #endif | ||
| 127 | |||
| 128 | if (fmt != NULL) | ||
| 129 | { | ||
| 130 | va_start (ap, fmt); | ||
| 131 | vsnprintf (buf, sizeof (buf) - 1, fmt, ap); | ||
| 132 | va_end (ap); | ||
| 133 | fprintf (stderr, "ERROR: %s\n", buf); | ||
| 134 | } | ||
| 135 | |||
| 136 | exit (code); | ||
| 137 | } | ||
| 138 | |||
| 139 | /* | ||
| 140 | * read's next ip from file. | ||
| 141 | * returns ip in NBO | ||
| 142 | * returns -1 (eg. 255.255.255.255) on failure | ||
| 143 | */ | ||
| 144 | unsigned long int | ||
| 145 | readnextip (void) | ||
| 146 | { | ||
| 147 | char buf[64]; | ||
| 148 | |||
| 149 | if (opt->ffd == NULL) | ||
| 150 | { | ||
| 151 | if ((opt->ffd = fopen (opt->hostfile, "r")) == NULL) | ||
| 152 | { | ||
| 153 | perror ("unable to open hostfile"); | ||
| 154 | return (-1); | ||
| 155 | } | ||
| 156 | opt->target = opt->hostfile; | ||
| 157 | } | ||
| 158 | fgets (buf, sizeof (buf), opt->ffd); | ||
| 159 | |||
| 160 | return (inet_addr (buf)); | ||
| 161 | } | ||
| 162 | |||
| 163 | /* | ||
| 164 | * get next ip in NBO from network/mask | ||
| 165 | * [could be random order] | ||
| 166 | * returns -1 [255.255.255.255] if no more ip's | ||
| 167 | * hint: rfc: "the first and last ip in a subnetwork are reserved" | ||
| 168 | */ | ||
| 169 | static unsigned long int | ||
| 170 | gennextip (void) | ||
| 171 | { | ||
| 172 | |||
| 173 | if (opt->ip_pos <= opt->end_ip) | ||
| 174 | return (htonl (opt->ip_pos++)); | ||
| 175 | |||
| 176 | return (-1); | ||
| 177 | |||
| 178 | } | ||
| 179 | |||
| 180 | /* | ||
| 181 | * generate next ip in spread-mode | ||
| 182 | * must: ip.end_ip - ip.start_ip > 2 | ||
| 183 | */ | ||
| 184 | static unsigned long int | ||
| 185 | gennext_spreadip (void) | ||
| 186 | { | ||
| 187 | u_long pos = opt->ip_pos; | ||
| 188 | |||
| 189 | |||
| 190 | if ((opt->ip_offset + 1 >= opt->ip_blklen) && (opt->ip_pos > opt->end_ip)) | ||
| 191 | return (-1); | ||
| 192 | |||
| 193 | if ((opt->ip_pos + opt->ip_blklen > opt->end_ip) | ||
| 194 | && (opt->ip_offset + 1 < opt->ip_blklen)) | ||
| 195 | opt->ip_pos = opt->start_ip + (++opt->ip_offset); | ||
| 196 | else | ||
| 197 | opt->ip_pos += opt->ip_blklen; | ||
| 198 | |||
| 199 | return (htonl (pos)); | ||
| 200 | |||
| 201 | } | ||
| 202 | |||
| 203 | |||
| 204 | static unsigned long int | ||
| 205 | gennext_random (void) | ||
| 206 | { | ||
| 207 | unsigned long int ip; | ||
| 208 | |||
| 209 | if (opt->random_maxcount != 0) { | ||
| 210 | if (--opt->random_maxcount == 0) | ||
| 211 | return (-1); | ||
| 212 | } | ||
| 213 | |||
| 214 | pitch: | ||
| 215 | ip = (random () & 0xffff) << 16; | ||
| 216 | ip |= random () & 0xffff; | ||
| 217 | |||
| 218 | if (((ip & 0xe0000000) >= 0xe0000000) || /* 224.0.0.0/3 */ | ||
| 219 | ((ip & 0xff000000) == 0x7f000000) || /* 127.0.0.0/8 */ | ||
| 220 | ((ip & 0xff000000) == 0x0a000000) || /* 10.0.0.0/8 */ | ||
| 221 | ((ip & 0xffff0000) == 0xc0a80000) || /* 192.168.0.0/16 */ | ||
| 222 | ((ip & 0xffff0000) == 0xac100000) || /* 172.16.0.0/16 */ | ||
| 223 | (ip == 0x00000000)) /* 0.0.0.0/32 */ | ||
| 224 | goto pitch; | ||
| 225 | |||
| 226 | return (htonl (ip)); | ||
| 227 | } | ||
| 228 | |||
| 229 | |||
| 230 | /* | ||
| 231 | * process all the options and load/init modules | ||
| 232 | */ | ||
| 233 | void | ||
| 234 | do_opt (int argc, char *argv[]) | ||
| 235 | { | ||
| 236 | extern char *optarg; | ||
| 237 | extern int optind; /*, opterr, optopt;*/ | ||
| 238 | unsigned short int sp[ETH_ALEN]; | ||
| 239 | int c; | ||
| 240 | char do_usage = 0; | ||
| 241 | |||
| 242 | |||
| 243 | while ((c = getopt (argc, argv, OPTS)) != -1) | ||
| 244 | { | ||
| 245 | switch (c) | ||
| 246 | { | ||
| 247 | case 'C': /* process conf file */ | ||
| 248 | if (readConfFile (optarg)) | ||
| 249 | { | ||
| 250 | opt->flags |= FileOpt.flags; | ||
| 251 | opt->limit = FileOpt.limit; | ||
| 252 | opt->delay = FileOpt.delay; | ||
| 253 | opt->nt.src = FileOpt.srcAddr; | ||
| 254 | opt->lnet.device = FileOpt.device; | ||
| 255 | for (c = 0; c < 6; c++) | ||
| 256 | opt->spf_smac[c] = FileOpt.mac[c]; | ||
| 257 | } | ||
| 258 | else | ||
| 259 | fprintf (stderr, "%s is not a valid vonfig file\n", optarg); | ||
| 260 | break; | ||
| 261 | case 'L': | ||
| 262 | break; /* process module stuff AFTER main-opts */ | ||
| 263 | case 'h': | ||
| 264 | do_usage = 1; | ||
| 265 | break; | ||
| 266 | case 'r': | ||
| 267 | if (read_restore (optarg) != 0) | ||
| 268 | { | ||
| 269 | fprintf (stderr, "unable to read restore file '%s'\n", | ||
| 270 | optarg); | ||
| 271 | exit (-1); | ||
| 272 | } | ||
| 273 | opt->flags |= OPT_REST; | ||
| 274 | break; | ||
| 275 | case 'l': | ||
| 276 | opt->limit = atoi (optarg); | ||
| 277 | break; | ||
| 278 | case 'v': | ||
| 279 | opt->flags |= OPT_VERB; | ||
| 280 | break; | ||
| 281 | case 'X': | ||
| 282 | opt->flags |= OPT_SPREADSCAN; | ||
| 283 | break; | ||
| 284 | case 'O': | ||
| 285 | opt->flags |= OPT_OUTONLY; /* dont scan, output ip's only */ | ||
| 286 | break; | ||
| 287 | case 'm': | ||
| 288 | opt->flags |= OPT_SETARP; | ||
| 289 | sscanf (optarg, "%hx:%hx:%hx:%hx:%hx:%hx", &sp[0], &sp[1], &sp[2], | ||
| 290 | &sp[3], &sp[4], &sp[5]); | ||
| 291 | for (c = 0; c < 6; c++) | ||
| 292 | opt->spf_smac[c] = (u_char) sp[c]; | ||
| 293 | break; | ||
| 294 | case 'M': | ||
| 295 | opt->flags &= ~OPT_SETARP; | ||
| 296 | sscanf (optarg, "%hx:%hx:%hx:%hx:%hx:%hx", &sp[0], &sp[1], &sp[2], | ||
| 297 | &sp[3], &sp[4], &sp[5]); | ||
| 298 | for (c = 0; c < 6; c++) | ||
| 299 | opt->spf_smac[c] = (u_char) sp[c]; | ||
| 300 | break; | ||
| 301 | case 'd': | ||
| 302 | opt->delay = atoi (optarg); | ||
| 303 | break; | ||
| 304 | case 'i': | ||
| 305 | opt->lnet.device = optarg; | ||
| 306 | break; | ||
| 307 | case 's': | ||
| 308 | opt->nt.src = inet_addr (optarg); | ||
| 309 | break; | ||
| 310 | case 'f': | ||
| 311 | opt->hostfile = optarg; | ||
| 312 | opt->flags |= OPT_HOSTFILE; | ||
| 313 | break; | ||
| 314 | case 'V': | ||
| 315 | printf (VERSION "\n"); | ||
| 316 | exit (0); | ||
| 317 | case ':': | ||
| 318 | usage (0, "parameter missing", c); | ||
| 319 | break; | ||
| 320 | default: | ||
| 321 | break; | ||
| 322 | usage (0, "unknown option -%c", c); | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 326 | /* | ||
| 327 | * init modules AFTER processing main-opts | ||
| 328 | */ | ||
| 329 | #ifdef HAVE_DLSYM | ||
| 330 | optind = 1; | ||
| 331 | while ((c = getopt (argc, argv, OPTS)) != -1) | ||
| 332 | { | ||
| 333 | switch (c) | ||
| 334 | { | ||
| 335 | case 'L': | ||
| 336 | loadinit_mod(optarg); | ||
| 337 | break; | ||
| 338 | } /* eo switch(c) */ | ||
| 339 | } /* eo while */ | ||
| 340 | #endif | ||
| 341 | if (do_usage != 0) | ||
| 342 | usage (0, NULL); | ||
| 343 | |||
| 344 | if ((optind < argc) && (!(opt->flags & OPT_REST))) | ||
| 345 | opt->argvlist = &argv[optind]; | ||
| 346 | if (opt->flags & OPT_OUTONLY) | ||
| 347 | opt->delay = 0; | ||
| 348 | if (opt->nt.src == -1) | ||
| 349 | usage (0, "you must specify a -s source address"); | ||
| 350 | if ((opt->argvlist == NULL) && (opt->hostfile == NULL)) | ||
| 351 | usage (0, "you must specify a -f hostfile or an ip-range"); | ||
| 352 | |||
| 353 | } | ||
| 354 | |||
| 355 | /* | ||
| 356 | * called via SIGCHLD and w8 for the pid [to destroy last kernel structure] | ||
| 357 | * OBSOLETE, ###fixme | ||
| 358 | */ | ||
| 359 | void | ||
| 360 | waitchld (int sig) | ||
| 361 | { | ||
| 362 | int status; | ||
| 363 | wait (&status); /* exit status of the child */ | ||
| 364 | } | ||
| 365 | |||
| 366 | void | ||
| 367 | sig_handle_abort (int sig) | ||
| 368 | { | ||
| 369 | |||
| 370 | if (pthread_self() != opt->bscantid) | ||
| 371 | return; | ||
| 372 | |||
| 373 | fprintf (stderr, "Session aborted ...one more to kill process\n"); | ||
| 374 | signal (sig, die); | ||
| 375 | opt->flags |= OPT_ABRT; | ||
| 376 | } | ||
| 377 | |||
| 378 | /* | ||
| 379 | * generic signal driver :> | ||
| 380 | */ | ||
| 381 | void | ||
| 382 | sigdriver (int sig) | ||
| 383 | { | ||
| 384 | |||
| 385 | if (pthread_self() != opt->bscantid) | ||
| 386 | return; | ||
| 387 | |||
| 388 | if (sig == SIGUSR1) | ||
| 389 | print_scanstat (stderr); | ||
| 390 | if ((sig == SIGINT) || (sig == SIGQUIT)) /* ctrl-c */ | ||
| 391 | sig_handle_abort (sig); | ||
| 392 | } | ||
| 393 | |||
| 394 | /* | ||
| 395 | * This function MUST be called on exit (..or use atexit():) | ||
| 396 | * we have threads. Doesnt matter which thread calls this | ||
| 397 | * function...do everything and exit() the process | ||
| 398 | * (kills all threads...not very gentle...but...). | ||
| 399 | */ | ||
| 400 | void | ||
| 401 | die (int sig) | ||
| 402 | { | ||
| 403 | int c = 0; | ||
| 404 | |||
| 405 | print_scanstat (stderr); /* print before cleanup routines...*/ | ||
| 406 | |||
| 407 | if (opt->flags & OPT_ABRT) | ||
| 408 | if (write_restore () != 0) | ||
| 409 | perror ("restorefile failed"); | ||
| 410 | if ((opt->flags & OPT_SETARP) && (unsetarp (opt->nt.src) != 0)) | ||
| 411 | fprintf (stderr, "unable to unset arpentry. do it manually\n"); | ||
| 412 | #ifdef HAVE_DLSYM | ||
| 413 | while (c < modcount) | ||
| 414 | mods[c++].fini (); | ||
| 415 | #endif | ||
| 416 | |||
| 417 | #ifdef DEBUG | ||
| 418 | printf ("calling exit.\n"); | ||
| 419 | #endif | ||
| 420 | |||
| 421 | fflush (stdout); | ||
| 422 | |||
| 423 | exit (0); | ||
| 424 | } | ||
| 425 | |||
| 426 | /* | ||
| 427 | * reset all vars used during the scan (counters, ...) | ||
| 428 | * should be called before the call to make_iprange() | ||
| 429 | * If not...make_iprange thinks we use restore-file | ||
| 430 | */ | ||
| 431 | void | ||
| 432 | reset_vars () | ||
| 433 | { | ||
| 434 | opt->target = NULL; | ||
| 435 | opt->ipscan_count = 0; | ||
| 436 | opt->bsent_count = 0; | ||
| 437 | opt->ip_offset = 0; | ||
| 438 | opt->ip_blklen = 0; | ||
| 439 | opt->ip_pos = 0; | ||
| 440 | opt->start_ip = 0; | ||
| 441 | opt->end_ip = 0; | ||
| 442 | opt->snarf.close_c = 0; | ||
| 443 | opt->snarf.open_c = 0; | ||
| 444 | opt->snarf.refused_c = 0; | ||
| 445 | opt->snarf.icmp_c = 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | |||
| 449 | void | ||
| 450 | init_vars (char **nullptr) | ||
| 451 | { | ||
| 452 | srandom ((unsigned int) time (NULL)); | ||
| 453 | |||
| 454 | if ((opt = calloc (1, sizeof (*opt))) == NULL) | ||
| 455 | { | ||
| 456 | perror ("calloc"); | ||
| 457 | exit (-1); | ||
| 458 | } | ||
| 459 | memset (opt, 0, sizeof (struct _opt)); | ||
| 460 | |||
| 461 | opt->bscantid = 0; | ||
| 462 | opt->snarftid = 0; | ||
| 463 | opt->packet = packet; | ||
| 464 | opt->pkg_maxlen = sizeof (packet); | ||
| 465 | opt->pkg_len = 0; | ||
| 466 | opt->scan_start.tv_sec = 0; | ||
| 467 | opt->iptotscan_count = 0; | ||
| 468 | opt->scan_start.tv_usec = 0; | ||
| 469 | opt->hostfile = NULL; | ||
| 470 | opt->limit = 1000; | ||
| 471 | opt->flags = OPT_SETARP; | ||
| 472 | opt->ffd = NULL; | ||
| 473 | opt->argvlist = nullptr; | ||
| 474 | opt->lnet.device = NULL; /* done by libnet and libpcap */ | ||
| 475 | memcpy (opt->spf_smac, SPF_SMAC, 6); | ||
| 476 | opt->nt.src = -1; | ||
| 477 | opt->nt.dst = -1; | ||
| 478 | opt->delay = 10; | ||
| 479 | opt->lnet.device = NULL; | ||
| 480 | reset_vars (); | ||
| 481 | |||
| 482 | signal (SIGINT, sigdriver); | ||
| 483 | signal (SIGQUIT, sigdriver); | ||
| 484 | signal (SIGTERM, die); /* also called by client */ | ||
| 485 | signal (SIGCHLD, SIG_IGN); | ||
| 486 | signal (SIGUSR1, sigdriver); | ||
| 487 | } | ||
| 488 | |||
| 489 | void | ||
| 490 | print_opt () | ||
| 491 | { | ||
| 492 | u_char *p = (u_char *) opt->spf_smac; | ||
| 493 | |||
| 494 | fprintf (stderr, "Pid : %d\n", getpid()); | ||
| 495 | fprintf (stderr, "Interface : %s\n", opt->lnet.device); | ||
| 496 | fprintf (stderr, "Source IP : %s\n", int_ntoa (opt->nt.src)); | ||
| 497 | fprintf (stderr, "Source MAC : %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", | ||
| 498 | p[0], p[1], p[2], p[3], p[4], p[5]); | ||
| 499 | fprintf (stderr, "pps : %u\n", opt->limit); | ||
| 500 | } | ||
| 501 | |||
| 502 | /* | ||
| 503 | * print scanstatistics on filedes | ||
| 504 | */ | ||
| 505 | void | ||
| 506 | print_scanstat (FILE * fd) | ||
| 507 | { | ||
| 508 | char perc = 100; | ||
| 509 | struct timeval tv2; | ||
| 510 | time_t timep; | ||
| 511 | struct tm mytm; | ||
| 512 | |||
| 513 | gettimeofday (&tv2, NULL); | ||
| 514 | time_diff (&opt->scan_start, &tv2); | ||
| 515 | if (tv2.tv_sec == 0) | ||
| 516 | tv2.tv_sec = 1; | ||
| 517 | timep = tv2.tv_sec; | ||
| 518 | gmtime_r (&timep, &mytm); | ||
| 519 | |||
| 520 | if ((opt->end_ip - opt->start_ip) != 0) | ||
| 521 | perc = | ||
| 522 | (((float) | ||
| 523 | opt->ipscan_count / (float) (opt->end_ip - | ||
| 524 | opt->start_ip)) * 100); | ||
| 525 | |||
| 526 | fprintf (fd, | ||
| 527 | "%2.2d:%2.2d:%2.2d:%2.2d %s %3d%% p/s: %6d [o:%lu r:%lu c:%lu i:%lu]\n", | ||
| 528 | mytm.tm_yday, mytm.tm_hour, mytm.tm_min, mytm.tm_sec, | ||
| 529 | opt->target, perc, (int) (opt->iptotscan_count / tv2.tv_sec), | ||
| 530 | opt->snarf.open_c, opt->snarf.refused_c, opt->snarf.close_c, | ||
| 531 | opt->snarf.icmp_c); | ||
| 532 | |||
| 533 | } | ||
| 534 | |||
| 535 | |||
| 536 | /* | ||
| 537 | * calculate beginning and end of ip-range | ||
| 538 | * set start_ip and end_ip and target | ||
| 539 | */ | ||
| 540 | void | ||
| 541 | make_iprange (u_long * network, u_long * netmask, u_long * start_ip, | ||
| 542 | u_long * end_ip, char *str) | ||
| 543 | { | ||
| 544 | char buf[64]; | ||
| 545 | char *ptr; | ||
| 546 | |||
| 547 | opt->target = str; | ||
| 548 | strncpy (buf, str, sizeof (buf)); | ||
| 549 | buf[sizeof (buf) - 1] = '\0'; | ||
| 550 | opt->getnextip = NULL; | ||
| 551 | *start_ip = 0; | ||
| 552 | |||
| 553 | if (strncmp (buf, "random", 6) == 0) { | ||
| 554 | opt->getnextip = (void *) gennext_random; | ||
| 555 | if (strchr (buf, ':') != NULL) { | ||
| 556 | sscanf (strchr (buf, ':') + 1, "%lu", &opt->random_maxcount); | ||
| 557 | } else { | ||
| 558 | opt->random_maxcount = 0; | ||
| 559 | } | ||
| 560 | return; | ||
| 561 | } | ||
| 562 | |||
| 563 | /* a.b.c.d/e */ | ||
| 564 | if (strchr (buf, '/') != NULL) | ||
| 565 | { | ||
| 566 | *netmask = 0xffffffff; /* for the lamers who forget the /<netmask> */ | ||
| 567 | |||
| 568 | if ((ptr = (char *) strrchr (buf, '/')) != NULL) | ||
| 569 | *netmask = 0xffffffff << (32 - atoi (ptr + 1)); | ||
| 570 | |||
| 571 | if ((ptr = (char *) strchr (buf, '/')) != NULL) | ||
| 572 | *ptr = '\0'; | ||
| 573 | |||
| 574 | *network = (ntohl (inet_addr (buf)) & *netmask); | ||
| 575 | *start_ip = (*network & *netmask) + 1; | ||
| 576 | *end_ip = (*network | ~*netmask) - 1; | ||
| 577 | if (*netmask >= 0xfffffffe) | ||
| 578 | (*start_ip)--; | ||
| 579 | if (*netmask == 0xffffffff) | ||
| 580 | (*end_ip)++; | ||
| 581 | } | ||
| 582 | |||
| 583 | /* a.b.c.d - w.x.y.z */ | ||
| 584 | if ((*start_ip == 0) && ((ptr = (char *) strrchr (buf, '-')) != NULL)) | ||
| 585 | { | ||
| 586 | *end_ip = ntohl (inet_addr (ptr + 1)); | ||
| 587 | *ptr = '\0'; | ||
| 588 | *start_ip = ntohl (inet_addr (buf)); | ||
| 589 | } | ||
| 590 | |||
| 591 | /* a.b.c.d */ | ||
| 592 | if (*start_ip == 0) | ||
| 593 | { | ||
| 594 | *end_ip = ntohl (inet_addr (buf)); | ||
| 595 | *start_ip = ntohl (inet_addr (buf)); | ||
| 596 | } | ||
| 597 | |||
| 598 | if (opt->ip_pos == 0) /* if != 0 we use restore-file */ | ||
| 599 | opt->ip_pos = *start_ip; | ||
| 600 | |||
| 601 | /* initialize getnextip-funtion and spread scan variables */ | ||
| 602 | if ((opt->flags & OPT_SPREADSCAN) && (opt->end_ip - opt->start_ip > 2)) | ||
| 603 | { | ||
| 604 | init_spreadscan (opt->end_ip - opt->start_ip); | ||
| 605 | opt->getnextip = (void *) gennext_spreadip; | ||
| 606 | } | ||
| 607 | else | ||
| 608 | { | ||
| 609 | opt->getnextip = (void *) gennextip; | ||
| 610 | } | ||
| 611 | |||
| 612 | } | ||
| 613 | |||
| 614 | /* | ||
| 615 | * initialize offset for spread-scan | ||
| 616 | * call make_iprange before | ||
| 617 | * | ||
| 618 | * most networks are /24. dont let ip_blklen get to big | ||
| 619 | */ | ||
| 620 | void | ||
| 621 | init_spreadscan (u_long diff) | ||
| 622 | { | ||
| 623 | opt->ip_blklen = (u_long) sqrt (diff); | ||
| 624 | |||
| 625 | if (opt->ip_blklen > 100) /* range is 100^2 large */ | ||
| 626 | opt->ip_blklen = 257 + opt->ip_blklen * 0.2; /* use a prime# here */ | ||
| 627 | |||
| 628 | } | ||
| 629 | |||
| 630 | |||
| 631 | /* | ||
| 632 | * output the ip's only. dont scan. | ||
| 633 | */ | ||
| 634 | void | ||
| 635 | do_outonly () | ||
| 636 | { | ||
| 637 | uint32_t ip; | ||
| 638 | |||
| 639 | while ((ip = (*opt->getnextip) ()) != -1) | ||
| 640 | { | ||
| 641 | opt->ipscan_count++; | ||
| 642 | printf ("%s\n", int_ntoa (ip)); | ||
| 643 | } | ||
| 644 | |||
| 645 | } | ||
| 646 | |||
| 647 | |||
| 648 | /* | ||
| 649 | * process a scanrange from argv | ||
| 650 | * Return -1 if abort | ||
| 651 | */ | ||
| 652 | int | ||
| 653 | process_iprange () | ||
| 654 | { | ||
| 655 | int c = 0; | ||
| 656 | int ret; | ||
| 657 | #ifdef HAVE_DLSYM | ||
| 658 | int mc = 0; | ||
| 659 | #endif | ||
| 660 | |||
| 661 | while ((opt->nt.dst = (*opt->getnextip) ()) != -1) | ||
| 662 | { | ||
| 663 | memset (opt->packet, 0, opt->pkg_maxlen); | ||
| 664 | |||
| 665 | opt->pkg_len = 0; | ||
| 666 | |||
| 667 | if (opt->flags & OPT_VERB) | ||
| 668 | fprintf (stderr, "scanning %s:%d\n", | ||
| 669 | int_ntoa (opt->nt.dst), ntohs (opt->nt.dport)); | ||
| 670 | |||
| 671 | #ifdef HAVE_DLSYM | ||
| 672 | for (mc = 0; mc < modcount; mc++) | ||
| 673 | { | ||
| 674 | ret = mods[mc].callmdl (MOD_FIRSTPKG, opt); | ||
| 675 | if (ret == RMOD_SKIP) | ||
| 676 | continue; | ||
| 677 | if (ret == RMOD_ABRT) | ||
| 678 | { | ||
| 679 | fprintf(stderr, "oops: callmdl returned RMOD_ABRT\n"); | ||
| 680 | return(-1); | ||
| 681 | } | ||
| 682 | #endif | ||
| 683 | |||
| 684 | opt->bsent_count += | ||
| 685 | send_ipv4 (opt->sox, opt->packet + ETH_SIZE, opt->pkg_len); | ||
| 686 | opt->iptotscan_count++; | ||
| 687 | opt->ipscan_count++; /* linear ipscan-offset */ | ||
| 688 | |||
| 689 | if (opt->ipscan_count % opt->limit == 0) /* every second */ | ||
| 690 | { | ||
| 691 | if ((c = tty_getchar ()) != -1) | ||
| 692 | print_scanstat (stderr); | ||
| 693 | if (opt->flags & OPT_ABRT) | ||
| 694 | return (-1); /* sig_abort_handler called */ | ||
| 695 | } | ||
| 696 | |||
| 697 | /* do floodprotection */ | ||
| 698 | while (opt->limit > 0) | ||
| 699 | { | ||
| 700 | /* | ||
| 701 | * forgett about the initial value of tv.tv_usec... | ||
| 702 | * This is called 'optimizing algorithms'. The usec does | ||
| 703 | * not count if you scan >>10seconds... | ||
| 704 | */ | ||
| 705 | gettimeofday (&opt->tv2, NULL); | ||
| 706 | opt->sec = (opt->tv2.tv_sec - opt->scan_start.tv_sec) | ||
| 707 | - (opt->scan_start.tv_usec - opt->tv2.tv_usec) / 1000000.0; | ||
| 708 | if ((opt->iptotscan_count / opt->sec) >= opt->limit) | ||
| 709 | usleep (10); /* should give up timeslice */ | ||
| 710 | else | ||
| 711 | break; | ||
| 712 | } | ||
| 713 | #ifdef HAVE_DLSYM | ||
| 714 | } /* modcount-loop */ | ||
| 715 | #endif | ||
| 716 | } | ||
| 717 | return (0); | ||
| 718 | } | ||
| 719 | |||
| 720 | void * | ||
| 721 | p_doit(void *arg) | ||
| 722 | { | ||
| 723 | printf("first thread here\n"); | ||
| 724 | sleep(100); | ||
| 725 | return NULL; | ||
| 726 | } | ||
| 727 | |||
| 728 | |||
| 729 | int | ||
| 730 | main (int argc, char *argv[]) | ||
| 731 | { | ||
| 732 | struct sockaddr_in saddr; | ||
| 733 | struct timeval tv; | ||
| 734 | int size; | ||
| 735 | int pstatus; /* pthread error status */ | ||
| 736 | #ifdef IP_HDRINCL | ||
| 737 | const int on = 1; | ||
| 738 | #endif | ||
| 739 | |||
| 740 | init_vars (&argv[argc]); /* before do_opt */ | ||
| 741 | |||
| 742 | do_opt (argc, argv); | ||
| 743 | tty_init (); | ||
| 744 | |||
| 745 | if (opt->flags & OPT_SETARP) | ||
| 746 | if (setarp (opt->nt.src, opt->spf_smac) != 0) | ||
| 747 | { | ||
| 748 | fprintf (stderr, "unable to set arpentry. do it manually\n"); | ||
| 749 | exit (1); | ||
| 750 | } | ||
| 751 | |||
| 752 | init_network_raw (); | ||
| 753 | prepare_libnet (&opt->lnet); /* used by arpg.c and maybe by bscan.c */ | ||
| 754 | |||
| 755 | memset (&saddr, 0, sizeof (saddr)); | ||
| 756 | |||
| 757 | if ((opt->sox = socket (AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) | ||
| 758 | { | ||
| 759 | fprintf (stderr, "error creating socket\n"); | ||
| 760 | exit (1); | ||
| 761 | } | ||
| 762 | #ifdef IP_HDRINCL | ||
| 763 | if (setsockopt (opt->sox, IPPROTO_IP, IP_HDRINCL, &on, sizeof (on)) < 0) | ||
| 764 | { | ||
| 765 | fprintf (stderr, "error setsockopt\n"); | ||
| 766 | exit (1); | ||
| 767 | } | ||
| 768 | #endif | ||
| 769 | |||
| 770 | size = 160 * 1024; /* OK if setsockopt fails */ | ||
| 771 | setsockopt (opt->sox, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)); | ||
| 772 | |||
| 773 | opt->flags |= OPT_W8SEMA; | ||
| 774 | opt->bscantid = pthread_self(); | ||
| 775 | pstatus = pthread_create(&opt->snarftid, NULL, &do_snarf, opt->lnet.device); | ||
| 776 | if (pstatus != 0) | ||
| 777 | err_abort(pstatus, "pthread_create"); | ||
| 778 | |||
| 779 | while (opt->flags & OPT_W8SEMA) | ||
| 780 | usleep(50); | ||
| 781 | |||
| 782 | print_opt (); | ||
| 783 | |||
| 784 | if (opt->scan_start.tv_sec == 0) | ||
| 785 | gettimeofday (&opt->scan_start, NULL); | ||
| 786 | |||
| 787 | while ((*opt->argvlist != NULL) || (opt->flags & OPT_HOSTFILE)) | ||
| 788 | { | ||
| 789 | if (!(opt->flags & OPT_REST)) | ||
| 790 | reset_vars (); /* reset all counting variables */ | ||
| 791 | |||
| 792 | if (!(opt->flags & OPT_HOSTFILE)) | ||
| 793 | { | ||
| 794 | make_iprange (&opt->network, &opt->netmask, &opt->start_ip, | ||
| 795 | &opt->end_ip, *opt->argvlist++); | ||
| 796 | } | ||
| 797 | else | ||
| 798 | { | ||
| 799 | opt->getnextip = (void *) readnextip; | ||
| 800 | if (opt->flags & OPT_REST) | ||
| 801 | { | ||
| 802 | int c = 0; | ||
| 803 | |||
| 804 | fprintf (stderr, "restore: skipping %lu in '%s'\n", | ||
| 805 | opt->ipscan_count, opt->hostfile); | ||
| 806 | while (c++ < opt->ipscan_count) | ||
| 807 | if ((*opt->getnextip) () == -1) | ||
| 808 | break; | ||
| 809 | } | ||
| 810 | } | ||
| 811 | |||
| 812 | opt->flags &= ~OPT_REST; /* 2nd.. init not by restorefile */ | ||
| 813 | |||
| 814 | if ((opt->getnextip == NULL) || (opt->nt.src == 0) | ||
| 815 | || (opt->nt.src == -1)) | ||
| 816 | usage (0, "no ip/range given or nonparseable range, skip"); | ||
| 817 | if (opt->flags & OPT_OUTONLY) | ||
| 818 | { | ||
| 819 | do_outonly (); | ||
| 820 | continue; | ||
| 821 | } | ||
| 822 | |||
| 823 | if (process_iprange () == -1) | ||
| 824 | { | ||
| 825 | print_scanstat (stderr); | ||
| 826 | break; /* abort scan ! */ | ||
| 827 | } | ||
| 828 | |||
| 829 | if (opt->flags & OPT_HOSTFILE) | ||
| 830 | break; /* process only ONE hostfile */ | ||
| 831 | |||
| 832 | if (*opt->argvlist != NULL) | ||
| 833 | print_scanstat (stderr); | ||
| 834 | } | ||
| 835 | |||
| 836 | gettimeofday (&tv, NULL); | ||
| 837 | time_diff (&opt->scan_start, &tv); | ||
| 838 | opt->sec = tv.tv_sec + tv.tv_usec / 1000000.0; | ||
| 839 | fprintf (stderr, "scanned %lu ip's in %.3f seconds\n", opt->iptotscan_count, | ||
| 840 | opt->sec); | ||
| 841 | if (opt->delay > 0) | ||
| 842 | { | ||
| 843 | fprintf (stderr, "waiting %d sec for outstanding packets...\n", | ||
| 844 | opt->delay); | ||
| 845 | signal (SIGINT, die); /* if waiting exit immediatly on INTR */ | ||
| 846 | sleep (opt->delay); | ||
| 847 | } | ||
| 848 | |||
| 849 | die (0); | ||
| 850 | return (0); | ||
| 851 | } | ||
