Skip to content

Commit

Permalink
refactor massip-addr
Browse files Browse the repository at this point in the history
  • Loading branch information
robertdavidgraham committed Jan 6, 2021
1 parent 8387c6d commit b1f9e9f
Show file tree
Hide file tree
Showing 41 changed files with 175 additions and 66 deletions.
2 changes: 1 addition & 1 deletion src/in-binary.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Read in the binary file produced by "out-binary.c". This allows you to
translate the "binary" format into any of the other output formats.
*/
#include "ipv6address.h"
#include "massip-addr.h"
#include "in-binary.h"
#include "masscan.h"
#include "masscan-app.h"
Expand Down
2 changes: 1 addition & 1 deletion src/in-filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
#ifndef IN_FILTER_H
#define IN_FILTER_H
#include "ipv6address.h"
#include "massip-addr.h"
struct RangeList;
struct Range6List;
struct MassIP;
Expand Down
2 changes: 1 addition & 1 deletion src/logger.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#ifndef LOGGER_H
#define LOGGER_H
#include "ipv6address.h"
#include "massip-addr.h"

void LOG(int level, const char *fmt, ...);
void LOGip(int level, ipaddress ip, unsigned port, const char *fmt, ...);
Expand Down
42 changes: 29 additions & 13 deletions src/main-conf.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@
*/
#include "masscan.h"
#include "ipv6address.h"
#include "massip-addr.h"
#include "masscan-version.h"
#include "string_s.h"
#include "logger.h"
#include "proto-banner1.h"
#include "templ-payloads.h"
#include "templ-port.h"
#include "crypto-base64.h"
#include "vulncheck.h"
#include "masscan-app.h"
Expand All @@ -27,6 +26,7 @@
#include "util-malloc.h"
#include "massip.h"
#include "massip-parse.h"
#include "massip-port.h"
#include <ctype.h>
#include <limits.h>

