tree_cell * nasl_this_host(lex_ctxt * lexic) { struct arglist * script_infos = lexic->script_infos; tree_cell * retc; struct in_addr addr; char hostname[255]; char * ret; struct in_addr * ia = plug_get_host_ip(script_infos); struct in_addr src; retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; addr = socket_get_next_source_addr(arg_get_value(script_infos, "globals")); if ( addr.s_addr != INADDR_ANY ) { retc->x.str_val = estrdup(inet_ntoa(addr)); retc->size = strlen(retc->x.str_val); return retc; } src.s_addr = 0; if(ia) { if(islocalhost(ia)) src.s_addr = ia->s_addr; else (void)routethrough(ia, &src); if(src.s_addr) { char * ret; ret = estrdup(inet_ntoa(src)); retc->x.str_val = ret; retc->size = strlen(ret); return retc; } hostname[sizeof(hostname) - 1] = '\0'; gethostname(hostname, sizeof(hostname) - 1); addr = nn_resolve(hostname); ret = estrdup(inet_ntoa(addr)); retc->x.str_val = ret; retc->size = strlen(ret); } return retc; }
/* REMEMBER TO CALL hoststruct_free() on the hoststruct when you are done with it!!! */ struct hoststruct *nexthost(struct hostgroup_state *hs, struct scan_lists *ports, int *pingtype) { int hidx; char *device; if (hs->next_batch_no < hs->current_batch_sz) { /* Woop! This is easy -- we just pass back the next host struct */ return &hs->hostbatch[hs->next_batch_no++]; } /* Doh, we need to refresh our array */ bzero(hs->hostbatch, hs->max_batch_sz * sizeof(struct hoststruct)); hs->current_batch_sz = hs->next_batch_no = 0; do { /* Grab anything we have in our current_expression */ while (hs->current_batch_sz < hs->max_batch_sz && target_struct_get(&hs->current_expression, &(hs->hostbatch[hs->current_batch_sz].host)) != -1) { hidx = hs->current_batch_sz; /* Lets figure out what device this IP uses ... */ if (o.source) { memcpy((char *) &hs->hostbatch[hidx].source_ip, (char *) o.source, sizeof(struct in_addr)); strcpy(hs->hostbatch[hidx].device, o.device); } else { /* We figure out the source IP/device IFF 1) We are r00t AND 2) We are doing tcp pingscan OR 3) We are doing a raw-mode portscan or osscan */ if (o.isr00t && ((*pingtype & PINGTYPE_TCP) || o.synscan || o.finscan || o.xmasscan || o.nullscan || o.ipprotscan || o.maimonscan || o.idlescan || o.ackscan || o.udpscan || o.osscan || o.windowscan)) { device = routethrough(&(hs->hostbatch[hidx].host), &(hs->hostbatch[hidx].source_ip)); if (!device) { if (*pingtype == PINGTYPE_NONE) { fatal("Could not determine what interface to route packets through, run again with -e <device>"); } else { error ("WARNING: Could not determine what interface to route packets through to %s, changing ping scantype to ICMP ping only", inet_ntoa(hs->hostbatch[hidx].host)); *pingtype = PINGTYPE_ICMP_PING; } } else { strcpy(hs->hostbatch[hidx].device, device); } } } /* In some cases, we can only allow hosts that use the same device in a group. */ if (o.isr00t && hidx > 0 && *hs->hostbatch[hidx].device && hs->hostbatch[hidx].source_ip.s_addr != hs->hostbatch[0].source_ip.s_addr) { /* Cancel everything! This guy must go in the next group and we are outtof here */ target_struct_return(&(hs->current_expression)); goto batchfull; } hs->current_batch_sz++; } if (hs->current_batch_sz < hs->max_batch_sz && hs->next_expression < hs->num_expressions) { /* We are going to have to plop in another expression. */ while (!parse_targets(&(hs->current_expression), hs->target_expressions[hs->next_expression++])) { if (hs->next_expression >= hs->num_expressions) break; } } else break; } while (1); batchfull: if (hs->current_batch_sz == 0) return NULL; /* OK, now we have our complete batch of entries. The next step is to randomize them (if requested) */ if (hs->randomize) { hoststructfry(hs->hostbatch, hs->current_batch_sz); } return &hs->hostbatch[hs->next_batch_no++]; }