beginning the implementation of new output / probe module interface

This commit is contained in:
Zakir Durumeric 2013-08-19 03:02:52 -04:00
parent b70a2835b9
commit a0288adec8
8 changed files with 322 additions and 112 deletions

129
src/fieldset.c Normal file
View File

@ -0,0 +1,129 @@
#include "fieldset.h"
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include "../lib/logger.h"
// maximum number of records that can be stored in a fieldset
#define MAX_FIELDS 128
// types of data that can be stored in a field
#define FS_STRING 0
#define FS_UINT64 1
#define FS_BINARY 2
// definition of a field that's provided by a probe module
// these are used so that users can ask at the command-line
// what fields are available for consumption
typedef struct field_def {
const char *name;
const char *type;
const char *desc;
} field_def_t;
// the internal field type used by fieldset
typedef struct field {
const char *name;
int type;
int free_;
size_t len;
void *value;
} field_t;
// data structure that is populated by the probe module
// and translated into the data structure that's passed
// to the output module
typedef struct fieldset {
int len;
field_t fields[MAX_FIELDS];
} fieldset_t;
// we pass a different fieldset to an output module than
// the probe module generates for us because a user may
// only want certain fields and will expect them in a certain
// order. We generate a translated fieldset that contains
// only the fields we want to export to the output module.
// a translation specifies how to efficiently convert the fs
// povided by the probe module to the fs for the output module.
typedef struct translation {
int len;
int translation[MAX_FIELDS];
} translation_t;
int fs_split_string(int *len, char**results)
{
}
fieldset_t *fs_new_fieldset(void)
{
fieldset_t *f = malloc(sizeof(fieldset_t));
if (!f) {
log_fatal("fieldset", "unable to allocate new fieldset");
}
memset(f, 0, sizeof(fieldset_t));
return f;
}
static inline void fs_add_word(fieldset_t *fs, const char *name, int type,
int free_, size_t len, void *value)
{
if (fs->len + 1 >= MAX_FIELDS) {
log_fatal("fieldset", "out of room in fieldset");
}
field_t *f = &(fs->fields[fs->len]);
fs->len++;
f->type = type;
f->name = name;
f->len = len;
f->value = value;
f->free_ = free_;
}
void fs_add_string(fieldset_t *fs, const char *name, char *value, int free_)
{
fs_add_word(fs, name, FS_STRING, free_, strlen(value), (void*) value);
}
void fs_add_uint64(fieldset_t *fs, const char *name, uint64_t value)
{
fs_add_word(fs, name, FS_STRING, 0, sizeof(uint64_t), (void*) value);
}
void fs_add_binary(fieldset_t *fs, const char *name, size_t len,
void *value, int free_)
{
fs_add_word(fs, name, FS_BINARY, free_, len, value);
}
void fs_free(fieldset_t *fs)
{
for (int i=0; i < fs->len; i++) {
field_t *f = &(fs->fields[i]);
if (f->free_) {
free(f->value);
}
}
free(fs);
}
translation_t *fs_generate_fieldset_translation()
{
}
fieldset_t *translate_fieldset(fieldset_t *fs, translation_t *t)
{
fieldset_t *retv = fs_new_fieldset();
if (!retv) {
log_fatal("fieldset", "unable to allocate space for translated field set");
}
for (int i=0; i < t->len; i++) {
int o = t->translation[i];
memcpy(&(retv->fields[i]), &(fs->fields[o]), sizeof(field_t));
}
retv->len = t->len;
}

0
src/fieldset.h Normal file
View File

View File

