mirror of
https://github.com/jrbrtsn/ban2fail
synced 2024-06-20 13:58:02 +00:00
Improved reporting features
This commit is contained in:
parent
3a0f2216dc
commit
4e6635a722
47
ban2fail.c
47
ban2fail.c
@ -86,8 +86,8 @@ struct Global G= {
|
|||||||
|
|
||||||
.version= {
|
.version= {
|
||||||
.major= 0,
|
.major= 0,
|
||||||
.minor= 12,
|
.minor= 13,
|
||||||
.patch= 5
|
.patch= 0
|
||||||
},
|
},
|
||||||
|
|
||||||
.bitTuples.flags= GlobalFlagBitTuples
|
.bitTuples.flags= GlobalFlagBitTuples
|
||||||
@ -100,10 +100,10 @@ const static struct initInfo S_initInfo_arr[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct bitTuple BlockBitTuples[]= {
|
static const struct bitTuple BlockBitTuples[]= {
|
||||||
{.name= "BLOCKED", .bit= BLOCKED_FLG},
|
{.name= "BLK", .bit= BLOCKED_FLG},
|
||||||
{.name= "+WouldBLOCK+", .bit= WOULD_BLOCK_FLG},
|
{.name= "+blk+", .bit= WOULD_BLOCK_FLG},
|
||||||
{.name= "-UnjustBLOCK-", .bit= UNJUST_BLOCK_FLG},
|
{.name= "-blk-", .bit= UNJUST_BLOCK_FLG},
|
||||||
{.name= "Whitelisted", .bit= WHITELIST_FLG},
|
{.name= "WL", .bit= WHITELIST_FLG},
|
||||||
{/* Terminating member */}
|
{/* Terminating member */}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -201,9 +201,11 @@ main(int argc, char **argv)
|
|||||||
case 'a':
|
case 'a':
|
||||||
G.flags |= GLB_LIST_ADDR_FLG;
|
G.flags |= GLB_LIST_ADDR_FLG;
|
||||||
if(optarg) {
|
if(optarg) {
|
||||||
if(*optarg == '+')
|
if(*optarg == '+') {
|
||||||
G.flags |= GLB_DNS_LOOKUP_FLG;
|
G.flags |= GLB_DNS_LOOKUP_FLG;
|
||||||
else
|
} else if(*optarg == '-') {
|
||||||
|
G.flags |= GLB_DNS_LOOKUP_FLG|GLB_DNS_FILTER_BAD_FLG;
|
||||||
|
} else
|
||||||
++errflg;
|
++errflg;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -477,28 +479,29 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Print out only for list option */
|
/* 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",
|
const static struct bitTuple dns_flagsArr[]= {
|
||||||
*fmt= "%-15s\t%5u/%-4d offenses %s (%s)\n";
|
{.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= "";
|
const static char *dns_fmt= "%-15s\t%5u/%-4d offenses %s [%s] %s %s\n",
|
||||||
if(e->dns.flags & PDNS_FWD_FAIL_FLG)
|
*fmt= "%-15s\t%5u/%-4d offenses %s [%s]\n";
|
||||||
failStat= " ~";
|
|
||||||
if(e->dns.flags & PDNS_FWD_NONE_FLG)
|
|
||||||
failStat= " *";
|
|
||||||
if(e->dns.flags & PDNS_FWD_MISMATCH_FLG)
|
|
||||||
failStat= " !";
|
|
||||||
|
|
||||||
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->addr
|
||||||
, e->count
|
, e->count
|
||||||
, nAllowed
|
, nAllowed
|
||||||
, e->cntry[0] ? e->cntry : "--"
|
, e->cntry[0] ? e->cntry : "--"
|
||||||
, bits2str(flags, BlockBitTuples)
|
, bits2str(flags, BlockBitTuples)
|
||||||
, e->dns.name
|
, e->dns.name ? e->dns.name : ""
|
||||||
, failStat
|
, bits2str(e->dns.flags, dns_flagsArr)
|
||||||
, e->dns.getaddrinfo_rtn
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
/* How long to wait for reverse DNS lookups before bailing out */
|
/* How long to wait for reverse DNS lookups before bailing out */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# define DFLT_DNS_PAUSE_SEC 60
|
# define DFLT_DNS_PAUSE_SEC 10
|
||||||
#else
|
#else
|
||||||
# define DFLT_DNS_PAUSE_SEC 60
|
# define DFLT_DNS_PAUSE_SEC 60
|
||||||
#endif
|
#endif
|
||||||
@ -64,8 +64,9 @@ extern struct Global {
|
|||||||
GLB_LIST_CNTRY_FLG =1<<2,
|
GLB_LIST_CNTRY_FLG =1<<2,
|
||||||
GLB_DONT_IPTABLE_FLG =1<<3,
|
GLB_DONT_IPTABLE_FLG =1<<3,
|
||||||
GLB_LIST_SUMMARY_FLG =1<<4,
|
GLB_LIST_SUMMARY_FLG =1<<4,
|
||||||
GLB_PRINT_LOGFILE_NAMES_FLG =1<<5,
|
GLB_PRINT_LOGFILE_NAMES_FLG=1<<5,
|
||||||
GLB_DNS_LOOKUP_FLG =1<<6,
|
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
|
GLB_LONG_LISTING_FLG = GLB_LIST_CNTRY_FLG|GLB_LIST_ADDR_FLG
|
||||||
} flags;
|
} flags;
|
||||||
|
|
||||||
|
@ -94,11 +94,8 @@ LOGENTRY_destructor(LOGENTRY *self)
|
|||||||
* Free resources.
|
* Free resources.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Sometimes this is assigned a static string */
|
if(self->dns.name)
|
||||||
if(self->dns.flags & PDNS_REV_DNS_FLG && self->dns.name)
|
|
||||||
{
|
|
||||||
free(self->dns.name);
|
free(self->dns.name);
|
||||||
}
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,6 @@ typedef struct _LOGENTRY {
|
|||||||
struct {
|
struct {
|
||||||
enum PDNS_flags flags;
|
enum PDNS_flags flags;
|
||||||
char *name;
|
char *name;
|
||||||
int getaddrinfo_rtn;
|
|
||||||
} dns;
|
} dns;
|
||||||
|
|
||||||
} LOGENTRY;
|
} LOGENTRY;
|
||||||
|
126
pdns.c
126
pdns.c
@ -55,12 +55,9 @@ struct workerMsg {
|
|||||||
/*============================================================*/
|
/*============================================================*/
|
||||||
/*=========== Forward declarations ===========================*/
|
/*=========== 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 mgr_check_inbox_f(void *data, int signo);
|
||||||
static int join_f(void *data, int signo);
|
static int join_f(void *data, int signo);
|
||||||
static unsigned nThreads_joined(void);
|
static unsigned nThreads_joined(void);
|
||||||
static int print_addrinfo(struct addrinfo *ai, FILE *fh);
|
|
||||||
static int shutdown_f(void *data);
|
static int shutdown_f(void *data);
|
||||||
static void stop_remaining_workers(void);
|
static void stop_remaining_workers(void);
|
||||||
static int timeout_f(void *data);
|
static int timeout_f(void *data);
|
||||||
@ -334,7 +331,7 @@ shutdown_f(void *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*============================================================*/
|
/*============================================================*/
|
||||||
/*================= Worker threads ============================*/
|
/*================= Worker threads ===========================*/
|
||||||
/*============================================================*/
|
/*============================================================*/
|
||||||
|
|
||||||
static void*
|
static void*
|
||||||
@ -380,6 +377,7 @@ worker_check_inbox_f(void *vp_ndx, int signo)
|
|||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int rtn= -1;
|
int rtn= -1;
|
||||||
|
/* Our S.workerArr index was passed in as (void*) */
|
||||||
unsigned ndx= (long unsigned)vp_ndx;
|
unsigned ndx= (long unsigned)vp_ndx;
|
||||||
struct worker *self= S.workerArr + ndx;
|
struct worker *self= S.workerArr + ndx;
|
||||||
struct workerMsg msg;
|
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")) {
|
if(!strcmp(msg.e->addr, "50.116.38.131")) {
|
||||||
pthread_mutex_lock(&S.prt_mtx);
|
pthread_mutex_lock(&S.prt_mtx);
|
||||||
ez_fprintf(stderr, "%s (%s) ----------------------------------\n", msg.e->addr, msg.e->dns.name);
|
ez_fprintf(stderr, "%s (%s) ----------------------------------\n", msg.e->addr, msg.e->dns.name);
|
||||||
print_addrinfo(res, stderr);
|
addrinfo_print(res, stderr);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
pthread_mutex_unlock(&S.prt_mtx);
|
pthread_mutex_unlock(&S.prt_mtx);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
msg.e->dns.getaddrinfo_rtn= rc;
|
|
||||||
|
|
||||||
switch(rc) {
|
switch(rc) {
|
||||||
case 0:
|
case 0:
|
||||||
if(!addrinfo_is_match(res, msg.e->addr))
|
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")) {
|
if(!strcmp(msg.e->addr, "50.116.38.131")) {
|
||||||
pthread_mutex_lock(&S.prt_mtx);
|
pthread_mutex_lock(&S.prt_mtx);
|
||||||
ez_fprintf(stderr, "%s ----------------------------------\n", msg.e->addr);
|
ez_fprintf(stderr, "%s ----------------------------------\n", msg.e->addr);
|
||||||
print_addrinfo(res, stderr);
|
addrinfo_print(res, stderr);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
pthread_mutex_unlock(&S.prt_mtx);
|
pthread_mutex_unlock(&S.prt_mtx);
|
||||||
}
|
}
|
||||||
@ -479,12 +475,10 @@ if(!strcmp(msg.e->addr, "50.116.38.131")) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EAI_NONAME:
|
case EAI_NONAME:
|
||||||
msg.e->dns.name= "3(NXDOMAIN)";
|
|
||||||
msg.e->dns.flags |= PDNS_NXDOMAIN_FLG;
|
msg.e->dns.flags |= PDNS_NXDOMAIN_FLG;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EAI_AGAIN:
|
case EAI_AGAIN:
|
||||||
msg.e->dns.name= "2(SERVFAIL)";
|
|
||||||
msg.e->dns.flags |= PDNS_SERVFAIL_FLG;
|
msg.e->dns.flags |= PDNS_SERVFAIL_FLG;
|
||||||
break;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
9
pdns.h
9
pdns.h
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
/* Number of threads to use in parallel */
|
/* Number of threads to use in parallel */
|
||||||
#define PDNS_MAX_THREADS 200
|
#define PDNS_MAX_THREADS 200
|
||||||
|
/* Size manager's inbox to avoid overflow */
|
||||||
#define PDNS_MGR_INBOX_SZ PDNS_MAX_THREADS*2
|
#define PDNS_MGR_INBOX_SZ PDNS_MAX_THREADS*2
|
||||||
#define PDNS_WORKER_INBOX_SZ 1
|
#define PDNS_WORKER_INBOX_SZ 1
|
||||||
/* Give worker threads a chance to join */
|
/* Give worker threads a chance to join */
|
||||||
@ -44,7 +45,13 @@ enum PDNS_flags {
|
|||||||
PDNS_FWD_FAIL_FLG= 1<<4,
|
PDNS_FWD_FAIL_FLG= 1<<4,
|
||||||
PDNS_FWD_NONE_FLG= 1<<5,
|
PDNS_FWD_NONE_FLG= 1<<5,
|
||||||
PDNS_FWD_MISMATCH_FLG= 1<<6,
|
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
|
#define _GNU_SOURCE
|
||||||
|
136
util.c
136
util.c
@ -835,3 +835,139 @@ int _ez_rmdir_recursive (
|
|||||||
}
|
}
|
||||||
return rtn;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
47
util.h
47
util.h
@ -27,8 +27,12 @@ Common utility routines needed by most c and c++ applications.
|
|||||||
#ifndef UTIL_H
|
#ifndef UTIL_H
|
||||||
#define UTIL_H
|
#define UTIL_H
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <netdb.h>
|
||||||
#include <regex.h>
|
#include <regex.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -361,6 +365,9 @@ int
|
|||||||
rmdir_recursive(const char *path);
|
rmdir_recursive(const char *path);
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
* recursively remove a directory and all of it's contents.
|
* recursively remove a directory and all of it's contents.
|
||||||
|
*
|
||||||
|
* path: NULL terminated path of directory to be removed.
|
||||||
|
*
|
||||||
* RETURNS:
|
* RETURNS:
|
||||||
* 0 for success
|
* 0 for success
|
||||||
* -1 for error
|
* -1 for error
|
||||||
@ -375,6 +382,46 @@ int _ez_rmdir_recursive (
|
|||||||
const char *path
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user