Expand Down Expand Up @@ -1879,14 +1879,21 @@ masscan_set_parameter(struct Masscan *masscan,
|| EQUALS("dst-port", name) || EQUALS("dest-port", name)
|| EQUALS("destination-port", name)
|| EQUALS("target-port", name)) {
unsigned is_error = 0;
unsigned defaultrange = 0;
if (masscan->scan_type.udp)
rangelist_parse_ports(&masscan->targets.ports, value, &is_error, Templ_UDP);
else
rangelist_parse_ports(&masscan->targets.ports, value, &is_error, 0);
defaultrange = Templ_UDP;
else if (masscan->scan_type.sctp)
defaultrange = Templ_SCTP;
int err;

err = massip_add_port_string(&masscan->targets, value, defaultrange);
if (err) {
fprintf(stderr, "[-] FAIL: bad target port: %s\n", value);
fprintf(stderr, " Hint: a port is a number [0..65535]\n");
exit(1);
}
if (masscan->op == 0)
masscan->op = Operation_Scan;
}
masscan->op = Operation_Scan; }
else if (EQUALS("banner-types", name) || EQUALS("banner-type", name)
|| EQUALS("banner-apps", name) || EQUALS("banner-app", name)
) {
Expand All @@ -1903,12 +1910,21 @@ masscan_set_parameter(struct Masscan *masscan,
exit(1);
}
} else if (EQUALS("exclude-ports", name) || EQUALS("exclude-port", name)) {
unsigned is_error = 0;
rangelist_parse_ports(&masscan->exclude.ports, value, &is_error, 0);
if (is_error) {
LOG(0, "FAIL: bad exclude port: %s\n", value);
unsigned defaultrange = 0;
if (masscan->scan_type.udp)
defaultrange = Templ_UDP;
else if (masscan->scan_type.sctp)
defaultrange = Templ_SCTP;
int err;

err = massip_add_port_string(&masscan->exclude, value, defaultrange);
if (err) {
fprintf(stderr, "[-] FAIL: bad exclude port: %s\n", value);
fprintf(stderr, " Hint: a port is a number [0..65535]\n");
exit(1);
}
if (masscan->op == 0)
masscan->op = Operation_Scan;
} else if (EQUALS("bpf", name)) {
size_t len = strlen(value) + 1;
if (masscan->bpf_filter)
Expand Down Expand Up @@ -2766,7 +2782,7 @@ masscan_command_line(struct Masscan *masscan, int argc, char *argv[])
continue;
}

if (!isdigit(argv[i][0])) {
if (!isdigit(argv[i][0]) && argv[i][0] != ':' && argv[i][0] != '[') {
fprintf(stderr, "FAIL: unknown command-line parameter \"%s\"\n", argv[i]);
fprintf(stderr, " [hint] did you want \"--%s\"?\n", argv[i]);
exit(1);
Expand Down
2 changes: 1 addition & 1 deletion src/main-dedup.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#ifndef MAIN_DEDUP_H
#define MAIN_DEDUP_H
#include "ipv6address.h"
#include "massip-addr.h"

struct DedupTable *
dedup_create(void);
Expand Down
25 changes: 24 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
#include "proto-snmp.h" /* parse SNMP responses */
#include "proto-ntp.h" /* parse NTP responses */
#include "proto-coap.h" /* CoAP selftest */
#include "templ-port.h"
#include "in-binary.h" /* convert binary output to XML/JSON */
#include "main-globals.h" /* all the global variables in the program */
#include "proto-zeroaccess.h"
Expand All @@ -64,6 +63,7 @@
#include "util-malloc.h"
#include "util-checksum.h"
#include "massip-parse.h"
#include "massip-port.h"

#include <assert.h>
#include <limits.h>
Expand Down Expand Up @@ -1605,6 +1605,9 @@ int main(int argc, char *argv[])
has_target_addresses = massip_has_ipv4_targets(&masscan->targets) || massip_has_ipv6_targets(&masscan->targets);
has_target_ports = massip_has_target_ports(&masscan->targets);
massip_apply_excludes(&masscan->targets, &masscan->exclude);
if (!has_target_ports && masscan->op == Operation_ListScan)
massip_add_port_string(&masscan->targets, "80", 0);




Expand All @@ -1613,6 +1616,26 @@ int main(int argc, char *argv[])
* our --excludefile will chop up our pristine 0.0.0.0/0 range into
* hundreds of subranges. This allows us to grab addresses faster. */
massip_optimize(&masscan->targets);

/* FIXME: we only support 63-bit scans at the current time.
* This is big enough for the IPv4 Internet, where scanning
* for all TCP ports on all IPv4 addresses results in a 48-bit
* scan, but this isn't big enough even for a single port on
* an IPv6 subnet (which are 64-bits in size, usually). However,
* even at millions of packets per second scanning rate, you still
* can't complete a 64-bit scan in a reasonable amount of time.
* Nor would you want to attempt the feat, as it would overload
* the target IPv6 subnet. Since implementing this would be
* difficult for 32-bit processors, for now, I'm going to stick
* to a simple 63-bit scan.
*/
if (massint128_bitcount(massip_range(&masscan->targets)) > 63) {
fprintf(stderr, "[-] FAIL: scan range too large, max is 63-bits, requested is %u bits\n",
massint128_bitcount(massip_range(&masscan->targets)));
fprintf(stderr, " Hint: scan range is number of IP addresses times number of ports\n");
fprintf(stderr, " Hint: IPv6 subnet must be at least /66 \n");
exit(1);
}

/*
* Once we've read in the configuration, do the operation that was
Expand Down
2 changes: 1 addition & 1 deletion src/masscan.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#ifndef MASSCAN_H
#define MASSCAN_H
#include "ipv6address.h"
#include "massip-addr.h"
#include "string_s.h"
#include "stack-src.h"
#include "massip.h"
Expand Down
22 changes: 21 additions & 1 deletion src/ipv6address.c → src/massip-addr.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "ipv6address.h"
#include "massip-addr.h"
#include <string.h>

/**
Expand Down Expand Up @@ -158,6 +158,26 @@ struct ipaddress_formatted ipaddress_fmt(ipaddress a)
return out;
}


static unsigned _count_long(uint64_t number)
{
unsigned i;
unsigned count = 0;
for (i=0; i<64; i++) {
if ((number >> i) & 1)
count = i + 1;
}
return count;
}

unsigned massint128_bitcount(massint128_t number)
{
if (number.hi)
return _count_long(number.hi) + 64;
else
return _count_long(number.lo);
}

int ipv6address_selftest(void)
{
int x = 0;
Expand Down
34 changes: 30 additions & 4 deletions src/ipv6address.h → src/massip-addr.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/*
Simple module that contains the IPv6 type (consisting of two 64-bit
integers), and for pretty-printing the address.
integers), and for pretty-printing the address. Also handles 128-bit
integer arithmetic on addresses.
*/
#ifndef IPV6ADDRESS_H
#define IPV6ADDRESS_H
#ifndef MASSIP_ADDR_H
#define MASSIP_ADDR_H
#include <stdint.h>
#include <stddef.h>

Expand All @@ -14,12 +15,35 @@
#pragma warning(disable: 4201)
#endif

/**
* An IPv6 address is represented as two 64-bit integers intead of a single
* 128-bit integer. This is because curently (year 2020) most compilers
* do not support the `uint128_t` type, but all relevant ones do support
* the `uint64_t` type.
*/
struct ipv6address {uint64_t hi; uint64_t lo;};
typedef struct ipv6address ipv6address;
typedef ipv6address massint128_t;

/**
* IPv4 addresses are represented simply with an integer.
*/
typedef unsigned ipv4address;

/**
* In many cases we need to do arithmetic on IPv6 addresses, treating
* them as a large 128-bit integer. Thus, we declare our own 128-bit
* integer type (and some accompanying math functions). But it's
* still just the same as a 128-bit integer.
*/
typedef ipv6address massint128_t;


/**
* Most of the code in this project is agnostic to the version of IP
* addresses (IPv4 or IPv6). Therefore, we represnet them as a union
* distinguished by a version number. The `version` is an integer
* with a value of either 4 or 6.
*/
struct ipaddress {
union {
unsigned ipv4;
Expand Down Expand Up @@ -72,6 +96,8 @@ struct ipaddress_formatted {
struct ipaddress_formatted ipv6address_fmt(ipv6address a);
struct ipaddress_formatted ipaddress_fmt(ipaddress a);

unsigned massint128_bitcount(massint128_t num);

/**
* @return 0 on success, 1 on failure
*/
Expand Down
4 changes: 4 additions & 0 deletions src/massip-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,10 @@ _parser_next(struct massip_parser *p, const char *buf, size_t *r_offset, size_t
p->digit_count = 1;
state = IPV6_BEGIN;
break;
case ':':
p->ipv6.tmp[p->ipv6.index++] = 0;
state = IPV6_COLON;
break;
case '[':
p->ipv6.is_bracket = 1;
state = IPV6_BEGIN;
Expand Down
4 changes: 3 additions & 1 deletion src/massip-parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
#ifndef MASSIP_PARSE_H
#define MASSIP_PARSE_H
#include "ipv6address.h"
#include "massip-addr.h"

struct MassIP;
struct Range;
Expand Down Expand Up @@ -47,6 +47,8 @@ enum RangeParseResult {
enum RangeParseResult
massip_parse_range(const char *line, size_t *inout_offset, size_t max, struct Range *ipv4, struct Range6 *ipv6);



/**
* Parse a single IPv6 address. This is called when working with
* the operating system stack, when querying addresses from
Expand Down
13 changes: 7 additions & 6 deletions src/templ-port.h → src/massip-port.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#ifndef TEMPL_PORT_H
#define TEMPL_PORT_H
#ifndef MASSIP_PORT_H
#define MASSIP_PORT_H

/*
* Due to the asynchronous scanning architecture, we have to combine TCP
* and UDP ports (plus other scans) in a combined range. Thus, we make
* the weird decision to put UDP ports in the range 64k to 128k, and
* so on. We should probably make this less bizaree in the future.
* Ports are 16-bit numbers ([0..65535], but different
* transports (TCP, UDP, SCTP) are distinct port ranges. Thus, we
* instead of three 64k ranges we could instead treat this internally
* as a 192k port range. We can expand this range to include other
* things we scan for, such as ICMP pings or ARP requests.
*/
enum {
Templ_TCP = 0,
Expand Down
6 changes: 3 additions & 3 deletions src/massip-rangesv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
*/
#include "massip-rangesv4.h"
#include "massip-port.h"
#include "logger.h"
#include "templ-port.h"
#include "util-bool.h"
#include "util-malloc.h"

Expand Down Expand Up @@ -916,11 +916,9 @@ rangelist_parse_ports(struct RangeList *ports, const char *string, unsigned *is_
}

if (port > 0xFF && proto_offset == Templ_Oproto_first) {
LOG(0, "bad ports: %u-%u\n", port, end);
*is_error = 2;
return p;
} else if (port > 0xFFFF || end > 0xFFFF || end < port) {
LOG(0, "bad ports: %u-%u\n", port, end);
*is_error = 2;
return p;
} else {
Expand All @@ -935,6 +933,8 @@ rangelist_parse_ports(struct RangeList *ports, const char *string, unsigned *is_
return p;
}



/***************************************************************************
* Deterministic random number generator for repeatable tests.
***************************************************************************/
Expand Down
2 changes: 2 additions & 0 deletions src/massip-rangesv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,8 @@ range6list_count(const struct Range6List *targets)
ipv6address x;

x = _int128_subtract(targets->list[i].end, targets->list[i].begin);
if (x.hi == ~0ULL && x.lo == ~0ULL)
return x; /* overflow */
x = _int128_add64(x, 1);
result = _int128_add(result, x);
}
Expand Down
2 changes: 1 addition & 1 deletion src/massip-rangesv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
#ifndef RANGES6_H
#define RANGES6_H
#include "ipv6address.h"
#include "massip-addr.h"
#include <stdio.h>
#include <stdint.h>
struct Range;
Expand Down
9 changes: 9 additions & 0 deletions src/massip.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ int massip_add_target_string(struct MassIP *massip, const char *string)
return 0;
}

int massip_add_port_string(struct MassIP *targets, const char *string, unsigned defaultrange)
{
unsigned is_error = 0;
rangelist_parse_ports(&targets->ports, string, &is_error, defaultrange);
if (is_error)
return 1;
else
return 0;
}

int massip_selftest(void)
{
Expand Down
6 changes: 6 additions & 0 deletions src/massip.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ int massip_has_port(const struct MassIP *massip, unsigned port);

int massip_add_target_string(struct MassIP *massip, const char *string);

/**
* Parse the string contain port specifier.
*/
int massip_add_port_string(struct MassIP *massip, const char *string, unsigned proto);


/**
* Indicates whether there are IPv4 targets. If so, we'll have to
* initialize the IPv4 portion of the stack.
Expand Down
Loading

0 comments on commit b1f9e9f

Please sign in to comment.