mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Revert r24116 and r24117; the addrset functions need to go in a C
library instead.
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
# Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o [Nmap] Updated --exclude and --excludefile to now support IPV6 addresses with
|
||||
netmasks. [Colin]
|
||||
|
||||
o [NSE] Added a MySQL audit script and a rulebase that supports auditing a
|
||||
subset of the MySQL CIS 1.0.2 Benchmark. [Patrik]
|
||||
|
||||
@@ -14,7 +11,7 @@ o [NSE] Added minimal Service Location Protocol (SLP) library and the script
|
||||
broadcast-novell-locate that detects servers running eDirectory. [Patrik]
|
||||
|
||||
o [ncat] ncat now listens on localhost and ::1 when you do ncat -l. If you
|
||||
specify an address or use -4,-6 it works as before. [Colin]
|
||||
specify an address or use -4,-6 it works as before.
|
||||
|
||||
o [NSE] Added the Simple Mail Transfer Protocol (SMTP) library. [Djalal]
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ netutil_build: libnetutil/Makefile
|
||||
@echo Compiling libnetutil;
|
||||
cd libnetutil && $(MAKE)
|
||||
|
||||
ncat_build: $(NCATDIR)/Makefile nbase_build nsock_build netutil_build $(NCATDIR)/ncat.h
|
||||
ncat_build: $(NCATDIR)/Makefile nbase_build nsock_build $(NCATDIR)/ncat.h
|
||||
cd $(NCATDIR) && $(MAKE)
|
||||
|
||||
lua_build: $(LIBLUADIR)/Makefile
|
||||
|
||||
@@ -14,8 +14,8 @@ LIBPCAPDIR = @libpcapdir@
|
||||
|
||||
TARGET = libnetutil.a
|
||||
|
||||
SRCS = $(srcdir)/netutil.cc $(srcdir)/addrset.cc
|
||||
OBJS = netutil.o addrset.o
|
||||
SRCS = $(srcdir)/netutil.cc
|
||||
OBJS = netutil.o
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
|
||||
@@ -1,594 +0,0 @@
|
||||
/***************************************************************************
|
||||
* addrset.c -- Address set (addrset) management. *
|
||||
***********************IMPORTANT NMAP LICENSE TERMS************************
|
||||
* *
|
||||
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
|
||||
* also a registered trademark of Insecure.Com LLC. This program is free *
|
||||
* software; you may redistribute and/or modify it under the terms of the *
|
||||
* GNU General Public License as published by the Free Software *
|
||||
* Foundation; Version 2 with the clarifications and exceptions described *
|
||||
* below. This guarantees your right to use, modify, and redistribute *
|
||||
* this software under certain conditions. If you wish to embed Nmap *
|
||||
* technology into proprietary software, we sell alternative licenses *
|
||||
* (contact sales@insecure.com). Dozens of software vendors already *
|
||||
* license Nmap technology such as host discovery, port scanning, OS *
|
||||
* detection, and version detection. *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derived works", yet *
|
||||
* it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we consider an application to constitute a *
|
||||
* "derivative work" for the purpose of this license if it does any of the *
|
||||
* following: *
|
||||
* o Integrates source code from Nmap *
|
||||
* o Reads or includes Nmap copyrighted data files, such as *
|
||||
* nmap-os-db or nmap-service-probes. *
|
||||
* o Executes Nmap and parses the results (as opposed to typical shell or *
|
||||
* execution-menu apps, which simply display raw Nmap output and so are *
|
||||
* not derivative works.) *
|
||||
* o Integrates/includes/aggregates Nmap into a proprietary executable *
|
||||
* installer, such as those produced by InstallShield. *
|
||||
* o Links to a library or executes a program that does any of the above *
|
||||
* *
|
||||
* The term "Nmap" should be taken to also include any portions or derived *
|
||||
* works of Nmap. This list is not exclusive, but is meant to clarify our *
|
||||
* interpretation of derived works with some common examples. Our *
|
||||
* interpretation applies only to Nmap--we don't speak for other people's *
|
||||
* GPL works. *
|
||||
* *
|
||||
* If you have any questions about the GPL licensing restrictions on using *
|
||||
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
|
||||
* we also offer alternative license to integrate Nmap into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates as well as helping to *
|
||||
* fund the continued development of Nmap technology. Please email *
|
||||
* sales@insecure.com for further information. *
|
||||
* *
|
||||
* As a special exception to the GPL terms, Insecure.Com LLC grants *
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. You must obey the GNU GPL in all *
|
||||
* respects for all of the code used other than OpenSSL. If you modify *
|
||||
* this file, you may extend this exception to your version of the file, *
|
||||
* but you are not obligated to do so. *
|
||||
* *
|
||||
* If you received these files with a written license agreement or *
|
||||
* contract stating terms other than the terms above, then that *
|
||||
* alternative license agreement takes precedence over these comments. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port Nmap to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to nmap-dev@insecure.org for possible incorporation into the main *
|
||||
* distribution. By sending these changes to Fyodor or one of the *
|
||||
* Insecure.Org development mailing lists, it is assumed that you are *
|
||||
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
|
||||
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
|
||||
* will always be available Open Source, but this is important because the *
|
||||
* inability to relicense code has caused devastating problems for other *
|
||||
* Free Software projects (such as KDE and NASM). We also occasionally *
|
||||
* relicense the code to third parties as discussed above. If you wish to *
|
||||
* specify special license conditions of your contributions, just say so *
|
||||
* when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License v2.0 for more details at *
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
|
||||
* included with Nmap. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
/* The code in this file has tests in the file ncat/tests/test-addrset.sh. Run that
|
||||
program after making any big changes. Also, please add tests for any new
|
||||
features. */
|
||||
|
||||
#include "nbase.h"
|
||||
#include "netutil.h"
|
||||
|
||||
#include "addrset.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
void addrset_init(struct addrset *set)
|
||||
{
|
||||
set->head = NULL;
|
||||
}
|
||||
|
||||
void addrset_free(struct addrset *set)
|
||||
{
|
||||
struct addrset_elem *elem, *next;
|
||||
|
||||
for (elem = set->head; elem != NULL; elem = next) {
|
||||
next = elem->next;
|
||||
free(elem);
|
||||
}
|
||||
}
|
||||
|
||||
/* A debugging function to print out the contents of an addrset_elem. For IPv4
|
||||
this is the four bit vectors. For IPv6 it is the address and netmask. */
|
||||
void addrset_elem_print(const struct addrset_elem *elem)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (elem->type == ADDRSET_TYPE_IPV4_BITVECTOR) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < sizeof(octet_bitvector) / sizeof(bitvector_t); j++)
|
||||
printf("%08lX ", elem->u.ipv4.bits[i][j]);
|
||||
printf("\n");
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
} else if (elem->type == ADDRSET_TYPE_IPV6_NETMASK) {
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
if (i > 0)
|
||||
printf(":");
|
||||
printf("%02X", elem->u.ipv6.addr.s6_addr[i]);
|
||||
printf("%02X", elem->u.ipv6.addr.s6_addr[i + 1]);
|
||||
}
|
||||
printf(" ");
|
||||
for (i = 0; i < 16; i += 2) {
|
||||
if (i > 0)
|
||||
printf(":");
|
||||
printf("%02X", elem->u.ipv6.mask.s6_addr[i]);
|
||||
printf("%02X", elem->u.ipv6.mask.s6_addr[i + 1]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
printf("---\n");
|
||||
}
|
||||
|
||||
/* This is a wrapper around getaddrinfo that automatically handles hints for
|
||||
IPv4/IPv6, TCP/UDP, and whether name resolution is allowed. */
|
||||
static int resolve_name(const char *name, struct addrinfo **result, int af, int use_dns)
|
||||
{
|
||||
struct addrinfo hints = { 0 };
|
||||
int rc;
|
||||
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
/* First do a non-DNS lookup for any address family (just checks for a valid
|
||||
numeric address). We recognize numeric addresses no matter the setting of
|
||||
af. This is also the last step if use_dns is false. */
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
*result = NULL;
|
||||
rc = getaddrinfo(name, NULL, &hints, result);
|
||||
if (rc == 0 || !use_dns)
|
||||
return rc;
|
||||
|
||||
/* Do a DNS lookup now. When we look up a name we only want addresses
|
||||
corresponding to the value of af. */
|
||||
hints.ai_flags &= ~AI_NUMERICHOST;
|
||||
hints.ai_family = af;
|
||||
*result = NULL;
|
||||
rc = getaddrinfo(name, NULL, &hints, result);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* This is an address family-agnostic version of inet_ntop. */
|
||||
static char *address_to_string(const struct sockaddr *sa, size_t sa_len,
|
||||
char *buf, size_t len)
|
||||
{
|
||||
getnameinfo(sa, sa_len, buf, len, NULL, 0, NI_NUMERICHOST);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Break an IPv4 address into an array of octets. */
|
||||
static void in_addr_to_octets(const struct in_addr *ia, uint8_t octets[4])
|
||||
{
|
||||
octets[0] = (ia->s_addr & 0xFF);
|
||||
octets[1] = (ia->s_addr & (0xFF << 8)) >> 8;
|
||||
octets[2] = (ia->s_addr & (0xFF << 16)) >> 16;
|
||||
octets[3] = (ia->s_addr & (0xFF << 24)) >> 24;
|
||||
}
|
||||
|
||||
#define BITVECTOR_BITS (sizeof(bitvector_t) * CHAR_BIT)
|
||||
#define BIT_SET(v, n) ((v)[(n) / BITVECTOR_BITS] |= 1UL << ((n) % BITVECTOR_BITS))
|
||||
#define BIT_IS_SET(v, n) (((v)[(n) / BITVECTOR_BITS] & 1UL << ((n) % BITVECTOR_BITS)) != 0)
|
||||
|
||||
static int parse_ipv4_ranges(struct addrset_elem *elem, const char *spec);
|
||||
static void apply_ipv4_netmask_bits(struct addrset_elem *elem, int bits);
|
||||
#ifdef HAVE_IPV6
|
||||
static void make_ipv6_netmask(struct in6_addr *mask, int bits);
|
||||
#endif
|
||||
|
||||
/* Add a host specification into the address set. Returns 1 on success, 0 on
|
||||
error. */
|
||||
|
||||
int addrset_add_spec(struct addrset *set, const char *spec, int af, int dns)
|
||||
{
|
||||
char *local_spec;
|
||||
char *netmask_s;
|
||||
char *tail;
|
||||
long netmask_bits;
|
||||
struct addrinfo *addrs, *addr;
|
||||
struct addrset_elem *elem;
|
||||
int rc;
|
||||
|
||||
/* Make a copy of the spec to mess with. */
|
||||
local_spec = strdup(spec);
|
||||
if (local_spec == NULL)
|
||||
return 0;
|
||||
|
||||
/* Read the CIDR netmask bits, if present. */
|
||||
netmask_s = strchr(local_spec, '/');
|
||||
if (netmask_s == NULL) {
|
||||
/* A negative value means unspecified; default depends on the address
|
||||
family. */
|
||||
netmask_bits = -1;
|
||||
} else {
|
||||
*netmask_s = '\0';
|
||||
netmask_s++;
|
||||
errno = 0;
|
||||
netmask_bits = parse_long(netmask_s, &tail);
|
||||
if (errno != 0 || *tail != '\0' || tail == netmask_s) {
|
||||
netutil_error("Error parsing netmask in \"%s\".\n", spec);
|
||||
free(local_spec);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
elem = (struct addrset_elem *) safe_malloc(sizeof(*elem));
|
||||
memset(elem->u.ipv4.bits, 0, sizeof(elem->u.ipv4.bits));
|
||||
|
||||
/* Check if this is an IPv4 address, with optional ranges and wildcards. */
|
||||
if (parse_ipv4_ranges(elem, local_spec)) {
|
||||
if (netmask_bits > 32) {
|
||||
netutil_error("Illegal netmask in \"%s\". Must be between 0 and 32.\n", spec);
|
||||
free(local_spec);
|
||||
free(elem);
|
||||
return 0;
|
||||
}
|
||||
apply_ipv4_netmask_bits(elem, netmask_bits);
|
||||
|
||||
elem->type = ADDRSET_TYPE_IPV4_BITVECTOR;
|
||||
elem->next = set->head;
|
||||
set->head = elem;
|
||||
free(local_spec);
|
||||
return 1;
|
||||
} else {
|
||||
free(elem);
|
||||
}
|
||||
|
||||
/* When all else fails, resolve the name. */
|
||||
rc = resolve_name(local_spec, &addrs, af, dns);
|
||||
if (rc != 0) {
|
||||
netutil_error("Error resolving name \"%s\": %s\n", local_spec, gai_strerror(rc));
|
||||
free(local_spec);
|
||||
return 0;
|
||||
}
|
||||
if (addrs == NULL)
|
||||
netutil_error("Warning: no addresses found for %s.\n", local_spec);
|
||||
free(local_spec);
|
||||
|
||||
/* Walk the list of addresses and add them all to the set with netmasks. */
|
||||
for (addr = addrs; addr != NULL; addr = addr->ai_next) {
|
||||
char addr_string[128];
|
||||
|
||||
elem = (struct addrset_elem *) safe_malloc(sizeof(*elem));
|
||||
memset(elem->u.ipv4.bits, 0, sizeof(elem->u.ipv4.bits));
|
||||
|
||||
address_to_string(addr->ai_addr, addr->ai_addrlen, addr_string, sizeof(addr_string));
|
||||
|
||||
/* Note: it is possible that in this loop we are dealing with addresses
|
||||
of more than one family (e.g., IPv4 and IPv6). But we have at most
|
||||
one netmask value for all of them. Whatever netmask we have is
|
||||
applied blindly to whatever addresses there are, which may not be
|
||||
what you want if a /24 is applied to IPv6 and will cause an error if
|
||||
a /120 is applied to IPv4. */
|
||||
if (addr->ai_family == AF_INET) {
|
||||
const struct sockaddr_in *sin = (struct sockaddr_in *) addr->ai_addr;
|
||||
uint8_t octets[4];
|
||||
|
||||
elem->type = ADDRSET_TYPE_IPV4_BITVECTOR;
|
||||
|
||||
in_addr_to_octets(&sin->sin_addr, octets);
|
||||
BIT_SET(elem->u.ipv4.bits[0], octets[0]);
|
||||
BIT_SET(elem->u.ipv4.bits[1], octets[1]);
|
||||
BIT_SET(elem->u.ipv4.bits[2], octets[2]);
|
||||
BIT_SET(elem->u.ipv4.bits[3], octets[3]);
|
||||
|
||||
if (netmask_bits > 32) {
|
||||
netutil_error("Illegal netmask in \"%s\". Must be between 0 and 32.\n", spec);
|
||||
free(elem);
|
||||
return 0;
|
||||
}
|
||||
apply_ipv4_netmask_bits(elem, netmask_bits);
|
||||
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
} else if (addr->ai_family == AF_INET6) {
|
||||
const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr->ai_addr;
|
||||
|
||||
elem->type = ADDRSET_TYPE_IPV6_NETMASK;
|
||||
|
||||
elem->u.ipv6.addr = sin6->sin6_addr;
|
||||
|
||||
if (netmask_bits > 128) {
|
||||
netutil_error("Illegal netmask in \"%s\". Must be between 0 and 128.\n", spec);
|
||||
free(elem);
|
||||
return 0;
|
||||
}
|
||||
make_ipv6_netmask(&elem->u.ipv6.mask, netmask_bits);
|
||||
#endif
|
||||
} else {
|
||||
free(elem);
|
||||
continue;
|
||||
}
|
||||
|
||||
elem->next = set->head;
|
||||
set->head = elem;
|
||||
}
|
||||
|
||||
if (addrs != NULL)
|
||||
freeaddrinfo(addrs);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Add whitespace-separated host specifications from fd into the address set.
|
||||
Returns 1 on success, 0 on error. */
|
||||
int addrset_add_file(struct addrset *set, FILE *fd, int af, int dns)
|
||||
{
|
||||
char buf[1024];
|
||||
int c, i;
|
||||
|
||||
for (;;) {
|
||||
/* Skip whitespace. */
|
||||
while ((c = getc(fd)) != EOF) {
|
||||
if (!isspace(c))
|
||||
break;
|
||||
}
|
||||
if (c == EOF)
|
||||
break;
|
||||
ungetc(c, fd);
|
||||
|
||||
i = 0;
|
||||
while ((c = getc(fd)) != EOF) {
|
||||
if (isspace(c))
|
||||
break;
|
||||
if (i + 1 > sizeof(buf) - 1) {
|
||||
/* Truncate the specification to give a little context. */
|
||||
buf[11] = '\0';
|
||||
netutil_error("Host specification starting with \"%s\" is too long.\n", buf);
|
||||
return 0;
|
||||
}
|
||||
buf[i++] = c;
|
||||
}
|
||||
buf[i] = '\0';
|
||||
|
||||
if (!addrset_add_spec(set, buf, af, dns))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Parse an IPv4 address with optional ranges and wildcards into bit vectors.
|
||||
Each octet must match the regular expression '(\*|#?(-#?)?(,#?(-#?)?)*)',
|
||||
where '#' stands for an integer between 0 and 255. Return 1 on success, 0 on
|
||||
error. */
|
||||
static int parse_ipv4_ranges(struct addrset_elem *elem, const char *spec)
|
||||
{
|
||||
const char *p;
|
||||
int octet_index, i;
|
||||
|
||||
p = spec;
|
||||
octet_index = 0;
|
||||
while (*p != '\0' && octet_index < 4) {
|
||||
if (*p == '*') {
|
||||
for (i = 0; i < 256; i++)
|
||||
BIT_SET(elem->u.ipv4.bits[octet_index], i);
|
||||
p++;
|
||||
} else {
|
||||
for (;;) {
|
||||
long start, end;
|
||||
char *tail;
|
||||
|
||||
errno = 0;
|
||||
start = parse_long(p, &tail);
|
||||
/* Is this a range open on the left? */
|
||||
if (tail == p) {
|
||||
if (*p == '-')
|
||||
start = 0;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
if (errno != 0 || start < 0 || start > 255)
|
||||
return 0;
|
||||
p = tail;
|
||||
|
||||
/* Look for a range. */
|
||||
if (*p == '-') {
|
||||
p++;
|
||||
errno = 0;
|
||||
end = parse_long(p, &tail);
|
||||
/* Is this range open on the right? */
|
||||
if (tail == p)
|
||||
end = 255;
|
||||
if (errno != 0 || end < 0 || end > 255 || end < start)
|
||||
return 0;
|
||||
p = tail;
|
||||
} else {
|
||||
end = start;
|
||||
}
|
||||
|
||||
/* Fill in the range in the bit vector. */
|
||||
for (i = start; i <= end; i++)
|
||||
BIT_SET(elem->u.ipv4.bits[octet_index], i);
|
||||
|
||||
if (*p != ',')
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
octet_index++;
|
||||
if (octet_index < 4) {
|
||||
if (*p != '.')
|
||||
return 0;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
if (*p != '\0' || octet_index < 4)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Expand a single-octet bit vector to include any additional addresses that
|
||||
result when mask is applied. */
|
||||
static void apply_ipv4_netmask_octet(octet_bitvector bits, uint8_t mask)
|
||||
{
|
||||
int i, j;
|
||||
uint32_t chunk_size;
|
||||
|
||||
/* Process the bit vector in chunks, first of size 1, then of size 2, up to
|
||||
size 128. Check the next bit of the mask. If it is 1, do nothing.
|
||||
Otherwise, pair up the chunks (first with the second, third with the
|
||||
fourth, etc.). For each pair of chunks, set a bit in one chunk if it is
|
||||
set in the other. chunk_size also serves as an index into the mask. */
|
||||
for (chunk_size = 1; chunk_size < 256; chunk_size <<= 1) {
|
||||
if ((mask & chunk_size) != 0)
|
||||
continue;
|
||||
for (i = 0; i < 256; i += chunk_size * 2) {
|
||||
for (j = 0; j < chunk_size; j++) {
|
||||
if (BIT_IS_SET(bits, i + j))
|
||||
BIT_SET(bits, i + j + chunk_size);
|
||||
else if (BIT_IS_SET(bits, i + j + chunk_size))
|
||||
BIT_SET(bits, i + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Expand an addrset_elem's IPv4 bit vectors to include any additional addresses
|
||||
that result when the given netmask is applied. The mask is in network byte
|
||||
order. */
|
||||
static void apply_ipv4_netmask(struct addrset_elem *elem, uint32_t mask)
|
||||
{
|
||||
mask = ntohl(mask);
|
||||
/* Apply the mask one octet at a time. It's done this way because ranges
|
||||
span exactly one octet. */
|
||||
apply_ipv4_netmask_octet(elem->u.ipv4.bits[0], (mask & 0xFF000000) >> 24);
|
||||
apply_ipv4_netmask_octet(elem->u.ipv4.bits[1], (mask & 0x00FF0000) >> 16);
|
||||
apply_ipv4_netmask_octet(elem->u.ipv4.bits[2], (mask & 0x0000FF00) >> 8);
|
||||
apply_ipv4_netmask_octet(elem->u.ipv4.bits[3], (mask & 0x000000FF));
|
||||
}
|
||||
|
||||
/* Expand an addrset_elem's IPv4 bit vectors to include any additional addresses
|
||||
that result from the application of a CIDR-style netmask with the given
|
||||
number of bits. If bits is negative it is taken to be 32. */
|
||||
static void apply_ipv4_netmask_bits(struct addrset_elem *elem, int bits)
|
||||
{
|
||||
uint32_t mask;
|
||||
|
||||
if (bits > 32)
|
||||
return;
|
||||
if (bits < 0)
|
||||
bits = 32;
|
||||
|
||||
if (bits == 0)
|
||||
mask = htonl(0x00000000);
|
||||
else
|
||||
mask = htonl(0xFFFFFFFF << (32 - bits));
|
||||
apply_ipv4_netmask(elem, mask);
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
/* Fill in an in6_addr with a CIDR-style netmask with the given number of bits.
|
||||
If bits is negative it is taken to be 128. The netmask is written in network
|
||||
byte order. */
|
||||
static void make_ipv6_netmask(struct in6_addr *mask, int bits)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(mask, 0, sizeof(*mask));
|
||||
|
||||
if (bits > 128)
|
||||
return;
|
||||
if (bits < 0)
|
||||
bits = 128;
|
||||
|
||||
if (bits == 0)
|
||||
return;
|
||||
|
||||
i = 0;
|
||||
/* 0 < bits <= 128, so this loop goes at most 15 times. */
|
||||
for ( ; bits > 8; bits -= 8)
|
||||
mask->s6_addr[i++] = 0xFF;
|
||||
mask->s6_addr[i] = 0xFF << (8 - bits);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int match_ipv4_bits(const octet_bitvector bits[4], const struct sockaddr *sa)
|
||||
{
|
||||
uint8_t octets[4];
|
||||
|
||||
if (sa->sa_family != AF_INET)
|
||||
return 0;
|
||||
|
||||
in_addr_to_octets(&((const struct sockaddr_in *) sa)->sin_addr, octets);
|
||||
|
||||
return BIT_IS_SET(bits[0], octets[0])
|
||||
&& BIT_IS_SET(bits[1], octets[1])
|
||||
&& BIT_IS_SET(bits[2], octets[2])
|
||||
&& BIT_IS_SET(bits[3], octets[3]);
|
||||
}
|
||||
|
||||
#ifdef HAVE_IPV6
|
||||
static int match_ipv6_netmask(const struct in6_addr *addr,
|
||||
const struct in6_addr *mask, const struct sockaddr *sa)
|
||||
{
|
||||
const uint8_t *a = addr->s6_addr;
|
||||
const uint8_t *m = mask->s6_addr;
|
||||
const uint8_t *b = ((const struct sockaddr_in6 *) sa)->sin6_addr.s6_addr;
|
||||
int i;
|
||||
|
||||
if (sa->sa_family != AF_INET6)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if ((a[i] & m[i]) != (b[i] & m[i]))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int addrset_elem_match(const struct addrset_elem *elem, const struct sockaddr *sa)
|
||||
{
|
||||
switch (elem->type) {
|
||||
case ADDRSET_TYPE_IPV4_BITVECTOR:
|
||||
return match_ipv4_bits(elem->u.ipv4.bits, sa);
|
||||
#ifdef HAVE_IPV6
|
||||
case ADDRSET_TYPE_IPV6_NETMASK:
|
||||
return match_ipv6_netmask(&elem->u.ipv6.addr, &elem->u.ipv6.mask, sa);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int addrset_contains(const struct addrset *set, const struct sockaddr *sa)
|
||||
{
|
||||
struct addrset_elem *elem;
|
||||
|
||||
for (elem = set->head; elem != NULL; elem = elem->next) {
|
||||
if (addrset_elem_match(elem, sa))
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,162 +0,0 @@
|
||||
/***************************************************************************
|
||||
* addrset.h *
|
||||
***********************IMPORTANT NMAP LICENSE TERMS************************
|
||||
* *
|
||||
* The Nmap Security Scanner is (C) 1996-2011 Insecure.Com LLC. Nmap is *
|
||||
* also a registered trademark of Insecure.Com LLC. This program is free *
|
||||
* software; you may redistribute and/or modify it under the terms of the *
|
||||
* GNU General Public License as published by the Free Software *
|
||||
* Foundation; Version 2 with the clarifications and exceptions described *
|
||||
* below. This guarantees your right to use, modify, and redistribute *
|
||||
* this software under certain conditions. If you wish to embed Nmap *
|
||||
* technology into proprietary software, we sell alternative licenses *
|
||||
* (contact sales@insecure.com). Dozens of software vendors already *
|
||||
* license Nmap technology such as host discovery, port scanning, OS *
|
||||
* detection, and version detection. *
|
||||
* *
|
||||
* Note that the GPL places important restrictions on "derived works", yet *
|
||||
* it does not provide a detailed definition of that term. To avoid *
|
||||
* misunderstandings, we consider an application to constitute a *
|
||||
* "derivative work" for the purpose of this license if it does any of the *
|
||||
* following: *
|
||||
* o Integrates source code from Nmap *
|
||||
* o Reads or includes Nmap copyrighted data files, such as *
|
||||
* nmap-os-db or nmap-service-probes. *
|
||||
* o Executes Nmap and parses the results (as opposed to typical shell or *
|
||||
* execution-menu apps, which simply display raw Nmap output and so are *
|
||||
* not derivative works.) *
|
||||
* o Integrates/includes/aggregates Nmap into a proprietary executable *
|
||||
* installer, such as those produced by InstallShield. *
|
||||
* o Links to a library or executes a program that does any of the above *
|
||||
* *
|
||||
* The term "Nmap" should be taken to also include any portions or derived *
|
||||
* works of Nmap. This list is not exclusive, but is meant to clarify our *
|
||||
* interpretation of derived works with some common examples. Our *
|
||||
* interpretation applies only to Nmap--we don't speak for other people's *
|
||||
* GPL works. *
|
||||
* *
|
||||
* If you have any questions about the GPL licensing restrictions on using *
|
||||
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
|
||||
* we also offer alternative license to integrate Nmap into proprietary *
|
||||
* applications and appliances. These contracts have been sold to dozens *
|
||||
* of software vendors, and generally include a perpetual license as well *
|
||||
* as providing for priority support and updates as well as helping to *
|
||||
* fund the continued development of Nmap technology. Please email *
|
||||
* sales@insecure.com for further information. *
|
||||
* *
|
||||
* As a special exception to the GPL terms, Insecure.Com LLC grants *
|
||||
* permission to link the code of this program with any version of the *
|
||||
* OpenSSL library which is distributed under a license identical to that *
|
||||
* listed in the included docs/licenses/OpenSSL.txt file, and distribute *
|
||||
* linked combinations including the two. You must obey the GNU GPL in all *
|
||||
* respects for all of the code used other than OpenSSL. If you modify *
|
||||
* this file, you may extend this exception to your version of the file, *
|
||||
* but you are not obligated to do so. *
|
||||
* *
|
||||
* If you received these files with a written license agreement or *
|
||||
* contract stating terms other than the terms above, then that *
|
||||
* alternative license agreement takes precedence over these comments. *
|
||||
* *
|
||||
* Source is provided to this software because we believe users have a *
|
||||
* right to know exactly what a program is going to do before they run it. *
|
||||
* This also allows you to audit the software for security holes (none *
|
||||
* have been found so far). *
|
||||
* *
|
||||
* Source code also allows you to port Nmap to new platforms, fix bugs, *
|
||||
* and add new features. You are highly encouraged to send your changes *
|
||||
* to nmap-dev@insecure.org for possible incorporation into the main *
|
||||
* distribution. By sending these changes to Fyodor or one of the *
|
||||
* Insecure.Org development mailing lists, it is assumed that you are *
|
||||
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
|
||||
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
|
||||
* will always be available Open Source, but this is important because the *
|
||||
* inability to relicense code has caused devastating problems for other *
|
||||
* Free Software projects (such as KDE and NASM). We also occasionally *
|
||||
* relicense the code to third parties as discussed above. If you wish to *
|
||||
* specify special license conditions of your contributions, just say so *
|
||||
* when you send them. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, but *
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
||||
* General Public License v2.0 for more details at *
|
||||
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
|
||||
* included with Nmap. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef _NETUTIL_ADDRSET_H
|
||||
#define _NETUTIL_ADDRSET_H
|
||||
|
||||
//#define HAVE_IPV6 1
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#ifndef WIN32
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct addrset_elem;
|
||||
|
||||
/* A set of addresses. Used to match against allow/deny lists. */
|
||||
struct addrset {
|
||||
/* Linked list of struct addset_elem. */
|
||||
struct addrset_elem *head;
|
||||
};
|
||||
|
||||
/* We use bit vectors to represent what values are allowed in an IPv4 octet.
|
||||
Each vector is built up of an array of bitvector_t (any convenient integer
|
||||
type). */
|
||||
typedef unsigned long bitvector_t;
|
||||
/* A 256-element bit vector, representing legal values for one octet. */
|
||||
typedef bitvector_t octet_bitvector[(256 - 1) / (sizeof(unsigned long) * CHAR_BIT) + 1];
|
||||
|
||||
enum addrset_elem_type {
|
||||
ADDRSET_TYPE_IPV4_BITVECTOR,
|
||||
#ifdef HAVE_IPV6
|
||||
ADDRSET_TYPE_IPV6_NETMASK,
|
||||
#endif
|
||||
};
|
||||
|
||||
/* A chain of tests for set inclusion. If one test is passed, the address is in
|
||||
the set. */
|
||||
struct addrset_elem {
|
||||
enum addrset_elem_type type;
|
||||
union {
|
||||
struct {
|
||||
/* A bit vector for each address octet. */
|
||||
octet_bitvector bits[4];
|
||||
} ipv4;
|
||||
#ifdef HAVE_IPV6
|
||||
struct {
|
||||
struct in6_addr addr;
|
||||
struct in6_addr mask;
|
||||
} ipv6;
|
||||
#endif
|
||||
} u;
|
||||
struct addrset_elem *next;
|
||||
};
|
||||
|
||||
extern void addrset_init(struct addrset *set);
|
||||
|
||||
extern void addrset_free(struct addrset *set);
|
||||
|
||||
extern int addrset_add_spec(struct addrset *set, const char *spec, int af, int dns);
|
||||
|
||||
extern int addrset_add_file(struct addrset *set, FILE *fd, int af, int dns);
|
||||
|
||||
extern int addrset_contains(const struct addrset *set, const struct sockaddr *sa);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
22
nmap.cc
22
nmap.cc
@@ -475,7 +475,7 @@ int nmap_main(int argc, char *argv[]) {
|
||||
/* Only NSE scripts can add targets */
|
||||
NewTargets *new_targets = NULL;
|
||||
#endif
|
||||
addrset exclude_group;
|
||||
TargetGroup *exclude_group = NULL;
|
||||
char myname[MAXHOSTNAMELEN + 1];
|
||||
#if (defined(IN_ADDR_DEEPSTRUCT) || defined( SOLARIS))
|
||||
/* Note that struct in_addr in solaris is 3 levels deep just to store an
|
||||
@@ -1645,17 +1645,20 @@ int nmap_main(int argc, char *argv[]) {
|
||||
|
||||
/* lets load our exclude list */
|
||||
if (excludefd != NULL) {
|
||||
load_exclude_file(&exclude_group, excludefd);
|
||||
exclude_group = load_exclude_file(excludefd);
|
||||
fclose(excludefd);
|
||||
}
|
||||
if (exclude_spec != NULL) {
|
||||
/* Simultaneous --excludefile and --exclude are not supported. */
|
||||
load_exclude_string(&exclude_group ,exclude_spec);
|
||||
assert(exclude_group == NULL);
|
||||
exclude_group = load_exclude_string(exclude_spec);
|
||||
free(exclude_spec);
|
||||
}
|
||||
|
||||
if (o.debugging > 3)
|
||||
dumpExclude(&exclude_group);
|
||||
if (exclude_group != NULL) {
|
||||
if (o.debugging > 3)
|
||||
dumpExclude(exclude_group);
|
||||
}
|
||||
|
||||
#ifndef NOLUA
|
||||
if (o.scriptupdatedb) {
|
||||
@@ -1689,7 +1692,7 @@ int nmap_main(int argc, char *argv[]) {
|
||||
ideal_scan_group_sz = determineScanGroupSize(o.numhosts_scanned, &ports);
|
||||
while(Targets.size() < ideal_scan_group_sz) {
|
||||
o.current_scantype = HOST_DISCOVERY;
|
||||
currenths = nexthost(hstate, &exclude_group, &ports, o.pingtype);
|
||||
currenths = nexthost(hstate, exclude_group, &ports, o.pingtype);
|
||||
if (!currenths) {
|
||||
/* Try to refill with any remaining expressions */
|
||||
/* First free the old ones */
|
||||
@@ -1727,7 +1730,7 @@ int nmap_main(int argc, char *argv[]) {
|
||||
num_host_exp_groups);
|
||||
|
||||
/* Try one last time -- with new expressions */
|
||||
currenths = nexthost(hstate, &exclude_group, &ports, o.pingtype);
|
||||
currenths = nexthost(hstate, exclude_group, &ports, o.pingtype);
|
||||
if (!currenths)
|
||||
break;
|
||||
}
|
||||
@@ -1968,8 +1971,9 @@ int nmap_main(int argc, char *argv[]) {
|
||||
#endif
|
||||
|
||||
delete hstate;
|
||||
|
||||
addrset_free(&exclude_group);
|
||||
if (exclude_group)
|
||||
delete[] exclude_group;
|
||||
|
||||
hstate = NULL;
|
||||
|
||||
/* Free host expressions */
|
||||
|
||||
167
targets.cc
167
targets.cc
@@ -101,7 +101,7 @@
|
||||
#include "nmap_dns.h"
|
||||
#include "nmap_tty.h"
|
||||
#include "utils.h"
|
||||
#include "libnetutil/addrset.h"
|
||||
|
||||
using namespace std;
|
||||
extern NmapOps o;
|
||||
|
||||
@@ -156,40 +156,133 @@ void returnhost(HostGroupState *hs) {
|
||||
/* Is the host passed as Target to be excluded? Much of this logic had
|
||||
to be rewritten from wam's original code to allow for the objects */
|
||||
static int hostInExclude(struct sockaddr *checksock, size_t checksocklen,
|
||||
const addrset *exclude_group) {
|
||||
if (exclude_group == NULL)
|
||||
TargetGroup *exclude_group) {
|
||||
unsigned long tmpTarget; /* ip we examine */
|
||||
int i=0; /* a simple index */
|
||||
char targets_type; /* what is the address type of the Target Group */
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
|
||||
size_t slen; /* needed for funct but not used */
|
||||
unsigned long mask = 0; /* our trusty netmask, which we convert to nbo */
|
||||
struct sockaddr_in *checkhost_in;
|
||||
|
||||
if ((TargetGroup *)0 == exclude_group)
|
||||
return 0;
|
||||
|
||||
if (checksock == NULL)
|
||||
return 0;
|
||||
checkhost_in = NULL;
|
||||
if (checksock->sa_family == AF_INET) {
|
||||
assert(checksocklen >= sizeof(struct sockaddr_in));
|
||||
checkhost_in = (struct sockaddr_in *) checksock;
|
||||
}
|
||||
|
||||
if (addrset_contains(exclude_group,checksock))
|
||||
return 1;
|
||||
/* First find out what type of addresses are in the target group */
|
||||
targets_type = exclude_group[i].get_targets_type();
|
||||
|
||||
/* Lets go through the targets until we reach our uninitialized placeholder */
|
||||
while (exclude_group[i].get_targets_type() != TargetGroup::TYPE_NONE) {
|
||||
/* while there are still hosts in the target group */
|
||||
while (exclude_group[i].get_next_host(&ss, &slen) == 0) {
|
||||
tmpTarget = sin->sin_addr.s_addr;
|
||||
|
||||
/* For Netmasks simply compare the network bits and move to the next
|
||||
* group if it does not compare, we don't care about the individual addrs */
|
||||
if (targets_type == TargetGroup::IPV4_NETMASK) {
|
||||
if (checkhost_in == NULL)
|
||||
break;
|
||||
mask = htonl((unsigned long) (0-1) << (32-exclude_group[i].get_mask()));
|
||||
if ((tmpTarget & mask) == (checkhost_in->sin_addr.s_addr & mask)) {
|
||||
exclude_group[i].rewind();
|
||||
return 1;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* For ranges we need to be a little more slick, if we don't find a match
|
||||
* we should skip the rest of the addrs in the octet, thank wam for this
|
||||
* optimization */
|
||||
else if (targets_type == TargetGroup::IPV4_RANGES) {
|
||||
if (checkhost_in == NULL)
|
||||
break;
|
||||
if (tmpTarget == checkhost_in->sin_addr.s_addr) {
|
||||
exclude_group[i].rewind();
|
||||
return 1;
|
||||
} else {
|
||||
/* note these are in network byte order */
|
||||
if ((tmpTarget & 0x000000ff) != (checkhost_in->sin_addr.s_addr & 0x000000ff))
|
||||
exclude_group[i].skip_range(TargetGroup::FIRST_OCTET);
|
||||
else if ((tmpTarget & 0x0000ff00) != (checkhost_in->sin_addr.s_addr & 0x0000ff00))
|
||||
exclude_group[i].skip_range(TargetGroup::SECOND_OCTET);
|
||||
else if ((tmpTarget & 0x00ff0000) != (checkhost_in->sin_addr.s_addr & 0x00ff0000))
|
||||
exclude_group[i].skip_range(TargetGroup::THIRD_OCTET);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#if HAVE_IPV6
|
||||
else if (targets_type == TargetGroup::IPV6_ADDRESS) {
|
||||
fatal("exclude file not supported for IPV6 -- If it is important to you, send a mail to fyodor@insecure.org so I can guage support\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
exclude_group[i++].rewind();
|
||||
}
|
||||
|
||||
/* we did not find the host */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert a vector of host specifications to an array (allocated with new[]) of
|
||||
TargetGroups. The size of the returned array is one greater than the number
|
||||
of host specs, to leave on uninitialized member at the end. */
|
||||
static TargetGroup *specs_to_targetgroups(const std::vector<std::string> &specs) {
|
||||
TargetGroup *excludelist;
|
||||
unsigned int i;
|
||||
|
||||
excludelist = new TargetGroup[specs.size() + 1];
|
||||
|
||||
for (i = 0; i < specs.size(); i++) {
|
||||
if (excludelist[i].parse_expr(specs[i].c_str(), o.af()) == 0) {
|
||||
if (o.debugging > 1)
|
||||
error("Loaded exclude target of: %s", specs[i].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return excludelist;
|
||||
}
|
||||
|
||||
/* Load an exclude list from a file for --excludefile. */
|
||||
int load_exclude_file(addrset *excludelist, FILE *fp) {
|
||||
addrset_init(excludelist);
|
||||
TargetGroup* load_exclude_file(FILE *fp) {
|
||||
std::vector<std::string> specs;
|
||||
char host_spec[1024];
|
||||
size_t n;
|
||||
|
||||
while ((n = read_host_from_file(fp, host_spec, sizeof(host_spec))) > 0) {
|
||||
if (n >= sizeof(host_spec))
|
||||
fatal("One of your exclude file specifications was too long to read (>= %u chars)", (unsigned int) sizeof(host_spec));
|
||||
addrset_add_spec(excludelist, host_spec, o.af(), 1);
|
||||
specs.push_back(host_spec);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return specs_to_targetgroups(specs);
|
||||
}
|
||||
|
||||
/* Load a comma-separated exclude list from a string, the argument to
|
||||
--exclude. */
|
||||
int load_exclude_string(addrset *excludelist, const char *s) {
|
||||
addrset_init(excludelist);
|
||||
addrset_add_spec(excludelist, s, o.af(), 1);
|
||||
TargetGroup* load_exclude_string(const char *s) {
|
||||
std::vector<std::string> specs;
|
||||
const char *begin, *p;
|
||||
|
||||
return 1;
|
||||
p = s;
|
||||
while (*p != '\0') {
|
||||
begin = p;
|
||||
while (*p != '\0' && *p != ',')
|
||||
p++;
|
||||
specs.push_back(std::string(begin, p - begin));
|
||||
if (*p == '\0')
|
||||
break;
|
||||
p++;
|
||||
}
|
||||
|
||||
return specs_to_targetgroups(specs);
|
||||
}
|
||||
|
||||
|
||||
@@ -199,11 +292,43 @@ int load_exclude_string(addrset *excludelist, const char *s) {
|
||||
the Target Group Object. Rather than writing a bunch of methods to return
|
||||
private attributes, which would only be used for debugging, I went for the
|
||||
method below. */
|
||||
int dumpExclude(addrset *exclude_group) {
|
||||
/* When we updated the exclude code to use addrset from libnetutil (originally
|
||||
from ncat) there was no simple available debugging function. Thus we are
|
||||
zeroing this and if it is needed look in addrset.cc for the lower level
|
||||
debug function -Colin */
|
||||
int dumpExclude(TargetGroup *exclude_group) {
|
||||
int i=0, debug_save=0, type=TargetGroup::TYPE_NONE;
|
||||
unsigned int mask = 0;
|
||||
struct sockaddr_storage ss;
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
|
||||
size_t slen;
|
||||
|
||||
/* shut off debugging for now, this is a debug routine in itself, we don't
|
||||
want to see all the debug messages inside of the object */
|
||||
debug_save = o.debugging;
|
||||
o.debugging = 0;
|
||||
|
||||
while ((type = exclude_group[i].get_targets_type()) != TargetGroup::TYPE_NONE) {
|
||||
switch (type) {
|
||||
case TargetGroup::IPV4_NETMASK:
|
||||
exclude_group[i].get_next_host(&ss, &slen);
|
||||
mask = exclude_group[i].get_mask();
|
||||
error("exclude host group %d is %s/%d", i, inet_ntoa(sin->sin_addr), mask);
|
||||
break;
|
||||
|
||||
case TargetGroup::IPV4_RANGES:
|
||||
while (exclude_group[i].get_next_host(&ss, &slen) == 0)
|
||||
error("exclude host group %d is %s", i, inet_ntoa(sin->sin_addr));
|
||||
break;
|
||||
|
||||
case TargetGroup::IPV6_ADDRESS:
|
||||
fatal("IPV6 addresses are not supported in the exclude file\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Unknown target type in exclude file.\n");
|
||||
}
|
||||
exclude_group[i++].rewind();
|
||||
}
|
||||
|
||||
/* return debugging to what it was */
|
||||
o.debugging = debug_save;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -290,7 +415,7 @@ static bool target_needs_new_hostgroup(const HostGroupState *hs, const Target *t
|
||||
return false;
|
||||
}
|
||||
|
||||
Target *nexthost(HostGroupState *hs, const addrset *exclude_group,
|
||||
Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
|
||||
struct scan_lists *ports, int pingtype) {
|
||||
int i;
|
||||
struct sockaddr_storage ss;
|
||||
|
||||
10
targets.h
10
targets.h
@@ -115,7 +115,6 @@
|
||||
#endif
|
||||
|
||||
#include "nmap.h"
|
||||
#include "libnetutil/addrset.h"
|
||||
#include "global_structures.h"
|
||||
|
||||
class HostGroupState;
|
||||
@@ -155,14 +154,15 @@ struct pingtech {
|
||||
rawprotoscan: 1;
|
||||
};
|
||||
|
||||
|
||||
/* Ports is the list of ports the user asked to be scanned (0 terminated),
|
||||
you can just pass NULL (it is only a stupid optimization that needs it) */
|
||||
Target *nexthost(HostGroupState *hs,const addrset *exclude_group,
|
||||
Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
|
||||
struct scan_lists *ports, int pingtype);
|
||||
int load_exclude_file(addrset *exclude_group, FILE *fp);
|
||||
int load_exclude_string(addrset *exclude_group, const char *s);
|
||||
TargetGroup* load_exclude_file(FILE *fp);
|
||||
TargetGroup* load_exclude_string(const char *s);
|
||||
/* a debugging routine to dump an exclude list to stdout. */
|
||||
int dumpExclude(addrset *exclude_group);
|
||||
int dumpExclude(TargetGroup*exclude_group);
|
||||
/* Returns the last host obtained by nexthost. It will be given again the next
|
||||
time you call nexthost(). */
|
||||
void returnhost(HostGroupState *hs);
|
||||
|
||||
Reference in New Issue
Block a user