Merge branch 'master' of github.com:zmap/zmap

This commit is contained in:
Zakir Durumeric 2013-09-09 22:38:21 -04:00
commit 5cd6f3294c
7 changed files with 122 additions and 18 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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])
};

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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