static void parse_port_list(struct RangeList *ports, const char *string) { char *p = (char*)string; while (*p) { unsigned port; unsigned end; while (*p && isspace(*p & 0xFF)) p++; if (*p == 0) break; port = strtoul(p, &p, 0); end = port; if (*p == '-') { p++; end = strtoul(p, &p, 0); } if (*p == ',') p++; if (port > 0xFFFF || end > 0xFFFF || end < port) { fprintf(stderr, "CONF: bad ports: %u-%u\n", port, end); break; } else { rangelist_add_range(ports, port, end); } } }
void rangelist_remove_range(struct RangeList *task, unsigned begin, unsigned end) { unsigned i; struct Range x; x.begin = begin; x.end = end; /* See if the range overlaps any exist range already in the * list */ for (i = 0; i < task->count; i++) { if (!range_is_overlap(task->list[i], x)) continue; /* If the removal-range wholly covers the range, delete * it completely */ if (begin <= task->list[i].begin && end >= task->list[i].end) { todo_remove_at(task, i); i--; continue; } /* If the removal-range bisects the target-rage, truncate * the lower end and add a new high-end */ if (begin > task->list[i].begin && end < task->list[i].end) { struct Range newrange; newrange.begin = end+1; newrange.end = task->list[i].end; task->list[i].end = begin-1; rangelist_add_range(task, newrange.begin, newrange.end); i--; continue; } /* If overlap on the lower side */ if (end >= task->list[i].begin && end < task->list[i].end) { task->list[i].begin = end+1; } /* If overlap on the upper side */ if (begin > task->list[i].begin && begin <= task->list[i].end) { task->list[i].end = begin-1; } //assert(!"impossible"); } }
/*************************************************************************** * Add the IPv4 range to our list of ranges. ***************************************************************************/ void rangelist_add_range(struct RangeList *task, unsigned begin, unsigned end) { unsigned i; struct Range range; range.begin = begin; range.end = end; /* auto-expand the list if necessary */ if (task->count + 1 >= task->max) { size_t new_max = (size_t)task->max * 2 + 1; struct Range *new_list; if (new_max >= SIZE_MAX/sizeof(*new_list)) exit(1); /* integer overflow */ new_list = (struct Range *)malloc(sizeof(*new_list) * new_max); if (new_list == NULL) exit(1); /* out of memory */ memcpy(new_list, task->list, task->count * sizeof(*new_list)); if (task->list) free(task->list); task->list = new_list; task->max = (unsigned)new_max; } /* See if the range overlaps any exist range already in the * list */ for (i = 0; i < task->count; i++) { if (range_is_overlap(task->list[i], range)) { range_combine(&range, task->list[i]); todo_remove_at(task, i); rangelist_add_range(task, range.begin, range.end); return; } } /* Find a spot to insert in sorted order */ for (i = 0; i < task->count; i++) { if (range.begin < task->list[i].begin) { memmove(task->list+i+1, task->list+i, (task->count - i) * sizeof(task->list[0])); break; } } /* Add to end of list */ task->list[i].begin = begin; task->list[i].end = end; task->count++; }
static void rangelist_add_range2(struct RangeList *task, struct Range range) { rangelist_add_range(task, range.begin, range.end); }
/*************************************************************************** * Add the IPv4 range to our list of ranges. ***************************************************************************/ void rangelist_add_range(struct RangeList *task, unsigned begin, unsigned end) { int first, middle, last; struct Range range; range.begin = begin; range.end = end; /* auto-expand the list if necessary */ if (task->count + 1 >= task->max) { size_t new_max = (size_t)task->max * 2 + 1; struct Range *new_list; if (new_max >= SIZE_MAX/sizeof(*new_list)) exit(1); /* integer overflow */ new_list = (struct Range *)malloc(sizeof(*new_list) * new_max); if (new_list == NULL) exit(1); /* out of memory */ memcpy(new_list, task->list, task->count * sizeof(*new_list)); if (task->list) free(task->list); task->list = new_list; task->max = (unsigned)new_max; } if (!task->count) { task->list[0].begin = begin; task->list[0].end = end; task->count++; return; } /* Binary search to find where the current IP range belongs by comparing range beginnings */ first = 0; last = task->count - 1; middle = (first + last) / 2; while (first <= last) { if (task->list[middle].begin < range.begin) first = middle + 1; else if (task->list[middle].begin == range.begin) break; else last = middle - 1; middle = (first + last) / 2; } /* `middle` now points to the IP range numerically smaller than or equal to it. Try to merge it * with the numerically smaller, and then greater ranges. */ if (range_is_overlap(task->list[middle], range)) { range_combine(&range, task->list[middle]); todo_remove_at(task, middle); rangelist_add_range(task, range.begin, range.end); return; } if (task->count > (middle+1) && range_is_overlap(task->list[middle+1], range)) { range_combine(&range, task->list[middle+1]); todo_remove_at(task, middle+1); rangelist_add_range(task, range.begin, range.end); return; } /* Make space for the current range respecting sorted order by placing it in entry `middle+1` */ memmove(task->list+middle+2, task->list+middle+1, (task->count - middle - 1) * sizeof(task->list[0])); /* Add to the list */ task->list[middle+1].begin = begin; task->list[middle+1].end = end; task->count++; }
void main_listscan(struct Masscan *masscan) { uint64_t count_ips; uint64_t count_ports; uint64_t i; uint64_t range; uint64_t start; uint64_t end; struct BlackRock blackrock; unsigned increment = masscan->shard.of; uint64_t seed = masscan->seed; count_ports = rangelist_count(&masscan->ports); if (count_ports == 0) rangelist_add_range(&masscan->ports, 80, 80); count_ports = rangelist_count(&masscan->ports); count_ips = rangelist_count(&masscan->targets); if (count_ips == 0) { LOG(0, "FAIL: target IP address list empty\n"); LOG(0, " [hint] try something like \"--range 10.0.0.0/8\"\n"); LOG(0, " [hint] try something like \"--range 192.168.0.100-192.168.0.200\"\n"); return; } range = count_ips * count_ports; infinite: blackrock_init(&blackrock, range, seed, masscan->blackrock_rounds); start = masscan->resume.index + (masscan->shard.one-1); end = range; if (masscan->resume.count && end > start + masscan->resume.count) end = start + masscan->resume.count; end += (uint64_t)(masscan->retries * masscan->max_rate); //printf("start=%llu, end=%llu\n", start, end); for (i=start; i<end; ) { uint64_t xXx; unsigned ip; unsigned port; xXx = blackrock_shuffle(&blackrock, i); ip = rangelist_pick(&masscan->targets, xXx % count_ips); port = rangelist_pick(&masscan->ports, xXx / count_ips); if (count_ports == 1) { if (masscan->is_test_csv) { /* [KLUDGE] [TEST] * For testing randomness output, prints last two bytes of * IP address as CSV format for import into spreadsheet */ printf("%u,%u\n", (ip>>8)&0xFF, (ip>>0)&0xFF ); } else { printf("%u.%u.%u.%u\n", (ip>>24)&0xFF, (ip>>16)&0xFF, (ip>>8)&0xFF, (ip>>0)&0xFF ); } } else