@ -24,6 +24,7 @@
static FILE *file = NULL; static FILE *file = NULL;
#define UNUSED __attribute__((unused)) #define UNUSED __attribute__((unused))
int extendedfile_init(struct state_conf *conf) int extendedfile_init(struct state_conf *conf)
{ {
assert(conf); assert(conf);

View File

@ -24,6 +24,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include "probe_modules.h" #include "probe_modules.h"
#include "../fieldset.h"
#include "packet.h" #include "packet.h"
#include "validate.h" #include "validate.h"
@ -111,29 +112,10 @@ void icmp_echo_print_packet(FILE *fp, void* packet)
fprintf(fp, "------------------------------------------------------\n"); fprintf(fp, "------------------------------------------------------\n");
} }
response_type_t* icmp_echo_classify_packet(const u_char *packet, uint32_t len)
{
(void)len;
struct iphdr *ip_hdr = (struct iphdr *)&packet[sizeof(struct ethhdr)];
struct icmp *icmp_hdr = (struct icmp*)((char *)ip_hdr
+ sizeof(struct iphdr));
switch (icmp_hdr->icmp_type) {
case ICMP_ECHOREPLY:
return &(module_icmp_echo.responses[0]);
case ICMP_UNREACH:
return &(module_icmp_echo.responses[1]);
case ICMP_SOURCEQUENCH:
return &(module_icmp_echo.responses[2]);
case ICMP_REDIRECT:
return &(module_icmp_echo.responses[3]);
case ICMP_TIMXCEED:
return &(module_icmp_echo.responses[4]);
default:
return &(module_icmp_echo.responses[5]);
}
}
int icmp_validate_packet(const struct iphdr *ip_hdr, uint32_t len, uint32_t *src_ip, uint32_t *validation)
int icmp_validate_packet(const struct iphdr *ip_hdr,
uint32_t len, uint32_t *src_ip, uint32_t *validation)
{ {
if (ip_hdr->protocol != IPPROTO_ICMP) { if (ip_hdr->protocol != IPPROTO_ICMP) {
return 0; return 0;
@ -175,32 +157,38 @@ int icmp_validate_packet(const struct iphdr *ip_hdr, uint32_t len, uint32_t *src
return 1; return 1;
} }
static response_type_t responses[] = { void icmp_echo_process_packet(const u_char *packet,
{ __attribute__((unused)) uint32_t len, fieldset *fs)
.name = "echoreply", {
.is_success = 1 struct iphdr *ip_hdr = (struct iphdr *)&packet[sizeof(struct ethhdr)];
}, struct icmp *icmp_hdr = (struct icmp*)((char *)ip_hdr
{ + sizeof(struct iphdr));
.name = "unreach",
.is_success = 0 fs_add_uint64(fs, "type", ntohs(icmp_hdr->type));
}, fs_add_uint64(fs, "code", ntohs(icmp_hdr->code));
{ fs_add_uint64(fs, "icmp-id", ntohs(icmp_hdr->un.echo.id));
.name = "sourcequench", fs_add_uint64(fs, "seq", ntohs(icmp_hdr->un.echo.sequence));
.is_success = 0 switch (icmp_hdr->icmp_type) {
}, case ICMP_ECHOREPLY:
{ fs_add_string(fs, "classification", "echoreply", 0);
.name = "redirect", fs_add_uint64(fs, "success", 1);
.is_success = 0 case ICMP_UNREACH:
}, fs_add_string(fs, "classification", "unreach", 0);
{ fs_add_uint64(fs, "success", 0);
.name = "timxceed", case ICMP_SOURCEQUENCH:
.is_success = 0 fs_add_string(fs, "classification", "sourcequench", 0);
}, fs_add_uint64(fs, "success", 0);
{ case ICMP_REDIRECT:
.name = "other", fs_add_string(fs, "classification", "redirect", 0);
.is_success = 0 fs_add_uint64(fs, "success", 0);
case ICMP_TIMXCEED:
fs_add_string(fs, "classification", "timxceed", 0);
fs_add_uint64(fs, "success", 0);
default:
fs_add_string(fs, "classification", "other", 0);
fs_add_uint64(fs, "success", 0);
} }
}; }
probe_module_t module_icmp_echo = { probe_module_t module_icmp_echo = {
.name = "icmp_echoscan", .name = "icmp_echoscan",
@ -211,9 +199,16 @@ probe_module_t module_icmp_echo = {
.thread_initialize = &icmp_echo_init_perthread, .thread_initialize = &icmp_echo_init_perthread,
.make_packet = &icmp_echo_make_packet, .make_packet = &icmp_echo_make_packet,
.print_packet = &icmp_echo_print_packet, .print_packet = &icmp_echo_print_packet,
.classify_packet = &icmp_echo_classify_packet, .process_response = &icmp_echo_process_response,
.validate_packet = &icmp_validate_packet, .validate_packet = &icmp_validate_packet,
.close = NULL, .close = NULL,
.responses = responses .fields = {
{.name "type", .type="int", .desc="icmp message type"},
{.name "code", .type="int", .desc="icmp message sub type code"},
{.name "icmp-id", .type="int", .desc="icmp id number"},
{.name "seq", .type="int", .desc="icmp sequence number"},
{.name="classification", .type="string", .desc="probe module classification"},
{.name="success", .type="int", .desc="did probe module classify response as success"}
}
}; };

View File

@ -13,6 +13,7 @@
#include <stdint.h> #include <stdint.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <assert.h>
#include <netinet/ip.h> #include <netinet/ip.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
@ -22,6 +23,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include "../fieldset.h"
#include "probe_modules.h" #include "probe_modules.h"
#include "packet.h" #include "packet.h"
@ -112,18 +114,6 @@ void synscan_print_packet(FILE *fp, void* packet)
fprintf(fp, "------------------------------------------------------\n"); fprintf(fp, "------------------------------------------------------\n");
} }
response_type_t* synscan_classify_packet(const u_char *packet, uint32_t len)
{
(void)len;
struct iphdr *ip_hdr = (struct iphdr *)&packet[sizeof(struct ethhdr)];
struct tcphdr *tcp = (struct tcphdr*)((char *)ip_hdr
+ (sizeof(struct iphdr)));
if (tcp->rst) { // RST packet
return &(module_tcp_synscan.responses[1]);
} else { // SYNACK packet
return &(module_tcp_synscan.responses[0]);
}
}
int synscan_validate_packet(const struct iphdr *ip_hdr, uint32_t len, int synscan_validate_packet(const struct iphdr *ip_hdr, uint32_t len,
@ -159,16 +149,52 @@ int synscan_validate_packet(const struct iphdr *ip_hdr, uint32_t len,
return 1; return 1;
} }
static response_type_t responses[] = { void fs_add_sys_fields(fieldset_t *fs)
{ {
.is_success = 1,
.name = "synack" }
},
{ char *make_ip_str(uint32_t ip)
.is_success = 0, {
.name = "rst" struct in_addr t;
t.saddr = 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);
fs_add_string(fs, "daddr", make_ip_str(ip->daddr), 1);
fs_add_uint64(fs, "ipid", ntohl(ip->id);
fs_add_uint64(fs, "ttl", ntohl(ip->ttl);
}
void synscan_process_packet(const u_char *packet,
__attribute__((unused)) uint32_t len, fieldset_t *fs)
{
struct iphdr *ip_hdr = (struct iphdr *)&packet[sizeof(struct ethhdr)];
struct tcphdr *tcp = (struct tcphdr*)((char *)ip_hdr
+ (sizeof(struct iphdr)));
fs_add_uint64(fs, "sport", (uint64_t) ntohs(tcp->source));
fs_add_uint64(fs, "dport", (uint64_t) ntohs(tcp->dest));
fs_add_uint64(fs, "seqnum", (uint64_t) ntohs(tcp->seq));
fs_add_uint64(fs, "acknum", (uint64_t) ntohl(tcp->ack_seq));
fs_add_uint64(fs, "window", (uint64_t) ntohs(tcp->window));
if (tcp->rst) { // RST packet
fs_add_string(fs, "classification", "rst", 0);
fs_add_uint64(fs, "success", 0);
} else { // SYNACK packet
fs_add_string(fs, "classification", "synack", 0);
fs_add_uint64(fs, "success", 1);
} }
}; return
}
probe_module_t module_tcp_synscan = { probe_module_t module_tcp_synscan = {
.name = "tcp_synscan", .name = "tcp_synscan",
@ -180,9 +206,15 @@ probe_module_t module_tcp_synscan = {
.thread_initialize = &synscan_init_perthread, .thread_initialize = &synscan_init_perthread,
.make_packet = &synscan_make_packet, .make_packet = &synscan_make_packet,
.print_packet = &synscan_print_packet, .print_packet = &synscan_print_packet,
.classify_packet = &synscan_classify_packet, .process_packet = &synscan_process_packet,
.validate_packet = &synscan_validate_packet, .validate_packet = &synscan_validate_packet,
.close = NULL, .close = NULL,
.responses = responses, .fields = {
{.name = "sport", .type = "int", .desc = "TCP source port"},
{.name = "dport", .type = "int", .desc = "TCP destination port"},
{.name = "seqnum", .type = "int", .desc = "TCP sequence number"},
{.name = "acknum", .type = "int", .desc = "TCP acknowledgement number"},
{.name = "window", .type = "int", .desc = "TCP window"},
}
}; };

View File

@ -37,6 +37,7 @@ const char *gengetopt_args_info_help[] = {
" -o, --output-file=name Output file", " -o, --output-file=name Output file",
" -b, --blacklist-file=path File of subnets to exclude, in CIDR notation, \n e.g. 192.168.0.0/16", " -b, --blacklist-file=path File of subnets to exclude, in CIDR notation, \n e.g. 192.168.0.0/16",
" -w, --whitelist-file=path File of subnets to constrain scan to, in CIDR \n notation, e.g. 192.168.0.0/16", " -w, --whitelist-file=path File of subnets to constrain scan to, in CIDR \n notation, e.g. 192.168.0.0/16",
" -f, --output-fields=fields Fields that should be output in result set",
"\nScan options:", "\nScan options:",
" -n, --max-targets=n Cap number of targets to probe (as a number or \n a percentage of the address space)", " -n, --max-targets=n Cap number of targets to probe (as a number or \n a percentage of the address space)",
" -N, --max-results=n Cap number of results to return", " -N, --max-results=n Cap number of results to return",
@ -60,6 +61,7 @@ const char *gengetopt_args_info_help[] = {
" --output-args=args Arguments to pass to output module", " --output-args=args Arguments to pass to output module",
" --list-output-modules List available output modules", " --list-output-modules List available output modules",
" --list-probe-modules List available probe modules", " --list-probe-modules List available probe modules",
" --list-output-fields List all fields that can be output by selected \n probe module",
"\nAdditional options:", "\nAdditional options:",
" -C, --config=filename Read a configuration file, which can specify \n any of these options \n (default=`/etc/zmap/zmap.conf')", " -C, --config=filename Read a configuration file, which can specify \n any of these options \n (default=`/etc/zmap/zmap.conf')",
" -q, --quiet Do not print status updates", " -q, --quiet Do not print status updates",
@ -120,6 +122,7 @@ void clear_given (struct gengetopt_args_info *args_info)
args_info->output_file_given = 0 ; args_info->output_file_given = 0 ;
args_info->blacklist_file_given = 0 ; args_info->blacklist_file_given = 0 ;
args_info->whitelist_file_given = 0 ; args_info->whitelist_file_given = 0 ;
args_info->output_fields_given = 0 ;
args_info->max_targets_given = 0 ; args_info->max_targets_given = 0 ;
args_info->max_results_given = 0 ; args_info->max_results_given = 0 ;
args_info->max_runtime_given = 0 ; args_info->max_runtime_given = 0 ;
@ -140,6 +143,7 @@ void clear_given (struct gengetopt_args_info *args_info)
args_info->output_args_given = 0 ; args_info->output_args_given = 0 ;
args_info->list_output_modules_given = 0 ; args_info->list_output_modules_given = 0 ;
args_info->list_probe_modules_given = 0 ; args_info->list_probe_modules_given = 0 ;
args_info->list_output_fields_given = 0 ;
args_info->config_given = 0 ; args_info->config_given = 0 ;
args_info->quiet_given = 0 ; args_info->quiet_given = 0 ;
args_info->summary_given = 0 ; args_info->summary_given = 0 ;
@ -159,6 +163,8 @@ void clear_args (struct gengetopt_args_info *args_info)
args_info->blacklist_file_orig = NULL; args_info->blacklist_file_orig = NULL;
args_info->whitelist_file_arg = NULL; args_info->whitelist_file_arg = NULL;
args_info->whitelist_file_orig = NULL; args_info->whitelist_file_orig = NULL;
args_info->output_fields_arg = NULL;
args_info->output_fields_orig = NULL;
args_info->max_targets_arg = NULL; args_info->max_targets_arg = NULL;
args_info->max_targets_orig = NULL; args_info->max_targets_orig = NULL;
args_info->max_results_orig = NULL; args_info->max_results_orig = NULL;
@ -205,32 +211,34 @@ void init_args_info(struct gengetopt_args_info *args_info)
args_info->output_file_help = gengetopt_args_info_help[2] ; args_info->output_file_help = gengetopt_args_info_help[2] ;
args_info->blacklist_file_help = gengetopt_args_info_help[3] ; args_info->blacklist_file_help = gengetopt_args_info_help[3] ;
args_info->whitelist_file_help = gengetopt_args_info_help[4] ; args_info->whitelist_file_help = gengetopt_args_info_help[4] ;
args_info->max_targets_help = gengetopt_args_info_help[6] ; args_info->output_fields_help = gengetopt_args_info_help[5] ;
args_info->max_results_help = gengetopt_args_info_help[7] ; args_info->max_targets_help = gengetopt_args_info_help[7] ;
args_info->max_runtime_help = gengetopt_args_info_help[8] ; args_info->max_results_help = gengetopt_args_info_help[8] ;
args_info->rate_help = gengetopt_args_info_help[9] ; args_info->max_runtime_help = gengetopt_args_info_help[9] ;
args_info->bandwidth_help = gengetopt_args_info_help[10] ; args_info->rate_help = gengetopt_args_info_help[10] ;
args_info->cooldown_time_help = gengetopt_args_info_help[11] ; args_info->bandwidth_help = gengetopt_args_info_help[11] ;
args_info->seed_help = gengetopt_args_info_help[12] ; args_info->cooldown_time_help = gengetopt_args_info_help[12] ;
args_info->sender_threads_help = gengetopt_args_info_help[13] ; args_info->seed_help = gengetopt_args_info_help[13] ;
args_info->probes_help = gengetopt_args_info_help[14] ; args_info->sender_threads_help = gengetopt_args_info_help[14] ;
args_info->dryrun_help = gengetopt_args_info_help[15] ; args_info->probes_help = gengetopt_args_info_help[15] ;
args_info->source_port_help = gengetopt_args_info_help[17] ; args_info->dryrun_help = gengetopt_args_info_help[16] ;
args_info->source_ip_help = gengetopt_args_info_help[18] ; args_info->source_port_help = gengetopt_args_info_help[18] ;
args_info->gateway_mac_help = gengetopt_args_info_help[19] ; args_info->source_ip_help = gengetopt_args_info_help[19] ;
args_info->interface_help = gengetopt_args_info_help[20] ; args_info->gateway_mac_help = gengetopt_args_info_help[20] ;
args_info->probe_module_help = gengetopt_args_info_help[22] ; args_info->interface_help = gengetopt_args_info_help[21] ;
args_info->output_module_help = gengetopt_args_info_help[23] ; args_info->probe_module_help = gengetopt_args_info_help[23] ;
args_info->probe_args_help = gengetopt_args_info_help[24] ; args_info->output_module_help = gengetopt_args_info_help[24] ;
args_info->output_args_help = gengetopt_args_info_help[25] ; args_info->probe_args_help = gengetopt_args_info_help[25] ;
args_info->list_output_modules_help = gengetopt_args_info_help[26] ; args_info->output_args_help = gengetopt_args_info_help[26] ;
args_info->list_probe_modules_help = gengetopt_args_info_help[27] ; args_info->list_output_modules_help = gengetopt_args_info_help[27] ;
args_info->config_help = gengetopt_args_info_help[29] ; args_info->list_probe_modules_help = gengetopt_args_info_help[28] ;
args_info->quiet_help = gengetopt_args_info_help[30] ; args_info->list_output_fields_help = gengetopt_args_info_help[29] ;
args_info->summary_help = gengetopt_args_info_help[31] ; args_info->config_help = gengetopt_args_info_help[31] ;
args_info->verbosity_help = gengetopt_args_info_help[32] ; args_info->quiet_help = gengetopt_args_info_help[32] ;
args_info->help_help = gengetopt_args_info_help[33] ; args_info->summary_help = gengetopt_args_info_help[33] ;
args_info->version_help = gengetopt_args_info_help[34] ; args_info->verbosity_help = gengetopt_args_info_help[34] ;
args_info->help_help = gengetopt_args_info_help[35] ;
args_info->version_help = gengetopt_args_info_help[36] ;
} }
@ -318,6 +326,8 @@ cmdline_parser_release (struct gengetopt_args_info *args_info)
free_string_field (&(args_info->blacklist_file_orig)); free_string_field (&(args_info->blacklist_file_orig));
free_string_field (&(args_info->whitelist_file_arg)); free_string_field (&(args_info->whitelist_file_arg));
free_string_field (&(args_info->whitelist_file_orig)); free_string_field (&(args_info->whitelist_file_orig));
free_string_field (&(args_info->output_fields_arg));
free_string_field (&(args_info->output_fields_orig));
free_string_field (&(args_info->max_targets_arg)); free_string_field (&(args_info->max_targets_arg));
free_string_field (&(args_info->max_targets_orig)); free_string_field (&(args_info->max_targets_orig));
free_string_field (&(args_info->max_results_orig)); free_string_field (&(args_info->max_results_orig));
@ -386,6 +396,8 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
write_into_file(outfile, "blacklist-file", args_info->blacklist_file_orig, 0); write_into_file(outfile, "blacklist-file", args_info->blacklist_file_orig, 0);
if (args_info->whitelist_file_given) if (args_info->whitelist_file_given)
write_into_file(outfile, "whitelist-file", args_info->whitelist_file_orig, 0); write_into_file(outfile, "whitelist-file", args_info->whitelist_file_orig, 0);
if (args_info->output_fields_given)
write_into_file(outfile, "output-fields", args_info->output_fields_orig, 0);
if (args_info->max_targets_given) if (args_info->max_targets_given)
write_into_file(outfile, "max-targets", args_info->max_targets_orig, 0); write_into_file(outfile, "max-targets", args_info->max_targets_orig, 0);
if (args_info->max_results_given) if (args_info->max_results_given)
@ -426,6 +438,8 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
write_into_file(outfile, "list-output-modules", 0, 0 ); write_into_file(outfile, "list-output-modules", 0, 0 );
if (args_info->list_probe_modules_given) if (args_info->list_probe_modules_given)
write_into_file(outfile, "list-probe-modules", 0, 0 ); write_into_file(outfile, "list-probe-modules", 0, 0 );
if (args_info->list_output_fields_given)
write_into_file(outfile, "list-output-fields", 0, 0 );
if (args_info->config_given) if (args_info->config_given)
write_into_file(outfile, "config", args_info->config_orig, 0); write_into_file(outfile, "config", args_info->config_orig, 0);
if (args_info->quiet_given) if (args_info->quiet_given)
@ -692,6 +706,7 @@ cmdline_parser_internal (
{ "output-file", 1, NULL, 'o' }, { "output-file", 1, NULL, 'o' },
{ "blacklist-file", 1, NULL, 'b' }, { "blacklist-file", 1, NULL, 'b' },
{ "whitelist-file", 1, NULL, 'w' }, { "whitelist-file", 1, NULL, 'w' },
{ "output-fields", 1, NULL, 'f' },
{ "max-targets", 1, NULL, 'n' }, { "max-targets", 1, NULL, 'n' },
{ "max-results", 1, NULL, 'N' }, { "max-results", 1, NULL, 'N' },
{ "max-runtime", 1, NULL, 't' }, { "max-runtime", 1, NULL, 't' },
@ -712,6 +727,7 @@ cmdline_parser_internal (
{ "output-args", 1, NULL, 0 }, { "output-args", 1, NULL, 0 },
{ "list-output-modules", 0, NULL, 0 }, { "list-output-modules", 0, NULL, 0 },
{ "list-probe-modules", 0, NULL, 0 }, { "list-probe-modules", 0, NULL, 0 },
{ "list-output-fields", 0, NULL, 0 },
{ "config", 1, NULL, 'C' }, { "config", 1, NULL, 'C' },
{ "quiet", 0, NULL, 'q' }, { "quiet", 0, NULL, 'q' },
{ "summary", 0, NULL, 'g' }, { "summary", 0, NULL, 'g' },
@ -721,7 +737,7 @@ cmdline_parser_internal (
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
}; };
c = getopt_long (argc, argv, "p:o:b:w:n:N:t:r:B:c:e:T:P:ds:S:G:i:M:O:C:qgv:hV", long_options, &option_index); c = getopt_long (argc, argv, "p:o:b:w:f:n:N:t:r:B:c:e:T:P:ds:S:G:i:M:O:C:qgv:hV", long_options, &option_index);
if (c == -1) break; /* Exit from `while (1)' loop. */ if (c == -1) break; /* Exit from `while (1)' loop. */
@ -774,6 +790,18 @@ cmdline_parser_internal (
additional_error)) additional_error))
goto failure; goto failure;
break;
case 'f': /* Fields that should be output in result set. */
if (update_arg( (void *)&(args_info->output_fields_arg),
&(args_info->output_fields_orig), &(args_info->output_fields_given),
&(local_args_info.output_fields_given), optarg, 0, 0, ARG_STRING,
check_ambiguity, override, 0, 0,
"output-fields", 'f',
additional_error))
goto failure;
break; break;
case 'n': /* Cap number of targets to probe (as a number or a percentage of the address space). */ case 'n': /* Cap number of targets to probe (as a number or a percentage of the address space). */
@ -1096,6 +1124,20 @@ cmdline_parser_internal (
additional_error)) additional_error))
goto failure; goto failure;
}
/* List all fields that can be output by selected probe module. */
else if (strcmp (long_options[option_index].name, "list-output-fields") == 0)
{
if (update_arg( 0 ,
0 , &(args_info->list_output_fields_given),
&(local_args_info.list_output_fields_given), optarg, 0, 0, ARG_NO,
check_ambiguity, override, 0, 0,
"list-output-fields", '-',
additional_error))
goto failure;
} }
break; break;

