also apply generator limit to use with CIDR

As described in GH issue #299, the MAX_GENERATE+1 limit is only
applied when using an address range, not when using CIDR.  This
commit changes this to always honor the generator limit.

* refactor target address generation to use the same new function
  for both range and CIDR notation
* check the limit for addresses to generate in the new function
* document the generator limit in "fping --help" output
* document the generator limit in the fping man page
* test that the address generation limit applies when using CIDR
  notation
pull/334/head
Erik Auerswald 6 months ago
parent d0ed64bcc7
commit 54e6f838c3

@ -1,6 +1,6 @@
#!/usr/bin/perl -w #!/usr/bin/perl -w
use Test::Command tests => 72; use Test::Command tests => 75;
use Test::More; use Test::More;
use File::Temp; use File::Temp;
@ -170,6 +170,14 @@ $cmd->stdout_is_eq("");
$cmd->stderr_is_eq("fping: netmask must be between 1 and 32 (is: 0)\n"); $cmd->stderr_is_eq("fping: netmask must be between 1 and 32 (is: 0)\n");
} }
# fping -g (cidr - too many addresses)
{
my $cmd = Test::Command->new(cmd => "fping -g 127.0.0.0/8");
$cmd->exit_is_num(1);
$cmd->stdout_is_eq("");
$cmd->stderr_is_eq("fping: -g parameter generates too many addresses\n");
}
# fping -g (range - no IPv6 generator) # fping -g (range - no IPv6 generator)
SKIP: { SKIP: {
if($ENV{SKIP_IPV6}) { if($ENV{SKIP_IPV6}) {

@ -294,6 +294,9 @@ line arguments, and 4 for a system call failure.
=head1 RESTRICTIONS =head1 RESTRICTIONS
The number of addresses that can be generated using the C<-g>, C<--generate>
option is limited to 100001.
If fping was configured with C<--enable-safe-limits>, the following values are If fping was configured with C<--enable-safe-limits>, the following values are
not allowed for non-root users: not allowed for non-root users:

@ -394,6 +394,7 @@ struct event *ev_dequeue(struct event_queue *queue);
void ev_remove(struct event_queue *queue, struct event *event); void ev_remove(struct event_queue *queue, struct event *event);
void add_cidr(char *); void add_cidr(char *);
void add_range(char *, char *); void add_range(char *, char *);
void add_addr_range_ipv4(unsigned long, unsigned long);
void print_warning(char *fmt, ...); void print_warning(char *fmt, ...);
int addr_cmp(struct sockaddr *a, struct sockaddr *b); int addr_cmp(struct sockaddr *a, struct sockaddr *b);
void host_add_ping_event(HOST_ENTRY *h, int index, int64_t ev_time); void host_add_ping_event(HOST_ENTRY *h, int index, int64_t ev_time);
@ -1304,13 +1305,7 @@ void add_cidr(char *addr)
} }
/* add all hosts in that network (net_addr and net_last inclusive) */ /* add all hosts in that network (net_addr and net_last inclusive) */
for (; net_addr <= net_last; net_addr++) { add_addr_range_ipv4(net_addr, net_last);
struct in_addr in_addr_tmp;
char buffer[20];
in_addr_tmp.s_addr = htonl(net_addr);
inet_ntop(AF_INET, &in_addr_tmp, buffer, sizeof(buffer));
add_name(buffer);
}
} }
void add_range(char *start, char *end) void add_range(char *start, char *end)
@ -1354,6 +1349,12 @@ void add_range(char *start, char *end)
end_long = ntohl(((struct sockaddr_in *)addr_res->ai_addr)->sin_addr.s_addr); end_long = ntohl(((struct sockaddr_in *)addr_res->ai_addr)->sin_addr.s_addr);
freeaddrinfo(addr_res); freeaddrinfo(addr_res);
/* add IPv4 addresses from closed interval [start_long,end_long] */
add_addr_range_ipv4(start_long, end_long);
}
void add_addr_range_ipv4(unsigned long start_long, unsigned long end_long)
{
/* check if generator limit is exceeded */ /* check if generator limit is exceeded */
if (end_long > start_long + MAX_GENERATE) { if (end_long > start_long + MAX_GENERATE) {
fprintf(stderr, "%s: -g parameter generates too many addresses\n", prog); fprintf(stderr, "%s: -g parameter generates too many addresses\n", prog);
@ -3013,7 +3014,8 @@ void usage(int is_error)
fprintf(out, " -B, --backoff=N set exponential backoff factor to N (default: 1.5)\n"); fprintf(out, " -B, --backoff=N set exponential backoff factor to N (default: 1.5)\n");
fprintf(out, " -c, --count=N count mode: send N pings to each target and report stats\n"); fprintf(out, " -c, --count=N count mode: send N pings to each target and report stats\n");
fprintf(out, " -f, --file=FILE read list of targets from a file ( - means stdin)\n"); fprintf(out, " -f, --file=FILE read list of targets from a file ( - means stdin)\n");
fprintf(out, " -g, --generate generate target list (only if no -f specified)\n"); fprintf(out, " -g, --generate generate target list (only if no -f specified),\n");
fprintf(out, " limited to at most %d targets\n", MAX_GENERATE+1);
fprintf(out, " (give start and end IP in the target list, or a CIDR address)\n"); fprintf(out, " (give start and end IP in the target list, or a CIDR address)\n");
fprintf(out, " (ex. %s -g 192.168.1.0 192.168.1.255 or %s -g 192.168.1.0/24)\n", prog, prog); fprintf(out, " (ex. %s -g 192.168.1.0 192.168.1.255 or %s -g 192.168.1.0/24)\n", prog, prog);
fprintf(out, " -H, --ttl=N set the IP TTL value (Time To Live hops)\n"); fprintf(out, " -H, --ttl=N set the IP TTL value (Time To Live hops)\n");

Loading…
Cancel
Save