Merge branch 'master' of github.com:zmap/zmap
This commit is contained in:
commit
5cd6f3294c
@ -50,6 +50,26 @@ static inline void fs_add_word(fieldset_t *fs, const char *name, int type,
|
||||
f->free_ = free_;
|
||||
}
|
||||
|
||||
static void fs_modify_word(fieldset_t *fs, const char *name, int type,
|
||||
int free_, size_t len, void *value)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<fs->len; i++) {
|
||||
if (!strcmp(fs->fields[i].name, name)) {
|
||||
if (fs->fields[i].free_) {
|
||||
free((void*)fs->fields[i].value);
|
||||
fs->fields[i].value = 0;
|
||||
}
|
||||
fs->fields[i].type = type;
|
||||
fs->fields[i].free_ = free_;
|
||||
fs->fields[i].len = len;
|
||||
fs->fields[i].value = (uint64_t)value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fs_add_word(fs, name, type, free_, len, value);
|
||||
}
|
||||
|
||||
void fs_add_null(fieldset_t *fs, const char *name)
|
||||
{
|
||||
fs_add_word(fs, name, FS_NULL, 0, 0, NULL);
|
||||
@ -71,6 +91,28 @@ void fs_add_binary(fieldset_t *fs, const char *name, size_t len,
|
||||
fs_add_word(fs, name, FS_BINARY, free_, len, value);
|
||||
}
|
||||
|
||||
// Modify
|
||||
void fs_modify_null(fieldset_t *fs, const char *name)
|
||||
{
|
||||
fs_modify_word(fs, name, FS_NULL, 0, 0, NULL);
|
||||
}
|
||||
|
||||
void fs_modify_string(fieldset_t *fs, const char *name, char *value, int free_)
|
||||
{
|
||||
fs_modify_word(fs, name, FS_STRING, free_, strlen(value), (void*) value);
|
||||
}
|
||||
|
||||
void fs_modify_uint64(fieldset_t *fs, const char *name, uint64_t value)
|
||||
{
|
||||
fs_modify_word(fs, name, FS_UINT64, 0, sizeof(uint64_t), (void*) value);
|
||||
}
|
||||
|
||||
void fs_modify_binary(fieldset_t *fs, const char *name, size_t len,
|
||||
void *value, int free_)
|
||||
{
|
||||
fs_modify_word(fs, name, FS_BINARY, free_, len, value);
|
||||
}
|
||||
|
||||
uint64_t fs_get_uint64_by_index(fieldset_t *fs, int index)
|
||||
{
|
||||
return (uint64_t) fs->fields[index].value;
|
||||
|
@ -74,6 +74,8 @@ int fds_get_index_by_name(fielddefset_t *fds, char *name);
|
||||
|
||||
void gen_fielddef_set(fielddefset_t *fds, fielddef_t fs[], int len);
|
||||
|
||||
void fs_add_null(fieldset_t *fs, const char *name);
|
||||
|
||||
void fs_add_uint64(fieldset_t *fs, const char *name, uint64_t value);
|
||||
|
||||
void fs_add_string(fieldset_t *fs, const char *name, char *value, int free_);
|
||||
@ -81,9 +83,17 @@ void fs_add_string(fieldset_t *fs, const char *name, char *value, int free_);
|
||||
void fs_add_binary(fieldset_t *fs, const char *name, size_t len,
|
||||
void *value, int free_);
|
||||
|
||||
uint64_t fs_get_uint64_by_index(fieldset_t *fs, int index);
|
||||
// Modify
|
||||
void fs_modify_null(fieldset_t *fs, const char *name);
|
||||
|
||||
void fs_add_null(fieldset_t *fs, const char *name);
|
||||
void fs_modify_uint64(fieldset_t *fs, const char *name, uint64_t value);
|
||||
|
||||
void fs_modify_string(fieldset_t *fs, const char *name, char *value, int free_);
|
||||
|
||||
void fs_modify_binary(fieldset_t *fs, const char *name, size_t len,
|
||||
void *value, int free_);
|
||||
|
||||
uint64_t fs_get_uint64_by_index(fieldset_t *fs, int index);
|
||||
|
||||
void fs_free(fieldset_t *fs);
|
||||
|
||||
|
@ -36,6 +36,24 @@ int udp_send_msg_len = 0;
|
||||
|
||||
const char *udp_send_msg_default = "GET / HTTP/1.1\r\nHost: www\r\n\r\n";
|
||||
|
||||
const char *udp_unreach_strings[] = {
|
||||
"network unreachable",
|
||||
"host unreachable",
|
||||
"protocol unreachable",
|
||||
"port unreachable",
|
||||
"fragments required",
|
||||
"source route failed",
|
||||
"network unknown",
|
||||
"host unknown",
|
||||
"source host isolated",
|
||||
"network admin. prohibited",
|
||||
"host admin. prohibited",
|
||||
"network unreachable TOS",
|
||||
"host unreachable TOS",
|
||||
"communication admin. prohibited",
|
||||
"host presdence violation",
|
||||
"precedence cutoff"};
|
||||
|
||||
static int num_ports;
|
||||
|
||||
probe_module_t module_udp;
|
||||
@ -202,25 +220,39 @@ void udp_process_packet(const u_char *packet, UNUSED uint32_t len, fieldset_t *f
|
||||
fs_add_uint64(fs, "success", 1);
|
||||
fs_add_uint64(fs, "sport", ntohs(udp->source));
|
||||
fs_add_uint64(fs, "dport", ntohs(udp->dest));
|
||||
fs_add_null(fs, "icmp_responder");
|
||||
fs_add_null(fs, "icmp_type");
|
||||
fs_add_null(fs, "icmp_code");
|
||||
fs_add_null(fs, "icmp_unreach_str");
|
||||
fs_add_binary(fs, "data", (ntohs(udp->len) - sizeof(struct udphdr)), (void*) &udp[1], 0);
|
||||
} else if (ip_hdr->protocol == IPPROTO_ICMP) {
|
||||
struct icmphdr *icmp = (struct icmphdr *)((char *)ip_hdr + ip_hdr->ihl * 4);
|
||||
struct iphdr *ip_inner = (struct iphdr*)&icmp[1];
|
||||
// ICMP unreach comes from another server (not the one we sent a probe to);
|
||||
// But we will fix up saddr to be who we sent the probe to, in case you care.
|
||||
fs_modify_string(fs, "saddr", make_ip_str(ip_inner->daddr), 1);
|
||||
fs_add_string(fs, "classification", (char*) "icmp-unreach", 0);
|
||||
fs_add_uint64(fs, "success", 0);
|
||||
fs_add_null(fs, "sport");
|
||||
fs_add_null(fs, "dport");
|
||||
fs_add_string(fs, "icmp_responder", make_ip_str(ip_hdr->saddr), 1);
|
||||
fs_add_uint64(fs, "icmp_type", icmp->type);
|
||||
fs_add_uint64(fs, "icmp_code", icmp->code);
|
||||
if (icmp->code <= ICMP_PREC_CUTOFF) {
|
||||
fs_add_string(fs, "icmp_unreach_str", (char *)udp_unreach_strings[icmp->code], 0);
|
||||
} else {
|
||||
fs_add_string(fs, "icmp_unreach_str", (char *)"unknown", 0);
|
||||
}
|
||||
fs_add_null(fs, "data");
|
||||
} else {
|
||||
fs_add_string(fs, "classification", (char*) "other", 0);
|
||||
fs_add_uint64(fs, "success", 0);
|
||||
fs_add_null(fs, "sport");
|
||||
fs_add_null(fs, "dport");
|
||||
fs_add_null(fs, "icmp_responder");
|
||||
fs_add_null(fs, "icmp_type");
|
||||
fs_add_null(fs, "icmp_code");
|
||||
fs_add_null(fs, "icmp_unreach_str");
|
||||
fs_add_null(fs, "data");
|
||||
}
|
||||
}
|
||||
@ -252,7 +284,7 @@ int udp_validate_packet(const struct iphdr *ip_hdr, uint32_t len,
|
||||
if (icmp->type != ICMP_DEST_UNREACH) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct iphdr *ip_inner = (struct iphdr*)&icmp[1];
|
||||
// Now we know the actual inner ip length, we should recheck the buffer
|
||||
if (len < 4*ip_inner->ihl - sizeof(struct iphdr) + min_len) {
|
||||
@ -262,7 +294,7 @@ int udp_validate_packet(const struct iphdr *ip_hdr, uint32_t len,
|
||||
struct udphdr *udp = (struct udphdr *)((char*)ip_inner + 4*ip_inner->ihl);
|
||||
|
||||
sport = ntohs(udp->source);
|
||||
dport = ntohs(udp->dest);
|
||||
dport = ntohs(udp->dest);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
@ -280,8 +312,10 @@ static fielddef_t fields[] = {
|
||||
{.name = "success", .type="int", .desc = "is response considered success"},
|
||||
{.name = "sport", .type = "int", .desc = "UDP source port"},
|
||||
{.name = "dport", .type = "int", .desc = "UDP destination port"},
|
||||
{.name = "icmp_responder", .type = "string", .desc = "Source IP of ICMP_UNREACH message"},
|
||||
{.name = "icmp_type", .type = "int", .desc = "icmp message type"},
|
||||
{.name = "icmp_code", .type = "int", .desc = "icmp message sub type code"},
|
||||
{.name = "icmp_unreach_str", .type = "string", .desc = "for icmp_unreach responses, the string version of icmp_code (e.g. network-unreach)"},
|
||||
{.name = "data", .type="binary", .desc = "UDP payload"}
|
||||
};
|
||||
|
||||
@ -299,6 +333,6 @@ probe_module_t module_udp = {
|
||||
.process_packet = &udp_process_packet,
|
||||
.close = &udp_global_cleanup,
|
||||
.fields = fields,
|
||||
.numfields = sizeof(fields)/sizeof(fields[0])
|
||||
.numfields = sizeof(fields)/sizeof(fields[0])
|
||||
};
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "state.h"
|
||||
|
||||
@ -121,3 +122,16 @@ void make_udp_header(struct udphdr *udp_header, port_h_t dest_port,
|
||||
udp_header->check = 0;
|
||||
}
|
||||
|
||||
// Note: caller must free return value
|
||||
char *make_ip_str(uint32_t ip)
|
||||
{
|
||||
struct in_addr t;
|
||||
t.s_addr = ip;
|
||||
const char *temp = inet_ntoa(t);
|
||||
char *retv = malloc(strlen(temp)+1);
|
||||
assert (retv);
|
||||
strcpy(retv, temp);
|
||||
return retv;
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,4 +102,7 @@ static __attribute__((unused)) inline uint16_t get_src_port(int num_ports,
|
||||
return zconf.source_port_first + ((validation[1] + probe_num) % num_ports);
|
||||
}
|
||||
|
||||
// Note: caller must free return value
|
||||
char *make_ip_str(uint32_t ip);
|
||||
|
||||
#endif
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "../../lib/logger.h"
|
||||
#include "../fieldset.h"
|
||||
#include "probe_modules.h"
|
||||
#include "packet.h"
|
||||
|
||||
extern probe_module_t module_tcp_synscan;
|
||||
extern probe_module_t module_icmp_echo;
|
||||
@ -53,17 +54,6 @@ void print_probe_modules(void)
|
||||
}
|
||||
}
|
||||
|
||||
char *make_ip_str(uint32_t ip)
|
||||
{
|
||||
struct in_addr t;
|
||||
t.s_addr = ip;
|
||||
const char *temp = inet_ntoa(t);
|
||||
char *retv = malloc(strlen(temp)+1);
|
||||
assert (retv);
|
||||
strcpy(retv, temp);
|
||||
return retv;
|
||||
}
|
||||
|
||||
void fs_add_ip_fields(fieldset_t *fs, struct iphdr *ip)
|
||||
{
|
||||
fs_add_string(fs, "saddr", make_ip_str(ip->saddr), 1);
|
||||
|
15
src/zmap.1
15
src/zmap.1
@ -24,7 +24,7 @@ File of subnets to exclude, in CIDR notation (e.g. 192.168.0.0/16),
|
||||
one-per line. It is recommended you use this to exclude RFC 1918
|
||||
addresses, multicast, IANA reserved space, and other IANA
|
||||
special-purpose addresses. An example blacklist file is provided in
|
||||
.B conf/blacklist.example
|
||||
.B conf/blacklist.conf
|
||||
for this purpose.
|
||||
.TP
|
||||
.B -w, --whitelist-file=path
|
||||
@ -98,6 +98,11 @@ Select probe module (default=tcp_synscan)
|
||||
.TP
|
||||
.B \-O, --output-module=name
|
||||
Select output module (default=simple_file)
|
||||
.TP
|
||||
.B \-f, --output-fields=fields
|
||||
Fields that should be output in result set; see
|
||||
.B --list-output-fields
|
||||
|
||||
.TP
|
||||
.B --probe-args=args
|
||||
Arguments to pass to probe module
|
||||
@ -110,12 +115,18 @@ List available output modules
|
||||
.TP
|
||||
.B --list-probe-modules
|
||||
List available probe modules
|
||||
.TP
|
||||
.B --list-output-fields
|
||||
List all fields that can be output (using
|
||||
.B --output-fields
|
||||
)
|
||||
by selected probe module
|
||||
|
||||
.SS "Additional options"
|
||||
.TP
|
||||
.B \-C, --config=filename
|
||||
Read a configuration file, which can specify
|
||||
any of these options (default=zmap.conf)
|
||||
any of these options (default=/etc/zmap/zmap.conf)
|
||||
.TP
|
||||
.B \-q, --quiet
|
||||
Do not print status updates
|
||||
|
Loading…
Reference in New Issue
Block a user