mirror of
https://github.com/firehol/firehol.git
synced 2024-06-30 19:02:21 +00:00
added asynchronous DNS resolver - now it needs to be build with -lpthread
This commit is contained in:
parent
2f3a825dda
commit
d590fef00c
405
sbin/iprange.c
405
sbin/iprange.c
@ -14,7 +14,7 @@
|
||||
* comment by Costa Tsaousis:
|
||||
* An excellent work by Gabriel Somlo for loading and merging CIDRs.
|
||||
* I have built all the features this tool provides on top of the
|
||||
* (still) almost untouched original source.
|
||||
* original work of Gabriel.
|
||||
*
|
||||
* License
|
||||
*
|
||||
@ -34,10 +34,7 @@
|
||||
* See the file COPYING for details.
|
||||
*
|
||||
* To compile:
|
||||
* on Linux:
|
||||
* gcc -o iprange iprange.c -O2 -Wall
|
||||
* on Solaris 8, Studio 8 CC:
|
||||
* cc -xO5 -xarch=v8plusa -xdepend iprange.c -o iprange -lnsl -lresolv
|
||||
* gcc -o iprange iprange.c -O2 -Wall -lpthread
|
||||
*
|
||||
* CHANGELOG:
|
||||
* 2003 Gabriel L. Somlo, the original author of iprange.c core
|
||||
@ -66,11 +63,11 @@
|
||||
* - better error handling when parsing input files
|
||||
* - optimized printing using internal ip2str() implementation
|
||||
* - added DNS resolution of hostnames
|
||||
* 2015-11-05 Costa Tsaousis (costa@tsaousis.gr)
|
||||
* - added threaded DNS resolution of hostnames
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -81,6 +78,8 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// the maximum line element to read in input files
|
||||
// normally the elements are IP, IP/MASK, HOSTNAME
|
||||
@ -244,6 +243,16 @@ static inline void print_addr(in_addr_t addr, int prefix)
|
||||
static inline int split_range(in_addr_t addr, int prefix, in_addr_t lo, in_addr_t hi)
|
||||
{
|
||||
|
||||
if(unlikely(lo > hi)) {
|
||||
// it should never happen
|
||||
// give a log for the user to see
|
||||
fprintf(stderr, "%s: WARNING: invalid range reversed start=%s", PROG, ip2str(lo));
|
||||
fprintf(stderr, " end=%s\n", ip2str(hi));
|
||||
in_addr_t t = hi;
|
||||
hi = lo;
|
||||
lo = t;
|
||||
}
|
||||
|
||||
in_addr_t bc, lower_half, upper_half;
|
||||
|
||||
if (unlikely((prefix < 0) || (prefix > 32))) {
|
||||
@ -371,6 +380,16 @@ int compar_netaddr(const void *p1, const void *p2)
|
||||
static inline void print_addr_range(in_addr_t lo, in_addr_t hi)
|
||||
{
|
||||
|
||||
if(unlikely(lo > hi)) {
|
||||
// it should never happen
|
||||
// give a log for the user to see
|
||||
fprintf(stderr, "%s: WARNING: invalid range reversed start=%s", PROG, ip2str(lo));
|
||||
fprintf(stderr, " end=%s\n", ip2str(hi));
|
||||
in_addr_t t = hi;
|
||||
hi = lo;
|
||||
lo = t;
|
||||
}
|
||||
|
||||
if (unlikely(lo != hi)) {
|
||||
printf("%s%s-", print_prefix_nets, ip2str(lo));
|
||||
printf("%s%s\n", ip2str(hi), print_suffix_nets);
|
||||
@ -886,6 +905,8 @@ static inline ipset *ipset_exclude(ipset *ips1, ipset *ips2) {
|
||||
#define LINE_HAS_1_HOSTNAME 3
|
||||
|
||||
static inline int parse_hostname(char *line, int lineid, char *ipstr, char *ipstr2, int len) {
|
||||
if(ipstr2) { ; }
|
||||
|
||||
char *s = line;
|
||||
|
||||
// skip all spaces
|
||||
@ -1128,172 +1149,253 @@ void ipset_save_binary_v10(ipset *ips) {
|
||||
* hostname resolution
|
||||
*/
|
||||
|
||||
#ifdef ASYNC_RESOLVER
|
||||
|
||||
struct dnsreq {
|
||||
struct gaicb req; // has to be the first member
|
||||
|
||||
char host[MAX_INPUT_ELEMENT + 1];
|
||||
|
||||
struct dnsreq *prev;
|
||||
typedef struct dnsreq {
|
||||
char *hostname;
|
||||
struct dnsreq *next;
|
||||
} *dnsreqs = NULL;
|
||||
} DNSREQ;
|
||||
|
||||
int dns_max = 50;
|
||||
int dns_cur = 0;
|
||||
typedef struct dnsrep {
|
||||
in_addr_t ip;
|
||||
struct dnsrep *next;
|
||||
} DNSREP;
|
||||
|
||||
int dns_process_results(ipset *ips)
|
||||
DNSREQ *dns_requests = NULL;
|
||||
DNSREP *dns_replies = NULL;
|
||||
int dns_threads = 0;
|
||||
int dns_threads_max = 5;
|
||||
unsigned long dns_requests_pending = 0;
|
||||
unsigned long dns_requests_made = 0;
|
||||
unsigned long dns_requests_finished = 0;
|
||||
unsigned long dns_replies_found = 0;
|
||||
unsigned long dns_replies_failed = 0;
|
||||
|
||||
pthread_mutex_t dns_mut = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t dns_cond = PTHREAD_COND_INITIALIZER;
|
||||
pthread_rwlock_t dns_requests_rwlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
pthread_rwlock_t dns_replies_rwlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
void dns_lock_requests(void) { pthread_rwlock_wrlock(&dns_requests_rwlock); }
|
||||
void dns_unlock_requests(void) { pthread_rwlock_unlock(&dns_requests_rwlock); }
|
||||
void dns_lock_replies(void) { pthread_rwlock_wrlock(&dns_replies_rwlock); }
|
||||
void dns_unlock_replies(void) { pthread_rwlock_unlock(&dns_replies_rwlock); }
|
||||
|
||||
void *dns_thread_resolve(void *ptr);
|
||||
|
||||
// to be called by the main thread
|
||||
// to add a new DNS resolution request
|
||||
void dns_request_add(DNSREQ *d)
|
||||
{
|
||||
if(!dns_cur) return 0;
|
||||
dns_lock_requests();
|
||||
d->next = dns_requests;
|
||||
dns_requests = d;
|
||||
dns_requests_pending++;
|
||||
dns_requests_made++;
|
||||
dns_unlock_requests();
|
||||
|
||||
struct dnsreq *d;
|
||||
int ret;
|
||||
if(dns_requests && (dns_requests->next || dns_threads == 0) && dns_threads < dns_threads_max) {
|
||||
//if(unlikely(debug))
|
||||
// fprintf(stderr, "%s: Creating new DNS thread\n", PROG);
|
||||
|
||||
for(d = dnsreqs; d ; d = d->next) {
|
||||
ret = gai_error(&d->req);
|
||||
if(ret) continue;
|
||||
// start a new thread
|
||||
pthread_t thread;
|
||||
|
||||
if(unlikely(debug))
|
||||
fprintf(stderr, "%s: Request for '%s' completed.\n", PROG, d->req.ar_name);
|
||||
|
||||
struct addrinfo *rp;
|
||||
for (rp = d->req.ar_result; rp != NULL; rp = rp->ai_next) {
|
||||
char host[MAX_INPUT_ELEMENT + 1];
|
||||
|
||||
int r = getnameinfo(rp->ai_addr, rp->ai_addrlen, host, MAX_INPUT_ELEMENT, NULL, 0, NI_NUMERICHOST);
|
||||
if(r != 0) {
|
||||
fprintf(stderr, "%s: Cannot find the IP of hostname '%s' found in file %s. Reason: %s\n", PROG, d->req.ar_name, ips->filename, gai_strerror(r));
|
||||
continue;
|
||||
if(pthread_create(&thread, NULL, dns_thread_resolve, NULL)) {
|
||||
fprintf(stderr, "%s: Cannot create DNS thread.\n", PROG);
|
||||
return;
|
||||
}
|
||||
else if(pthread_detach(thread)) {
|
||||
fprintf(stderr, "%s: Cannot detach DNS thread.\n", PROG);
|
||||
return;
|
||||
}
|
||||
|
||||
if(unlikely(!ipset_add_ipstr(ips, host)))
|
||||
fprintf(stderr, "%s: Cannot add the IP '%s' of hostname '%s' found in file %s. Reason: %s\n", PROG, host, d->req.ar_name, ips->filename, gai_strerror(r));
|
||||
dns_threads++;
|
||||
}
|
||||
|
||||
if(d->next) d->next->prev = d->prev;
|
||||
if(d->prev) d->prev->next = d->next;
|
||||
if(dnsreqs == d) {
|
||||
if(d->prev) dnsreqs = d->prev;
|
||||
else dnsreqs = d->next;
|
||||
pthread_mutex_lock(&dns_mut);
|
||||
pthread_cond_signal(&dns_cond);
|
||||
pthread_mutex_unlock(&dns_mut);
|
||||
}
|
||||
|
||||
// to be called by a worker thread
|
||||
// to let the main thread it has completed a DNS resolution
|
||||
void dns_request_done(DNSREQ *d, int added)
|
||||
{
|
||||
dns_lock_requests();
|
||||
dns_requests_pending--;
|
||||
dns_requests_finished++;
|
||||
|
||||
if(!added) dns_replies_failed++;
|
||||
else dns_replies_found += added;
|
||||
|
||||
dns_unlock_requests();
|
||||
|
||||
free(d->hostname);
|
||||
free(d);
|
||||
d = dnsreqs;
|
||||
dns_cur--;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dns_wait_request(ipset *ips)
|
||||
// to be called by a worker thread
|
||||
// to get a resolution request from the requests queue
|
||||
DNSREQ *dns_request_get(void)
|
||||
{
|
||||
if(dns_process_results(ips)) return 0;
|
||||
DNSREQ *ret = NULL;
|
||||
|
||||
if(!dns_cur) return 0;
|
||||
//if(unlikely(debug))
|
||||
// fprintf(stderr, "%s: THREAD waiting for DNS REQUEST\n", PROG);
|
||||
|
||||
struct gaicb const *wait_reqs[dns_cur];
|
||||
struct dnsreq *d;
|
||||
|
||||
int nreqs = 0;
|
||||
for(d = dnsreqs, nreqs = 0; d ; d = d->next) {
|
||||
wait_reqs[nreqs++] = &d->req;
|
||||
while(!ret) {
|
||||
if(dns_requests) {
|
||||
dns_lock_requests();
|
||||
if(dns_requests) {
|
||||
ret = dns_requests;
|
||||
dns_requests = dns_requests->next;
|
||||
ret->next = NULL;
|
||||
}
|
||||
dns_unlock_requests();
|
||||
if(ret) return ret;
|
||||
}
|
||||
|
||||
int ret = gai_suspend(wait_reqs, nreqs, NULL);
|
||||
if(ret) {
|
||||
free(d);
|
||||
fprintf(stderr, "%s: Cannot wait for DNS resolutions. Reason: %s\n", PROG, gai_strerror(ret));
|
||||
return 1;
|
||||
pthread_mutex_lock(&dns_mut);
|
||||
while(!dns_requests)
|
||||
pthread_cond_wait(&dns_cond, &dns_mut);
|
||||
pthread_mutex_unlock(&dns_mut);
|
||||
}
|
||||
|
||||
if(dns_process_results(ips)) return 0;
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dns_wait_all(ipset *ips)
|
||||
void *dns_thread_resolve(void *ptr)
|
||||
{
|
||||
if(dns_cur)
|
||||
dns_wait_request(ips);
|
||||
}
|
||||
if(ptr) { ; }
|
||||
|
||||
int dns_add_request(ipset *ips, char *host)
|
||||
{
|
||||
while(dns_cur >= dns_max) {
|
||||
if(unlikely(debug))
|
||||
fprintf(stderr, "%s: %d DNS requests queued. Waiting for some of them to complete.\n", PROG, dns_cur);
|
||||
//if(unlikely(debug))
|
||||
// fprintf(stderr, "%s: THREAD created\n", PROG);
|
||||
|
||||
dns_wait_request(ips);
|
||||
}
|
||||
DNSREQ *d;
|
||||
while((d = dns_request_get())) {
|
||||
int added = 0;
|
||||
|
||||
struct dnsreq *d = calloc(1, sizeof(struct dnsreq));
|
||||
if(!d) {
|
||||
fprintf(stderr, "%s: out of memory.\n", PROG);
|
||||
return 1;
|
||||
}
|
||||
//if(unlikely(debug))
|
||||
// fprintf(stderr, "%s: THREAD resolving DNS REQUEST for '%s'\n", PROG, d->hostname);
|
||||
|
||||
strncpy(d->host, host, MAX_INPUT_ELEMENT);
|
||||
d->host[MAX_INPUT_ELEMENT] = '\0';
|
||||
|
||||
d->req.ar_name = d->host;
|
||||
|
||||
struct gaicb *reqs[1];
|
||||
reqs[0] = &d->req;
|
||||
|
||||
int ret = getaddrinfo_a(GAI_NOWAIT, reqs, 1, NULL);
|
||||
if(ret) {
|
||||
free(d);
|
||||
fprintf(stderr, "%s: Cannot request DNS resolutions for hostname '%s'. Reason: %s\n", PROG, host, gai_strerror(ret));
|
||||
return 1;
|
||||
}
|
||||
else if(unlikely(debug))
|
||||
fprintf(stderr, "%s: Queued DNS request No %d, for '%s'.\n", PROG, dns_cur + 1, host);
|
||||
|
||||
d->next = dnsreqs;
|
||||
if(d->next) d->next->prev = d;
|
||||
dnsreqs = d;
|
||||
dns_cur++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // ! ASYNC_RESOLVER
|
||||
|
||||
int dns_add_request(ipset *ips, char *hostname)
|
||||
{
|
||||
int r;
|
||||
struct addrinfo *result, *rp, hints;
|
||||
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_protocol = 0;
|
||||
|
||||
r = getaddrinfo(hostname, "80", &hints, &result);
|
||||
r = getaddrinfo(d->hostname, "80", &hints, &result);
|
||||
if(r != 0) {
|
||||
fprintf(stderr, "%s: Cannot resolve hostname '%s' found in file %s. Reason: %s\n", PROG, hostname, ips->filename, gai_strerror(r));
|
||||
return 1;
|
||||
fprintf(stderr, "%s: DNS: '%s' failed: %s\n", PROG, d->hostname, gai_strerror(r));
|
||||
dns_request_done(d, added);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (rp = result; rp != NULL; rp = rp->ai_next) {
|
||||
char host[MAX_INPUT_ELEMENT + 1];
|
||||
char host[MAX_INPUT_ELEMENT + 1] = "";
|
||||
r = getnameinfo(rp->ai_addr, rp->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);
|
||||
if (r != 0) {
|
||||
fprintf(stderr, "%s: Cannot find the IP of hostname '%s' found in file %s. Reason: %s\n", PROG, hostname, ips->filename, gai_strerror(r));
|
||||
return 1;
|
||||
fprintf(stderr, "%s: DNS: '%s' failed: %s\n", PROG, d->hostname, gai_strerror(r));
|
||||
continue;
|
||||
}
|
||||
|
||||
if(unlikely(!ipset_add_ipstr(ips, host)))
|
||||
fprintf(stderr, "%s: Cannot add the IP '%s' of hostname '%s' found in file %s. Reason: %s\n", PROG, host, hostname, ips->filename, gai_strerror(r));
|
||||
int err = 0;
|
||||
network_addr_t net = str_to_netaddr(host, &err);
|
||||
if(err) {
|
||||
fprintf(stderr, "%s: DNS: '%s' cannot parse the IP '%s': %s\n", PROG, d->hostname, host, gai_strerror(r));
|
||||
continue;
|
||||
}
|
||||
|
||||
DNSREP *p = malloc(sizeof(DNSREP));
|
||||
if(!p) {
|
||||
fprintf(stderr, "%s: DNS: out of memory while resolving host '%s'\n", PROG, d->hostname);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(unlikely(debug))
|
||||
fprintf(stderr, "%s: DNS: '%s' = %s\n", PROG, d->hostname, ip2str(net.addr));
|
||||
|
||||
p->ip = net.addr;
|
||||
dns_lock_replies();
|
||||
p->next = dns_replies;
|
||||
dns_replies = p;
|
||||
added++;
|
||||
dns_unlock_replies();
|
||||
}
|
||||
|
||||
freeaddrinfo(result);
|
||||
return 0;
|
||||
dns_request_done(d, added);
|
||||
}
|
||||
|
||||
void dns_wait_all(ipset *ips)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void dns_process_replies(ipset *ips)
|
||||
{
|
||||
;
|
||||
if(!dns_replies) return;
|
||||
|
||||
dns_lock_replies();
|
||||
while(dns_replies) {
|
||||
//if(unlikely(debug))
|
||||
// fprintf(stderr, "%s: Got DNS REPLY '%s'\n", PROG, ip2str(dns_replies->ip));
|
||||
|
||||
ipset_add(ips, dns_replies->ip, dns_replies->ip);
|
||||
|
||||
DNSREP *p = dns_replies->next;
|
||||
free(dns_replies);
|
||||
dns_replies = p;
|
||||
}
|
||||
dns_unlock_replies();
|
||||
}
|
||||
|
||||
#endif // ! ASYNC_RESOLVER
|
||||
void dns_request(ipset *ips, char *hostname)
|
||||
{
|
||||
dns_process_replies(ips);
|
||||
|
||||
//if(unlikely(debug))
|
||||
// fprintf(stderr, "%s: Adding DNS REQUEST for '%s'\n", PROG, hostname);
|
||||
|
||||
DNSREQ *d = malloc(sizeof(DNSREQ));
|
||||
if(!d) goto cleanup;
|
||||
|
||||
d->hostname = strdup(hostname);
|
||||
if(!d->hostname) goto cleanup;
|
||||
|
||||
dns_request_add(d);
|
||||
|
||||
return;
|
||||
|
||||
cleanup:
|
||||
fprintf(stderr, "%s: out of memory, while trying to resolv '%s'\n", PROG, hostname);
|
||||
if(d) free(d);
|
||||
}
|
||||
|
||||
void dns_done(ipset *ips)
|
||||
{
|
||||
if(ips) { ; }
|
||||
|
||||
unsigned long dots = 50, shown = 0, should_show = 0;
|
||||
|
||||
while(dns_requests_pending) {
|
||||
if(unlikely(debug))
|
||||
fprintf(stderr, "%s: DNS: waiting %lu DNS resolutions to finish...\n", PROG, dns_requests_pending);
|
||||
else {
|
||||
should_show = dots * dns_requests_finished / dns_requests_made;
|
||||
for(; shown < should_show; shown++) {
|
||||
if(!(shown % 10)) fprintf(stderr, "%lu%%", shown * 100 / dots);
|
||||
else fprintf(stderr, ".");
|
||||
}
|
||||
}
|
||||
|
||||
dns_process_replies(ips);
|
||||
|
||||
if(dns_requests_pending) sleep(1);
|
||||
}
|
||||
|
||||
if(unlikely(debug))
|
||||
fprintf(stderr, "%s: DNS: made %lu DNS requests, failed %lu, IPs got %lu, threads used %d of %d\n", PROG, dns_requests_made, dns_replies_failed, dns_replies_found, dns_threads, dns_threads_max);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ipset_load()
|
||||
@ -1381,10 +1483,10 @@ ipset *ipset_load(const char *filename) {
|
||||
|
||||
case LINE_HAS_1_HOSTNAME:
|
||||
if(unlikely(debug))
|
||||
fprintf(stderr, "%s: requesting DNS resolution for hostname '%s' from line %d of file %s.\n", PROG, ipstr, lineid, ips->filename);
|
||||
fprintf(stderr, "%s: DNS resolution for hostname '%s' from line %d of file %s.\n", PROG, ipstr, lineid, ips->filename);
|
||||
|
||||
// resolve_hostname(ips, ipstr);
|
||||
dns_add_request(ips, ipstr);
|
||||
dns_request(ips, ipstr);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1396,7 +1498,7 @@ ipset *ipset_load(const char *filename) {
|
||||
|
||||
if(likely(fp != stdin)) fclose(fp);
|
||||
|
||||
dns_wait_all(ips);
|
||||
dns_done(ips);
|
||||
|
||||
if(unlikely(!ips)) return NULL;
|
||||
|
||||
@ -1547,22 +1649,36 @@ void ipset_print(ipset *ips, int print) {
|
||||
int i, n = ips->entries;
|
||||
unsigned long int total = 0;
|
||||
|
||||
if(unlikely(debug)) fprintf(stderr, "%s: Printing %s having %lu entries, %lu unique IPs\n", PROG, ips->filename, ips->entries, ips->unique_ips);
|
||||
|
||||
switch(print) {
|
||||
case PRINT_CIDR:
|
||||
// reset the prefix counters
|
||||
for(i = 0; i <= 32; i++)
|
||||
prefix_counters[i] = 0;
|
||||
|
||||
if(unlikely(debug)) fprintf(stderr, "%s: Printing %s\n", PROG, ips->filename);
|
||||
|
||||
switch(print) {
|
||||
case PRINT_CIDR:
|
||||
n = ips->entries;
|
||||
for(i = 0; i < n ;i++) {
|
||||
total += split_range(0, 0, ips->netaddrs[i].addr, ips->netaddrs[i].broadcast);
|
||||
}
|
||||
break;
|
||||
|
||||
case PRINT_SINGLE_IPS:
|
||||
n = ips->entries;
|
||||
for(i = 0; i < n ;i++) {
|
||||
in_addr_t x, start = ips->netaddrs[i].addr, end = ips->netaddrs[i].broadcast;
|
||||
if(unlikely(start > end)) {
|
||||
fprintf(stderr, "%s: WARNING: invalid range reversed start=%s", PROG, ip2str(start));
|
||||
fprintf(stderr, " end=%s\n", ip2str(end));
|
||||
x = end;
|
||||
end = start;
|
||||
start = x;
|
||||
}
|
||||
if(unlikely(end - start > (256 * 256 * 256))) {
|
||||
fprintf(stderr, "%s: too big range eliminated start=%s", PROG, ip2str(start));
|
||||
fprintf(stderr, " end=%s gives %lu IPs\n", ip2str(end), (unsigned long)(end - start));
|
||||
continue;
|
||||
}
|
||||
for( x = start ; x >= start && x <= end ; x++ ) {
|
||||
print_addr_range(x, x);
|
||||
total++;
|
||||
@ -1571,6 +1687,7 @@ void ipset_print(ipset *ips, int print) {
|
||||
break;
|
||||
|
||||
default:
|
||||
n = ips->entries;
|
||||
for(i = 0; i < n ;i++) {
|
||||
print_addr_range(ips->netaddrs[i].addr, ips->netaddrs[i].broadcast);
|
||||
total++;
|
||||
@ -1761,9 +1878,10 @@ void usage(const char *me) {
|
||||
" --complement\n"
|
||||
" --complement-next\n"
|
||||
" > COMPLEMENT mode\n"
|
||||
" 1. union all files before this parameter (A set)\n"
|
||||
" here is how it works:\n"
|
||||
" 1. union all files before this parameter (ipset A)\n"
|
||||
" 2. remove all IPs found in the files after this\n"
|
||||
" parameter, from the set A\n"
|
||||
" parameter, from ipset A\n"
|
||||
" the resulting set is sorted\n"
|
||||
"\n"
|
||||
" --ipset-reduce PERCENT\n"
|
||||
@ -1865,6 +1983,7 @@ void usage(const char *me) {
|
||||
" prefix 32 is always enabled\n"
|
||||
" warning: misuse of this parameter can create a large\n"
|
||||
" number of entries in the generated set\n"
|
||||
"\n"
|
||||
" --print-ranges\n"
|
||||
" -j\n"
|
||||
" print IP ranges (A.A.A.A-B.B.B.B)\n"
|
||||
@ -1880,6 +1999,9 @@ void usage(const char *me) {
|
||||
"\n"
|
||||
" --print-binary\n"
|
||||
" print binary data\n"
|
||||
" this is the fastest way to print a large ipset\n"
|
||||
" the result can be read by iprange on the same\n"
|
||||
" architecture (no conversion of endianess)\n"
|
||||
"\n"
|
||||
" --print-prefix STRING\n"
|
||||
" print STRING before each IP, range or CIDR\n"
|
||||
@ -1921,6 +2043,15 @@ void usage(const char *me) {
|
||||
"\n"
|
||||
"\n"
|
||||
" --------------------------------------------------------------\n"
|
||||
" OPTIONS THAT AFFECT DNS RESOLUTION\n"
|
||||
"\n"
|
||||
" --dns-threads NUMBER\n"
|
||||
" the number of parallel DNS queries to execute\n"
|
||||
" when the input files contain hostnames\n"
|
||||
" the default is %d\n"
|
||||
"\n"
|
||||
"\n"
|
||||
" --------------------------------------------------------------\n"
|
||||
" OTHER OPTIONS\n"
|
||||
"\n"
|
||||
" --has-compare\n"
|
||||
@ -1948,7 +2079,7 @@ void usage(const char *me) {
|
||||
"\n"
|
||||
" if no filename is given, stdin is assumed\n"
|
||||
"\n"
|
||||
" files may contain:\n"
|
||||
" files may contain any or all of the following:\n"
|
||||
" - comments starting with # or ;\n"
|
||||
" - one IP per line (without mask)\n"
|
||||
" - a CIDR per line (A.A.A.A/B)\n"
|
||||
@ -1959,11 +2090,15 @@ void usage(const char *me) {
|
||||
" (this is affected by --dont-fix-network)\n"
|
||||
" - CIDRs can be given in either prefix or netmask\n"
|
||||
" format in all cases (including ranges)\n"
|
||||
" - one hostname per line, to be resolved with DNS\n"
|
||||
" (if the IP resolves to multiple IPs, all of them\n"
|
||||
" will be added to the ipset)\n"
|
||||
" hostnames cannot be given as ranges\n"
|
||||
" - spaces and empty lines are ignored\n"
|
||||
"\n"
|
||||
" any number of files can be given\n"
|
||||
"\n"
|
||||
, me);
|
||||
, me, dns_threads_max);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -2159,6 +2294,10 @@ int main(int argc, char **argv) {
|
||||
else if(!strcmp(argv[i], "--dont-fix-network")) {
|
||||
cidr_use_network = 0;
|
||||
}
|
||||
else if(i+1 < argc && !strcmp(argv[i], "--dns-threads")) {
|
||||
int dns_threads_max = atoi(argv[++i]);
|
||||
if(dns_threads_max < 1) dns_threads_max = 1;
|
||||
}
|
||||
else if(!strcmp(argv[i], "--has-compare")
|
||||
|| !strcmp(argv[i], "--has-reduce")) {
|
||||
fprintf(stderr, "yes, compare and reduce is present.\n");
|
||||
|
Loading…
Reference in New Issue
Block a user