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_;
|
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)
|
void fs_add_null(fieldset_t *fs, const char *name)
|
||||||
{
|
{
|
||||||
fs_add_word(fs, name, FS_NULL, 0, 0, NULL);
|
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);
|
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)
|
uint64_t fs_get_uint64_by_index(fieldset_t *fs, int index)
|
||||||
{
|
{
|
||||||
return (uint64_t) fs->fields[index].value;
|
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 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_uint64(fieldset_t *fs, const char *name, uint64_t value);
|
||||||
|
|
||||||
void fs_add_string(fieldset_t *fs, const char *name, char *value, int free_);
|
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 fs_add_binary(fieldset_t *fs, const char *name, size_t len,
|
||||||
void *value, int free_);
|
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);
|
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_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;
|
static int num_ports;
|
||||||
|
|
||||||
probe_module_t module_udp;
|
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, "success", 1);
|
||||||
fs_add_uint64(fs, "sport", ntohs(udp->source));
|
fs_add_uint64(fs, "sport", ntohs(udp->source));
|
||||||
fs_add_uint64(fs, "dport", ntohs(udp->dest));
|
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_type");
|
||||||
fs_add_null(fs, "icmp_code");
|
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);
|
fs_add_binary(fs, "data", (ntohs(udp->len) - sizeof(struct udphdr)), (void*) &udp[1], 0);
|
||||||
} else if (ip_hdr->protocol == IPPROTO_ICMP) {
|
} else if (ip_hdr->protocol == IPPROTO_ICMP) {
|
||||||
struct icmphdr *icmp = (struct icmphdr *)((char *)ip_hdr + ip_hdr->ihl * 4);
|
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_string(fs, "classification", (char*) "icmp-unreach", 0);
|
||||||
fs_add_uint64(fs, "success", 0);
|
fs_add_uint64(fs, "success", 0);
|
||||||
fs_add_null(fs, "sport");
|
fs_add_null(fs, "sport");
|
||||||
fs_add_null(fs, "dport");
|
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_type", icmp->type);
|
||||||
fs_add_uint64(fs, "icmp_code", icmp->code);
|
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");
|
fs_add_null(fs, "data");
|
||||||
} else {
|
} else {
|
||||||
fs_add_string(fs, "classification", (char*) "other", 0);
|
fs_add_string(fs, "classification", (char*) "other", 0);
|
||||||
fs_add_uint64(fs, "success", 0);
|
fs_add_uint64(fs, "success", 0);
|
||||||
fs_add_null(fs, "sport");
|
fs_add_null(fs, "sport");
|
||||||
fs_add_null(fs, "dport");
|
fs_add_null(fs, "dport");
|
||||||
|
fs_add_null(fs, "icmp_responder");
|
||||||
fs_add_null(fs, "icmp_type");
|
fs_add_null(fs, "icmp_type");
|
||||||
fs_add_null(fs, "icmp_code");
|
fs_add_null(fs, "icmp_code");
|
||||||
|
fs_add_null(fs, "icmp_unreach_str");
|
||||||
fs_add_null(fs, "data");
|
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) {
|
if (icmp->type != ICMP_DEST_UNREACH) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct iphdr *ip_inner = (struct iphdr*)&icmp[1];
|
struct iphdr *ip_inner = (struct iphdr*)&icmp[1];
|
||||||
// Now we know the actual inner ip length, we should recheck the buffer
|
// Now we know the actual inner ip length, we should recheck the buffer
|
||||||
if (len < 4*ip_inner->ihl - sizeof(struct iphdr) + min_len) {
|
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);
|
struct udphdr *udp = (struct udphdr *)((char*)ip_inner + 4*ip_inner->ihl);
|
||||||
|
|
||||||
sport = ntohs(udp->source);
|
sport = ntohs(udp->source);
|
||||||
dport = ntohs(udp->dest);
|
dport = ntohs(udp->dest);
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -280,8 +312,10 @@ static fielddef_t fields[] = {
|
|||||||
{.name = "success", .type="int", .desc = "is response considered success"},
|
{.name = "success", .type="int", .desc = "is response considered success"},
|
||||||
{.name = "sport", .type = "int", .desc = "UDP source port"},
|
{.name = "sport", .type = "int", .desc = "UDP source port"},
|
||||||
{.name = "dport", .type = "int", .desc = "UDP destination 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_type", .type = "int", .desc = "icmp message type"},
|
||||||
{.name = "icmp_code", .type = "int", .desc = "icmp message sub type code"},
|
{.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"}
|
{.name = "data", .type="binary", .desc = "UDP payload"}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -299,6 +333,6 @@ probe_module_t module_udp = {
|
|||||||
.process_packet = &udp_process_packet,
|
.process_packet = &udp_process_packet,
|
||||||
.close = &udp_global_cleanup,
|
.close = &udp_global_cleanup,
|
||||||
.fields = fields,
|
.fields = fields,
|
||||||
.numfields = sizeof(fields)/sizeof(fields[0])
|
.numfields = sizeof(fields)/sizeof(fields[0])
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "state.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;
|
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);
|
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
|
#endif
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "../../lib/logger.h"
|
#include "../../lib/logger.h"
|
||||||
#include "../fieldset.h"
|
#include "../fieldset.h"
|
||||||
#include "probe_modules.h"
|
#include "probe_modules.h"
|
||||||
|
#include "packet.h"
|
||||||
|
|
||||||
extern probe_module_t module_tcp_synscan;
|
extern probe_module_t module_tcp_synscan;
|
||||||
extern probe_module_t module_icmp_echo;
|
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)
|
void fs_add_ip_fields(fieldset_t *fs, struct iphdr *ip)
|
||||||
{
|
{
|
||||||
fs_add_string(fs, "saddr", make_ip_str(ip->saddr), 1);
|
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
|
one-per line. It is recommended you use this to exclude RFC 1918
|
||||||
addresses, multicast, IANA reserved space, and other IANA
|
addresses, multicast, IANA reserved space, and other IANA
|
||||||
special-purpose addresses. An example blacklist file is provided in
|
special-purpose addresses. An example blacklist file is provided in
|
||||||
.B conf/blacklist.example
|
.B conf/blacklist.conf
|
||||||
for this purpose.
|
for this purpose.
|
||||||
.TP
|
.TP
|
||||||
.B -w, --whitelist-file=path
|
.B -w, --whitelist-file=path
|
||||||
@ -98,6 +98,11 @@ Select probe module (default=tcp_synscan)
|
|||||||
.TP
|
.TP
|
||||||
.B \-O, --output-module=name
|
.B \-O, --output-module=name
|
||||||
Select output module (default=simple_file)
|
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
|
.TP
|
||||||
.B --probe-args=args
|
.B --probe-args=args
|
||||||
Arguments to pass to probe module
|
Arguments to pass to probe module
|
||||||
@ -110,12 +115,18 @@ List available output modules
|
|||||||
.TP
|
.TP
|
||||||
.B --list-probe-modules
|
.B --list-probe-modules
|
||||||
List available 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"
|
.SS "Additional options"
|
||||||
.TP
|
.TP
|
||||||
.B \-C, --config=filename
|
.B \-C, --config=filename
|
||||||
Read a configuration file, which can specify
|
Read a configuration file, which can specify
|
||||||
any of these options (default=zmap.conf)
|
any of these options (default=/etc/zmap/zmap.conf)
|
||||||
.TP
|
.TP
|
||||||
.B \-q, --quiet
|
.B \-q, --quiet
|
||||||
Do not print status updates
|
Do not print status updates
|
||||||
|
Loading…
Reference in New Issue
Block a user