From 4e6635a7228d658caf86d2f3b77448623ed38735 Mon Sep 17 00:00:00 2001 From: john Date: Sun, 1 Dec 2019 13:04:41 -0500 Subject: [PATCH] Improved reporting features --- ban2fail.c | 47 +++++++++--------- ban2fail.h | 17 +++---- logEntry.c | 5 +- logEntry.h | 1 - pdns.c | 126 ++----------------------------------------------- pdns.h | 9 +++- util.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++ util.h | 47 ++++++++++++++++++ 8 files changed, 230 insertions(+), 158 deletions(-) diff --git a/ban2fail.c b/ban2fail.c index 346969c..643a080 100644 --- a/ban2fail.c +++ b/ban2fail.c @@ -86,8 +86,8 @@ struct Global G= { .version= { .major= 0, - .minor= 12, - .patch= 5 + .minor= 13, + .patch= 0 }, .bitTuples.flags= GlobalFlagBitTuples @@ -100,10 +100,10 @@ const static struct initInfo S_initInfo_arr[] = { }; static const struct bitTuple BlockBitTuples[]= { - {.name= "BLOCKED", .bit= BLOCKED_FLG}, - {.name= "+WouldBLOCK+", .bit= WOULD_BLOCK_FLG}, - {.name= "-UnjustBLOCK-", .bit= UNJUST_BLOCK_FLG}, - {.name= "Whitelisted", .bit= WHITELIST_FLG}, + {.name= "BLK", .bit= BLOCKED_FLG}, + {.name= "+blk+", .bit= WOULD_BLOCK_FLG}, + {.name= "-blk-", .bit= UNJUST_BLOCK_FLG}, + {.name= "WL", .bit= WHITELIST_FLG}, {/* Terminating member */} }; @@ -201,9 +201,11 @@ main(int argc, char **argv) case 'a': G.flags |= GLB_LIST_ADDR_FLG; if(optarg) { - if(*optarg == '+') + if(*optarg == '+') { G.flags |= GLB_DNS_LOOKUP_FLG; - else + } else if(*optarg == '-') { + G.flags |= GLB_DNS_LOOKUP_FLG|GLB_DNS_FILTER_BAD_FLG; + } else ++errflg; } break; @@ -477,28 +479,29 @@ main(int argc, char **argv) } /* Print out only for list option */ - if(G.flags & GLB_LIST_ADDR_FLG) { + if(G.flags & GLB_LIST_ADDR_FLG && + !(G.flags & GLB_DNS_FILTER_BAD_FLG && e->dns.flags & PDNS_BAD_MASK)) + { - const static char *dns_fmt= "%-15s\t%5u/%-4d offenses %s (%s) %s%s\n", - *fmt= "%-15s\t%5u/%-4d offenses %s (%s)\n"; + const static struct bitTuple dns_flagsArr[]= { + {.name= "~", .bit= PDNS_FWD_FAIL_FLG}, + {.name= "!!", .bit= PDNS_FWD_NONE_FLG}, + {.name= "NXDOMAIN", .bit= PDNS_NXDOMAIN_FLG}, + {.name= "SERVFAIL", .bit= PDNS_SERVFAIL_FLG}, + {} + }; - const char *failStat= ""; - if(e->dns.flags & PDNS_FWD_FAIL_FLG) - failStat= " ~"; - if(e->dns.flags & PDNS_FWD_NONE_FLG) - failStat= " *"; - if(e->dns.flags & PDNS_FWD_MISMATCH_FLG) - failStat= " !"; + const static char *dns_fmt= "%-15s\t%5u/%-4d offenses %s [%s] %s %s\n", + *fmt= "%-15s\t%5u/%-4d offenses %s [%s]\n"; - ez_fprintf(G.listing_fh, e->dns.name ? dns_fmt : fmt + ez_fprintf(G.listing_fh, e->dns.flags ? dns_fmt : fmt , e->addr , e->count , nAllowed , e->cntry[0] ? e->cntry : "--" , bits2str(flags, BlockBitTuples) - , e->dns.name - , failStat - , e->dns.getaddrinfo_rtn + , e->dns.name ? e->dns.name : "" + , bits2str(e->dns.flags, dns_flagsArr) ); } diff --git a/ban2fail.h b/ban2fail.h index 7fe4df1..db5e094 100644 --- a/ban2fail.h +++ b/ban2fail.h @@ -41,7 +41,7 @@ /* How long to wait for reverse DNS lookups before bailing out */ #ifdef DEBUG -# define DFLT_DNS_PAUSE_SEC 60 +# define DFLT_DNS_PAUSE_SEC 10 #else # define DFLT_DNS_PAUSE_SEC 60 #endif @@ -59,13 +59,14 @@ /* Singleton static object with global visibility */ extern struct Global { enum { - GLB_VERBOSE_FLG =1<<0, - GLB_LIST_ADDR_FLG =1<<1, - GLB_LIST_CNTRY_FLG =1<<2, - GLB_DONT_IPTABLE_FLG =1<<3, - GLB_LIST_SUMMARY_FLG =1<<4, - GLB_PRINT_LOGFILE_NAMES_FLG =1<<5, - GLB_DNS_LOOKUP_FLG =1<<6, + GLB_VERBOSE_FLG =1<<0, + GLB_LIST_ADDR_FLG =1<<1, + GLB_LIST_CNTRY_FLG =1<<2, + GLB_DONT_IPTABLE_FLG =1<<3, + GLB_LIST_SUMMARY_FLG =1<<4, + GLB_PRINT_LOGFILE_NAMES_FLG=1<<5, + GLB_DNS_LOOKUP_FLG =1<<6, + GLB_DNS_FILTER_BAD_FLG =1<<7, GLB_LONG_LISTING_FLG = GLB_LIST_CNTRY_FLG|GLB_LIST_ADDR_FLG } flags; diff --git a/logEntry.c b/logEntry.c index f87d554..4fdfd30 100644 --- a/logEntry.c +++ b/logEntry.c @@ -94,11 +94,8 @@ LOGENTRY_destructor(LOGENTRY *self) * Free resources. */ { - /* Sometimes this is assigned a static string */ - if(self->dns.flags & PDNS_REV_DNS_FLG && self->dns.name) - { + if(self->dns.name) free(self->dns.name); - } return self; } diff --git a/logEntry.h b/logEntry.h index 50ff181..07b7604 100644 --- a/logEntry.h +++ b/logEntry.h @@ -36,7 +36,6 @@ typedef struct _LOGENTRY { struct { enum PDNS_flags flags; char *name; - int getaddrinfo_rtn; } dns; } LOGENTRY; diff --git a/pdns.c b/pdns.c index f7d4606..c5eb615 100644 --- a/pdns.c +++ b/pdns.c @@ -55,12 +55,9 @@ struct workerMsg { /*============================================================*/ /*=========== Forward declarations ===========================*/ /*============================================================*/ -static const char* addrinfo2addr(const struct addrinfo *ai); -static int addrinfo_is_match(const struct addrinfo *ai, const char *addr); static int mgr_check_inbox_f(void *data, int signo); static int join_f(void *data, int signo); static unsigned nThreads_joined(void); -static int print_addrinfo(struct addrinfo *ai, FILE *fh); static int shutdown_f(void *data); static void stop_remaining_workers(void); static int timeout_f(void *data); @@ -334,7 +331,7 @@ shutdown_f(void *data) } /*============================================================*/ -/*================= Worker threads ============================*/ +/*================= Worker threads ===========================*/ /*============================================================*/ static void* @@ -380,6 +377,7 @@ worker_check_inbox_f(void *vp_ndx, int signo) */ { int rtn= -1; + /* Our S.workerArr index was passed in as (void*) */ unsigned ndx= (long unsigned)vp_ndx; struct worker *self= S.workerArr + ndx; struct workerMsg msg; @@ -407,13 +405,11 @@ worker_check_inbox_f(void *vp_ndx, int signo) if(!strcmp(msg.e->addr, "50.116.38.131")) { pthread_mutex_lock(&S.prt_mtx); ez_fprintf(stderr, "%s (%s) ----------------------------------\n", msg.e->addr, msg.e->dns.name); - print_addrinfo(res, stderr); + addrinfo_print(res, stderr); fflush(stderr); pthread_mutex_unlock(&S.prt_mtx); } #endif - msg.e->dns.getaddrinfo_rtn= rc; - switch(rc) { case 0: if(!addrinfo_is_match(res, msg.e->addr)) @@ -465,7 +461,7 @@ if(!strcmp(msg.e->addr, "50.116.38.131")) { if(!strcmp(msg.e->addr, "50.116.38.131")) { pthread_mutex_lock(&S.prt_mtx); ez_fprintf(stderr, "%s ----------------------------------\n", msg.e->addr); - print_addrinfo(res, stderr); + addrinfo_print(res, stderr); fflush(stderr); pthread_mutex_unlock(&S.prt_mtx); } @@ -479,12 +475,10 @@ if(!strcmp(msg.e->addr, "50.116.38.131")) { break; case EAI_NONAME: - msg.e->dns.name= "3(NXDOMAIN)"; msg.e->dns.flags |= PDNS_NXDOMAIN_FLG; break; case EAI_AGAIN: - msg.e->dns.name= "2(SERVFAIL)"; msg.e->dns.flags |= PDNS_SERVFAIL_FLG; break; @@ -528,115 +522,3 @@ worker_exit_f(void *vp_ndx, int signo) } -/*============================================================*/ -/*================ Misc. =====================================*/ -/*============================================================*/ -const static struct bitTuple ai_flags_btArr[]= { - {.name= "AI_ADDRCONFIG", .bit= AI_ADDRCONFIG}, - {.name= "AI_ALL", .bit= AI_ALL}, - {.name= "AI_CANONNAME", .bit= AI_CANONNAME}, - {.name= "AI_NUMERICHOST", .bit= AI_NUMERICHOST}, - {.name= "AI_NUMERICSERV", .bit= AI_NUMERICSERV}, - {.name= "AI_PASSIVE", .bit= AI_PASSIVE}, - {.name= "AI_V4MAPPED", .bit= AI_V4MAPPED}, - {} -}; - -const static struct enumTuple ai_family_etArr[]= { - {.name= "AF_INET", .enumVal= AF_INET}, - {.name= "AF_INET6", .enumVal= AF_INET6}, - {.name= "AF_UNSPEC", .enumVal= AF_UNSPEC}, - {} -}; - -const static struct enumTuple ai_socktype_etArr[]= { - {.name= "SOCK_DGRAM", .enumVal= SOCK_DGRAM}, - {.name= "SOCK_RAW", .enumVal= SOCK_RAW}, - {.name= "SOCK_STREAM", .enumVal= SOCK_STREAM}, - {} -}; - -const static struct enumTuple ai_protocol_etArr[]= { - {.name= "IPPROTO_TCP", .enumVal= IPPROTO_TCP}, - {.name= "IPPROTO_UDP", .enumVal= IPPROTO_UDP}, - {} -}; - - -static int -print_addrinfo(struct addrinfo *ai, FILE *fh) -/************************************************************* - * Print a legible rendition of a struct addrinfo. - */ -{ - for(; ai; ai= ai->ai_next) { - const char *addr= addrinfo2addr(ai); - ez_fprintf(fh, -"struct addressinfo {\n" -"\tai_flags= %s\n" -"\tai_family= %s\n" -"\tai_socktype= %s\n" -"\tai_protocol= %s\n" -"\tai_addrlen= %d\n" -"\tai_addr= %s\n" -"\tai_cannonname= %s\n" -"}\n" - , bits2str(ai->ai_flags, ai_flags_btArr) - , enum2str(ai->ai_family, ai_family_etArr) - , enum2str(ai->ai_socktype, ai_socktype_etArr) - , enum2str(ai->ai_protocol, ai_protocol_etArr) - , (int)ai->ai_addrlen - , addr ? addr : "NULL" - , ai->ai_canonname ? ai->ai_canonname : "NULL" - ); - - } - return 0; -} - -static int -addrinfo_is_match(const struct addrinfo *ai, const char *addr) -/*********************************************************************** - * Search all members in linked list for a match. - */ -{ - for(; ai; ai= ai->ai_next) { - const char *this_addr= addrinfo2addr(ai); - if(!strcmp(this_addr, addr)) return 1; - } - return 0; -} - -static const char* -addrinfo2addr(const struct addrinfo *ai) -/*********************************************************************** - * Get address in static string buffer - */ -{ -#define BUF_SZ 43 - const char *rtn= NULL; - if(!ai->ai_addr) goto abort; - - static _Thread_local char buf[BUF_SZ]; - memset(buf, 0, sizeof(buf)); - - switch(ai->ai_family) { - case AF_INET: { - struct sockaddr_in *sin= (struct sockaddr_in*)ai->ai_addr; - rtn= inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)-1); - } break; - - case AF_INET6: { - struct sockaddr_in6 *sin6= (struct sockaddr_in6*)ai->ai_addr; - rtn= inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf)-1); - } break; - - default: - assert(0); - - } - -abort: - return rtn; -} - diff --git a/pdns.h b/pdns.h index 70a341d..f52ede2 100644 --- a/pdns.h +++ b/pdns.h @@ -31,6 +31,7 @@ /* Number of threads to use in parallel */ #define PDNS_MAX_THREADS 200 +/* Size manager's inbox to avoid overflow */ #define PDNS_MGR_INBOX_SZ PDNS_MAX_THREADS*2 #define PDNS_WORKER_INBOX_SZ 1 /* Give worker threads a chance to join */ @@ -44,7 +45,13 @@ enum PDNS_flags { PDNS_FWD_FAIL_FLG= 1<<4, PDNS_FWD_NONE_FLG= 1<<5, PDNS_FWD_MISMATCH_FLG= 1<<6, - PDNS_DONE_MASK= PDNS_SERVFAIL_FLG|PDNS_NXDOMAIN_FLG|PDNS_FWD_DNS_FLG + PDNS_DONE_MASK= PDNS_SERVFAIL_FLG|PDNS_NXDOMAIN_FLG|PDNS_FWD_DNS_FLG, + PDNS_BAD_MASK= PDNS_SERVFAIL_FLG| + PDNS_NXDOMAIN_FLG| + PDNS_FWD_FAIL_FLG| + PDNS_FWD_NONE_FLG| + PDNS_FWD_MISMATCH_FLG + }; #define _GNU_SOURCE diff --git a/util.c b/util.c index a1a9dea..d91943b 100644 --- a/util.c +++ b/util.c @@ -835,3 +835,139 @@ int _ez_rmdir_recursive ( } return rtn; } + +/*============================================================*/ +/*================ struct addrinfo ===========================*/ +/*============================================================*/ + +const static struct bitTuple ai_flags_btArr[]= { + {.name= "AI_ADDRCONFIG", .bit= AI_ADDRCONFIG}, + {.name= "AI_ALL", .bit= AI_ALL}, + {.name= "AI_CANONNAME", .bit= AI_CANONNAME}, + {.name= "AI_NUMERICHOST", .bit= AI_NUMERICHOST}, + {.name= "AI_NUMERICSERV", .bit= AI_NUMERICSERV}, + {.name= "AI_PASSIVE", .bit= AI_PASSIVE}, + {.name= "AI_V4MAPPED", .bit= AI_V4MAPPED}, + {} +}; + +const static struct enumTuple ai_family_etArr[]= { + {.name= "AF_INET", .enumVal= AF_INET}, + {.name= "AF_INET6", .enumVal= AF_INET6}, + {.name= "AF_UNSPEC", .enumVal= AF_UNSPEC}, + {} +}; + +const static struct enumTuple ai_socktype_etArr[]= { + {.name= "SOCK_DGRAM", .enumVal= SOCK_DGRAM}, + {.name= "SOCK_RAW", .enumVal= SOCK_RAW}, + {.name= "SOCK_STREAM", .enumVal= SOCK_STREAM}, + {} +}; + +const static struct enumTuple ai_protocol_etArr[]= { + {.name= "IPPROTO_TCP", .enumVal= IPPROTO_TCP}, + {.name= "IPPROTO_UDP", .enumVal= IPPROTO_UDP}, + {} +}; + + +int +addrinfo_print(struct addrinfo *ai, FILE *fh) +/************************************************************* + * Print a legible rendition of all struct addrinfo in the + * linked-list chain. + * + * ai: pinter to a struct addrinfo + * fh: stream for output + * + * RETURNS: + * 0 for success + * -1 for error + */ +{ + for(; ai; ai= ai->ai_next) { + const char *addr= addrinfo_2_addr(ai); + ez_fprintf(fh, +"struct addressinfo {\n" +"\tai_flags= %s\n" +"\tai_family= %s\n" +"\tai_socktype= %s\n" +"\tai_protocol= %s\n" +"\tai_addrlen= %d\n" +"\tai_addr= %s\n" +"\tai_cannonname= %s\n" +"}\n" + , bits2str(ai->ai_flags, ai_flags_btArr) + , enum2str(ai->ai_family, ai_family_etArr) + , enum2str(ai->ai_socktype, ai_socktype_etArr) + , enum2str(ai->ai_protocol, ai_protocol_etArr) + , (int)ai->ai_addrlen + , addr ? addr : "NULL" + , ai->ai_canonname ? ai->ai_canonname : "NULL" + ); + + } + return 0; +} + +int +addrinfo_is_match(const struct addrinfo *ai, const char *addr) +/*********************************************************************** + * Search all members in addrinfo linked list for a match. + * + * ai: pinter to a struct addrinfo + * addr: NULL terminated numeric address for strcmp() comparison + * + * RETURNS: + * 1 a match was found + * 0 no match was found. + */ +{ + for(; ai; ai= ai->ai_next) { + const char *this_addr= addrinfo_2_addr(ai); + if(!strcmp(this_addr, addr)) return 1; + } + return 0; +} + +const char* +addrinfo_2_addr(const struct addrinfo *ai) +/*********************************************************************** + * Return in a static buffer a sting version of the numeric address found + * in a single addrinfo struct. + * + * ai: pinter to a struct addrinfo + * + * RETURNS: + * NULL for failure + * address of the static buffer containing address in null terminated string form. + */ +{ +#define BUF_SZ 43 + const char *rtn= NULL; + if(!ai->ai_addr) goto abort; + + static _Thread_local char buf[BUF_SZ]; + memset(buf, 0, sizeof(buf)); + + switch(ai->ai_family) { + case AF_INET: { + struct sockaddr_in *sin= (struct sockaddr_in*)ai->ai_addr; + rtn= inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)-1); + } break; + + case AF_INET6: { + struct sockaddr_in6 *sin6= (struct sockaddr_in6*)ai->ai_addr; + rtn= inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf)-1); + } break; + + default: + assert(0); + + } + +abort: + return rtn; +} + diff --git a/util.h b/util.h index 7ebf247..ac0146d 100644 --- a/util.h +++ b/util.h @@ -27,8 +27,12 @@ Common utility routines needed by most c and c++ applications. #ifndef UTIL_H #define UTIL_H +#define _GNU_SOURCE #include +#include #include +#include +#include #include #include #include @@ -361,6 +365,9 @@ int rmdir_recursive(const char *path); /*************************************************************** * recursively remove a directory and all of it's contents. + * + * path: NULL terminated path of directory to be removed. + * * RETURNS: * 0 for success * -1 for error @@ -375,6 +382,46 @@ int _ez_rmdir_recursive ( const char *path ); +int +addrinfo_print(struct addrinfo *ai, FILE *fh); +/************************************************************* + * Print a legible rendition of all struct addrinfo in the + * linked-list chain. + * + * ai: pinter to a struct addrinfo + * fh: stream for output + * + * RETURNS: + * 0 for success + * -1 for error + */ + +int +addrinfo_is_match(const struct addrinfo *ai, const char *addr); +/*********************************************************************** + * Search all members in addrinfo linked list for a match. + * + * ai: pinter to a struct addrinfo + * addr: NULL terminated numeric address for strcmp() comparison + * + * RETURNS: + * 1 a match was found + * 0 no match was found. + */ + +const char* +addrinfo_2_addr(const struct addrinfo *ai); +/*********************************************************************** + * Return in a static buffer a sting version of the numeric address found + * in a single addrinfo struct. + * + * ai: pinter to a struct addrinfo + * + * RETURNS: + * NULL for failure + * address of the static buffer containing address in null terminated string form. + */ + #ifdef __cplusplus } #endif