View File

@ -22,6 +22,9 @@ option "blacklist-file" b "File of subnets to exclude, in CIDR notation, e.g. 1
option "whitelist-file" w "File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16" option "whitelist-file" w "File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16"
typestr="path" typestr="path"
optional string optional string
option "output-fields" f "Fields that should be output in result set"
typestr="fields"
optional string
section "Scan options" section "Scan options"
@ -93,6 +96,8 @@ option "list-output-modules" - "List available output modules"
optional optional
option "list-probe-modules" - "List available probe modules" option "list-probe-modules" - "List available probe modules"
optional optional
option "list-output-fields" - "List all fields that can be output by selected probe module"
optional
section "Additional options" section "Additional options"

View File

@ -49,6 +49,9 @@ struct gengetopt_args_info
char * whitelist_file_arg; /**< @brief File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16. */ char * whitelist_file_arg; /**< @brief File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16. */
char * whitelist_file_orig; /**< @brief File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16 original value given at command line. */ char * whitelist_file_orig; /**< @brief File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16 original value given at command line. */
const char *whitelist_file_help; /**< @brief File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16 help description. */ const char *whitelist_file_help; /**< @brief File of subnets to constrain scan to, in CIDR notation, e.g. 192.168.0.0/16 help description. */
char * output_fields_arg; /**< @brief Fields that should be output in result set. */
char * output_fields_orig; /**< @brief Fields that should be output in result set original value given at command line. */
const char *output_fields_help; /**< @brief Fields that should be output in result set help description. */
char * max_targets_arg; /**< @brief Cap number of targets to probe (as a number or a percentage of the address space). */ char * max_targets_arg; /**< @brief Cap number of targets to probe (as a number or a percentage of the address space). */
char * max_targets_orig; /**< @brief Cap number of targets to probe (as a number or a percentage of the address space) original value given at command line. */ char * max_targets_orig; /**< @brief Cap number of targets to probe (as a number or a percentage of the address space) original value given at command line. */
const char *max_targets_help; /**< @brief Cap number of targets to probe (as a number or a percentage of the address space) help description. */ const char *max_targets_help; /**< @brief Cap number of targets to probe (as a number or a percentage of the address space) help description. */
@ -103,6 +106,7 @@ struct gengetopt_args_info
const char *output_args_help; /**< @brief Arguments to pass to output module help description. */ const char *output_args_help; /**< @brief Arguments to pass to output module help description. */
const char *list_output_modules_help; /**< @brief List available output modules help description. */ const char *list_output_modules_help; /**< @brief List available output modules help description. */
const char *list_probe_modules_help; /**< @brief List available probe modules help description. */ const char *list_probe_modules_help; /**< @brief List available probe modules help description. */
const char *list_output_fields_help; /**< @brief List all fields that can be output by selected probe module help description. */
char * config_arg; /**< @brief Read a configuration file, which can specify any of these options (default='/etc/zmap/zmap.conf'). */ char * config_arg; /**< @brief Read a configuration file, which can specify any of these options (default='/etc/zmap/zmap.conf'). */
char * config_orig; /**< @brief Read a configuration file, which can specify any of these options original value given at command line. */ char * config_orig; /**< @brief Read a configuration file, which can specify any of these options original value given at command line. */
const char *config_help; /**< @brief Read a configuration file, which can specify any of these options help description. */ const char *config_help; /**< @brief Read a configuration file, which can specify any of these options help description. */
@ -118,6 +122,7 @@ struct gengetopt_args_info
unsigned int output_file_given ; /**< @brief Whether output-file was given. */ unsigned int output_file_given ; /**< @brief Whether output-file was given. */
unsigned int blacklist_file_given ; /**< @brief Whether blacklist-file was given. */ unsigned int blacklist_file_given ; /**< @brief Whether blacklist-file was given. */
unsigned int whitelist_file_given ; /**< @brief Whether whitelist-file was given. */ unsigned int whitelist_file_given ; /**< @brief Whether whitelist-file was given. */
unsigned int output_fields_given ; /**< @brief Whether output-fields was given. */
unsigned int max_targets_given ; /**< @brief Whether max-targets was given. */ unsigned int max_targets_given ; /**< @brief Whether max-targets was given. */
unsigned int max_results_given ; /**< @brief Whether max-results was given. */ unsigned int max_results_given ; /**< @brief Whether max-results was given. */
unsigned int max_runtime_given ; /**< @brief Whether max-runtime was given. */ unsigned int max_runtime_given ; /**< @brief Whether max-runtime was given. */
@ -138,6 +143,7 @@ struct gengetopt_args_info
unsigned int output_args_given ; /**< @brief Whether output-args was given. */ unsigned int output_args_given ; /**< @brief Whether output-args was given. */
unsigned int list_output_modules_given ; /**< @brief Whether list-output-modules was given. */ unsigned int list_output_modules_given ; /**< @brief Whether list-output-modules was given. */
unsigned int list_probe_modules_given ; /**< @brief Whether list-probe-modules was given. */ unsigned int list_probe_modules_given ; /**< @brief Whether list-probe-modules was given. */
unsigned int list_output_fields_given ; /**< @brief Whether list-output-fields was given. */
unsigned int config_given ; /**< @brief Whether config was given. */ unsigned int config_given ; /**< @brief Whether config was given. */
unsigned int quiet_given ; /**< @brief Whether quiet was given. */ unsigned int quiet_given ; /**< @brief Whether quiet was given. */
unsigned int summary_given ; /**< @brief Whether summary was given. */ unsigned int summary_given ; /**< @brief Whether summary was given. */