mirror of
https://github.com/jrbrtsn/ban2fail
synced 2024-06-16 11:58:01 +00:00
Create b2f-grep to facilitate add-addr.sh placing cursor for vim
This commit is contained in:
parent
3aa81aac46
commit
20b109af40
16
Jmakefile
16
Jmakefile
@ -2,7 +2,7 @@ baseDir := ~
|
|||||||
libsDir := $(baseDir)/libs
|
libsDir := $(baseDir)/libs
|
||||||
projectName := ban2fail
|
projectName := ban2fail
|
||||||
versions := debug release
|
versions := debug release
|
||||||
cc_exe := ban2fail fsckdns
|
cc_exe := ban2fail b2f-grep
|
||||||
#install_dir := /usr/local/bin
|
#install_dir := /usr/local/bin
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
@ -36,9 +36,21 @@ src := \
|
|||||||
timestamp.c \
|
timestamp.c \
|
||||||
util.c \
|
util.c \
|
||||||
|
|
||||||
libs := z crypto GeoIP pthread db
|
libs += z crypto GeoIP pthread db
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(exe), b2f-grep)
|
||||||
|
src := \
|
||||||
|
ez_libc.c \
|
||||||
|
b2f-grep.c \
|
||||||
|
ptrvec.c \
|
||||||
|
str.c \
|
||||||
|
util.c \
|
||||||
|
|
||||||
|
libs += gmp
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(exe), fsckdns)
|
ifeq ($(exe), fsckdns)
|
||||||
src := \
|
src := \
|
||||||
ez_libc.c \
|
ez_libc.c \
|
||||||
|
24
Makefile
24
Makefile
@ -2,7 +2,7 @@ baseDir := ~
|
|||||||
libsDir := $(baseDir)/libs
|
libsDir := $(baseDir)/libs
|
||||||
projectName := ban2fail
|
projectName := ban2fail
|
||||||
versions := debug release
|
versions := debug release
|
||||||
cc_exe := ban2fail fsckdns
|
cc_exe := ban2fail b2f-grep
|
||||||
#install_dir := /usr/local/bin
|
#install_dir := /usr/local/bin
|
||||||
|
|
||||||
########################################
|
########################################
|
||||||
@ -36,9 +36,21 @@ src := \
|
|||||||
timestamp.c \
|
timestamp.c \
|
||||||
util.c \
|
util.c \
|
||||||
|
|
||||||
libs := z crypto GeoIP pthread db
|
libs += z crypto GeoIP pthread db
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(exe), b2f-grep)
|
||||||
|
src := \
|
||||||
|
ez_libc.c \
|
||||||
|
b2f-grep.c \
|
||||||
|
ptrvec.c \
|
||||||
|
str.c \
|
||||||
|
util.c \
|
||||||
|
|
||||||
|
libs += gmp
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(exe), fsckdns)
|
ifeq ($(exe), fsckdns)
|
||||||
src := \
|
src := \
|
||||||
ez_libc.c \
|
ez_libc.c \
|
||||||
@ -70,15 +82,15 @@ ifndef version
|
|||||||
all : debug release
|
all : debug release
|
||||||
debug :
|
debug :
|
||||||
@$(MAKE) version=debug exe=ban2fail mainType=CC --no-builtin-rules -f $(makefile) --no-print-directory
|
@$(MAKE) version=debug exe=ban2fail mainType=CC --no-builtin-rules -f $(makefile) --no-print-directory
|
||||||
@$(MAKE) version=debug exe=fsckdns mainType=CC --no-builtin-rules -f $(makefile) --no-print-directory
|
@$(MAKE) version=debug exe=b2f-grep mainType=CC --no-builtin-rules -f $(makefile) --no-print-directory
|
||||||
release :
|
release :
|
||||||
@$(MAKE) version=release exe=ban2fail mainType=CC --no-builtin-rules -f $(makefile) --no-print-directory
|
@$(MAKE) version=release exe=ban2fail mainType=CC --no-builtin-rules -f $(makefile) --no-print-directory
|
||||||
@$(MAKE) version=release exe=fsckdns mainType=CC --no-builtin-rules -f $(makefile) --no-print-directory
|
@$(MAKE) version=release exe=b2f-grep mainType=CC --no-builtin-rules -f $(makefile) --no-print-directory
|
||||||
install : release
|
install : release
|
||||||
@strip release/ban2fail
|
@strip release/ban2fail
|
||||||
@[ $(install_dir)_foo = _foo ] || cp release/ban2fail $(install_dir)/
|
@[ $(install_dir)_foo = _foo ] || cp release/ban2fail $(install_dir)/
|
||||||
@strip release/fsckdns
|
@strip release/b2f-grep
|
||||||
@[ $(install_dir)_foo = _foo ] || cp release/fsckdns $(install_dir)/
|
@[ $(install_dir)_foo = _foo ] || cp release/b2f-grep $(install_dir)/
|
||||||
@[ -e install.sh ] && INSTALLDIR=$(install_dir) INSTALLTYPE=$(install_type) sudo ./install.sh
|
@[ -e install.sh ] && INSTALLDIR=$(install_dir) INSTALLTYPE=$(install_type) sudo ./install.sh
|
||||||
uninstall :
|
uninstall :
|
||||||
clean :
|
clean :
|
||||||
|
63
add-addrs.sh
Executable file
63
add-addrs.sh
Executable file
@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Add new addresses to ban2fail
|
||||||
|
|
||||||
|
set -efu
|
||||||
|
|
||||||
|
WD=~/projects/ban2fail
|
||||||
|
PROTO_CFG=$WD/real-ban2fail.cfg
|
||||||
|
ACTUAL_CFG=/etc/ban2fail/ban2fail.cfg
|
||||||
|
BAN2FAIL=/usr/local/bin/ban2fail
|
||||||
|
B2F_GREP=/usr/local/bin/b2f-grep
|
||||||
|
MD5SUM=
|
||||||
|
NEW_MD5SUM=
|
||||||
|
JUNK=
|
||||||
|
SEP=
|
||||||
|
IP=
|
||||||
|
PRTL_IP=
|
||||||
|
LINE=
|
||||||
|
|
||||||
|
trap "echo && $BAN2FAIL -s" 0
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
|
||||||
|
read MD5SUM JUNK < <(md5sum $ACTUAL_CFG)
|
||||||
|
|
||||||
|
read -p 'Next address(es) please? ' IP
|
||||||
|
|
||||||
|
# Only consider editing PROTO_CFG is IP is not empty.
|
||||||
|
if [[ -n "$IP" ]]; then
|
||||||
|
|
||||||
|
$BAN2FAIL $IP
|
||||||
|
|
||||||
|
echo '--------------------------------'
|
||||||
|
|
||||||
|
read -p 'Edit config file? '
|
||||||
|
case ${REPLY:0:1} in
|
||||||
|
y|Y) true;;
|
||||||
|
*) continue;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Edit all addresses we got from b2f-grep
|
||||||
|
for LINE in $(2>/dev/null $B2F_GREP $IP <$PROTO_CFG); do
|
||||||
|
$EDITOR +${LINE} $PROTO_CFG
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# See if PROTO_CFG was changed.
|
||||||
|
read NEW_MD5SUM JUNK < <(md5sum $PROTO_CFG)
|
||||||
|
[[ $NEW_MD5SUM == $MD5SUM ]] && continue
|
||||||
|
|
||||||
|
|
||||||
|
$BAN2FAIL -t $PROTO_CFG
|
||||||
|
read -p 'Make this permanent? '
|
||||||
|
case ${REPLY:0:1} in
|
||||||
|
y|Y) true;;
|
||||||
|
*) continue;;
|
||||||
|
esac
|
||||||
|
sudo /bin/cp $PROTO_CFG $ACTUAL_CFG
|
||||||
|
$BAN2FAIL -s
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
|
517
b2f-grep.c
Normal file
517
b2f-grep.c
Normal file
@ -0,0 +1,517 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <byteswap.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <gmp.h>
|
||||||
|
|
||||||
|
#include "ez_libc.h"
|
||||||
|
#include "ptrvec.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/*==================================================================*/
|
||||||
|
/*=================== Support structs ==============================*/
|
||||||
|
/*==================================================================*/
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* signed 129 bit integer IP address or IP address difference.
|
||||||
|
* This covers IPv4 and IPv6 addresses.
|
||||||
|
*/
|
||||||
|
typedef struct _MpAddr {
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MPADDR_INIT_FLG= 1<<0
|
||||||
|
} flags;
|
||||||
|
|
||||||
|
// AF_INET or AF_INET6
|
||||||
|
int domain;
|
||||||
|
|
||||||
|
// GNU multi-precision integer
|
||||||
|
mpz_t addr;
|
||||||
|
|
||||||
|
} MpAddr;
|
||||||
|
|
||||||
|
/****************************************************************
|
||||||
|
* Entry class, one for each address passed on command line.
|
||||||
|
*/
|
||||||
|
/* Useful class for this app */
|
||||||
|
typedef struct _Entry {
|
||||||
|
|
||||||
|
// 129 bit integer address.
|
||||||
|
MpAddr mp_addr;
|
||||||
|
|
||||||
|
// Line from stdin which has was closest to ours.
|
||||||
|
unsigned lineno;
|
||||||
|
|
||||||
|
// Invalid if 0 == lineno
|
||||||
|
MpAddr mp_closest_addr, // Address which was closest to ours.
|
||||||
|
mp_closest_prox; // Proximity to ours.
|
||||||
|
|
||||||
|
} Entry;
|
||||||
|
|
||||||
|
/*==================================================================*/
|
||||||
|
/*================= Forward declarations ===========================*/
|
||||||
|
/*==================================================================*/
|
||||||
|
|
||||||
|
static void MpAddr_sinit(MpAddr *self);
|
||||||
|
static MpAddr* MpAddr_constructor(MpAddr *self);
|
||||||
|
static void* MpAddr_destructor(MpAddr *self);
|
||||||
|
static int MpAddr_inetAssign(MpAddr *self, const char *addrStr);
|
||||||
|
static void MpAddr_assign(MpAddr *self, const MpAddr *src);
|
||||||
|
static void MpAdd_absDiff(MpAddr *self, const MpAddr *opl, const MpAddr *opr);
|
||||||
|
static int MpAdd_cmp(const MpAddr *self, const MpAddr *other);
|
||||||
|
static int MpAddr_isSameFamily(const MpAddr *self, const MpAddr *other);
|
||||||
|
static int MpAddr_lt(const MpAddr *self, const MpAddr *other);
|
||||||
|
|
||||||
|
|
||||||
|
#define Entry_create(p, addr) \
|
||||||
|
((p)=(Entry_constructor((p)=malloc(sizeof(Entry)), addr) ? (p) : ( p ? realloc(Entry_destructor(p),0) : 0 )))
|
||||||
|
static Entry* Entry_constructor(Entry *self, const char *addr);
|
||||||
|
static void* Entry_destructor(Entry *self);
|
||||||
|
//static int Entry_isSameFamily(const Entry *self, const MpAddr *mp_addr);
|
||||||
|
static int Entry_is_closer(const Entry *self, const MpAddr *mp_addr);
|
||||||
|
static int Entry_lineno_cmp(const void *const*pp1, const void *const* pp2);
|
||||||
|
static void Entry_print(const Entry *self);
|
||||||
|
static void Entry_register(Entry *self, unsigned lineno, const MpAddr *mp_addr);
|
||||||
|
//static MpAddr* Entry_get_prox(const Entry *self, MpAddr *rtn, const MpAddr *other);
|
||||||
|
|
||||||
|
/*==================================================================*/
|
||||||
|
/*========================= static data ============================*/
|
||||||
|
/*==================================================================*/
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
|
||||||
|
PTRVEC entry_vec;
|
||||||
|
|
||||||
|
unsigned max_off;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
int major,
|
||||||
|
minor,
|
||||||
|
patch;
|
||||||
|
} version;
|
||||||
|
|
||||||
|
} S= {
|
||||||
|
.max_off= 50,
|
||||||
|
|
||||||
|
.version= {
|
||||||
|
.major= 0,
|
||||||
|
.minor= 0,
|
||||||
|
.patch= 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*==================================================================*/
|
||||||
|
/*======================== main() stuff ============================*/
|
||||||
|
/*==================================================================*/
|
||||||
|
/* Enums for long options */
|
||||||
|
enum {
|
||||||
|
VERSION_OPT_ENUM=128, /* Larger than any printable character */
|
||||||
|
HELP_OPT_ENUM
|
||||||
|
};
|
||||||
|
|
||||||
|
/*==================================================================*/
|
||||||
|
/*======================== main() ==================================*/
|
||||||
|
/*==================================================================*/
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
/***************************************************
|
||||||
|
* Program execution begins here ...
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int rtn= EXIT_FAILURE;
|
||||||
|
|
||||||
|
extern char *optarg;
|
||||||
|
extern int optind, optopt;
|
||||||
|
|
||||||
|
PTRVEC_constructor(&S.entry_vec, 10);
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse command line arguments */
|
||||||
|
{ /*==================================================================*/
|
||||||
|
int c, errflg= 0;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
|
||||||
|
static const struct option long_options[]= {
|
||||||
|
{"help", no_argument, 0, HELP_OPT_ENUM},
|
||||||
|
{"version", no_argument, 0, VERSION_OPT_ENUM},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
int c, option_ndx= 0;
|
||||||
|
|
||||||
|
c= getopt_long(argc, argv, ":m:", long_options, &option_ndx);
|
||||||
|
|
||||||
|
if(-1 == c) break;
|
||||||
|
|
||||||
|
switch(c) {
|
||||||
|
|
||||||
|
/* print usage help */
|
||||||
|
case HELP_OPT_ENUM:
|
||||||
|
++errflg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VERSION_OPT_ENUM:
|
||||||
|
ez_fprintf(stdout, "b2f-grep v%d.%d.%d\n", S.version.major, S.version.minor, S.version.patch);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
{
|
||||||
|
int rc= sscanf(optarg, "%u", &S.max_off);
|
||||||
|
if(1 != rc)
|
||||||
|
++errflg;
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
ez_fprintf(stderr, "Unrecognized option: -%c\n", optopt);
|
||||||
|
++errflg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errflg) {
|
||||||
|
ez_fprintf(stderr,
|
||||||
|
"b2f-grep v%d.%d.%d Usage:\n"
|
||||||
|
"%s [options] addr1 [...] <ban2fail.cfg_file\n"
|
||||||
|
" -m max\tlargest value to consider in MAX_OFFENSES block\n"
|
||||||
|
" --help\tprint this usage message.\n"
|
||||||
|
" --version\tprint the version number and exit.\n"
|
||||||
|
, S.version.major, S.version.minor, S.version.patch
|
||||||
|
, argv[0]
|
||||||
|
);
|
||||||
|
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure we have at least one address to process */
|
||||||
|
if(optind == argc) {
|
||||||
|
eprintf("ERROR: no addresses supplied on command line.");
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pick up addresses on command line */
|
||||||
|
for(; optind < argc; ++optind) {
|
||||||
|
|
||||||
|
const char *addr= argv[optind];
|
||||||
|
|
||||||
|
/* Create an entry, and place it in our vector */
|
||||||
|
Entry *e;
|
||||||
|
if(!Entry_create(e, addr))
|
||||||
|
continue;
|
||||||
|
PTRVEC_addTail(&S.entry_vec, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // command options
|
||||||
|
|
||||||
|
{ /*====== Line by line processing ============*/
|
||||||
|
static char lbuf[1024],
|
||||||
|
ipbuf[40];
|
||||||
|
static MpAddr mp_addr,
|
||||||
|
mp_prox;
|
||||||
|
MpAddr_sinit(&mp_addr);
|
||||||
|
MpAddr_sinit(&mp_prox);
|
||||||
|
|
||||||
|
char *str;
|
||||||
|
unsigned lineno, max_off= 0;
|
||||||
|
for(lineno= 1, str= ez_fgets(lbuf, sizeof(lbuf)-1, stdin);
|
||||||
|
str;
|
||||||
|
str= ez_fgets(lbuf, sizeof(lbuf)-1, stdin), ++lineno)
|
||||||
|
{
|
||||||
|
str= trim(str);
|
||||||
|
|
||||||
|
/* See if this is a MAX_OFFENSES block declaration */
|
||||||
|
int rc= sscanf(str, "MAX_OFFENSES %u", &max_off);
|
||||||
|
if(1 == rc || max_off > S.max_off)
|
||||||
|
continue; // We have what we need for this line
|
||||||
|
|
||||||
|
/* Nope, maybe an IP address ... */
|
||||||
|
rc= sscanf(str, "IP = %39[^ \t]", ipbuf);
|
||||||
|
if(1 != rc)
|
||||||
|
continue; // Ignore line
|
||||||
|
|
||||||
|
if(MpAddr_inetAssign(&mp_addr, ipbuf)) {
|
||||||
|
eprintf("ERROR: on line %u", lineno);
|
||||||
|
continue; // Don't recognize address string
|
||||||
|
}
|
||||||
|
|
||||||
|
{ /* Loop through all entries, assign line numbers if necessary */
|
||||||
|
unsigned i;
|
||||||
|
Entry *e;
|
||||||
|
PTRVEC_loopFwd(&S.entry_vec, i, e) {
|
||||||
|
Entry_register(e, lineno, &mp_addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // reading stdin
|
||||||
|
|
||||||
|
{ /*========= Print results ============*/
|
||||||
|
unsigned i;
|
||||||
|
Entry *e;
|
||||||
|
PTRVEC_sort(&S.entry_vec, Entry_lineno_cmp);
|
||||||
|
PTRVEC_loopFwd(&S.entry_vec, i, e) {
|
||||||
|
if(i)
|
||||||
|
ez_fputc('\t', stdout);
|
||||||
|
Entry_print(e);
|
||||||
|
}
|
||||||
|
ez_fputc('\n', stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
rtn= EXIT_SUCCESS;
|
||||||
|
abort:
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*==================================================================*/
|
||||||
|
/*============== Supporting functions ==============================*/
|
||||||
|
/*==================================================================*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
MpAddr_sinit(MpAddr *self)
|
||||||
|
/**************************************************************
|
||||||
|
* Construct if necessary.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
if(!(self->flags & MPADDR_INIT_FLG))
|
||||||
|
MpAddr_constructor(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MpAddr*
|
||||||
|
MpAddr_constructor(MpAddr *self)
|
||||||
|
/**************************************************************
|
||||||
|
* Initialize for use.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
|
||||||
|
mpz_init2(self->addr, 129);
|
||||||
|
|
||||||
|
self->flags= MPADDR_INIT_FLG;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
MpAddr_destructor(MpAddr *self)
|
||||||
|
/**************************************************************
|
||||||
|
* Free resources.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
if(self->flags & MPADDR_INIT_FLG)
|
||||||
|
mpz_clear(self->addr);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
MpAddr_inetAssign(MpAddr *self, const char *addrStr)
|
||||||
|
/**************************************************************
|
||||||
|
* Assign address from string representation of numeric address
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int rtn= -1;
|
||||||
|
|
||||||
|
char hex_buf[33];
|
||||||
|
unsigned char buf[sizeof(struct in6_addr)];
|
||||||
|
|
||||||
|
self->domain= strchr(addrStr, ':') ? AF_INET6 : AF_INET;
|
||||||
|
int rc= inet_pton(self->domain, addrStr, buf);
|
||||||
|
switch(rc) {
|
||||||
|
case -1:
|
||||||
|
sys_eprintf("ERROR: inet_pton(\"%s\")", addrStr);
|
||||||
|
goto abort;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
eprintf("WARNING: \"%s\" not recognized as an address", addrStr);
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* At this point we have the address as an integer in big-endian order in buf */
|
||||||
|
|
||||||
|
switch(self->domain) {
|
||||||
|
|
||||||
|
case AF_INET:
|
||||||
|
snprintf(hex_buf, sizeof(hex_buf), "%hhu%hhu%hhu%hhu", buf[0], buf[1], buf[2], buf[3]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
snprintf(hex_buf, sizeof(hex_buf), "%hhu%hhu%hhu%hhu%hhu%hhu%hhu%hhu%hhu%hhu%hhu%hhu%hhu%hhu%hhu%hhu"
|
||||||
|
, buf[0]
|
||||||
|
, buf[1]
|
||||||
|
, buf[2]
|
||||||
|
, buf[3]
|
||||||
|
, buf[4]
|
||||||
|
, buf[5]
|
||||||
|
, buf[6]
|
||||||
|
, buf[7]
|
||||||
|
, buf[8]
|
||||||
|
, buf[9]
|
||||||
|
, buf[10]
|
||||||
|
, buf[11]
|
||||||
|
, buf[12]
|
||||||
|
, buf[13]
|
||||||
|
, buf[14]
|
||||||
|
, buf[15]
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc= mpz_set_str(self->addr, hex_buf, 16);
|
||||||
|
if(-1 == rc) {
|
||||||
|
eprintf("ERROR: \"%s\" not recognized as hexidecimal integer.", hex_buf);
|
||||||
|
goto abort;
|
||||||
|
}
|
||||||
|
|
||||||
|
rtn= 0;
|
||||||
|
abort:
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
MpAdd_absDiff(MpAddr *self, const MpAddr *opl, const MpAddr *opr)
|
||||||
|
/***************************************************************
|
||||||
|
* Compute the absolute different between opl and opr
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
MpAddr diff;
|
||||||
|
MpAddr_sinit(&diff);
|
||||||
|
|
||||||
|
mpz_sub(diff.addr, opl->addr, opr->addr);
|
||||||
|
mpz_abs(self->addr, diff.addr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
MpAdd_cmp(const MpAddr *self, const MpAddr *other)
|
||||||
|
/***************************************************************
|
||||||
|
* strcmp() style comparision return.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
return mpz_cmp(self->addr, other->addr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
MpAddr_isSameFamily(const MpAddr *self, const MpAddr *other)
|
||||||
|
/***************************************************************
|
||||||
|
* Returns non-zero if self and other are in the same address
|
||||||
|
* family.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
return self->domain == other->domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
MpAddr_cmp(const MpAddr *self, const MpAddr *other)
|
||||||
|
/***************************************************************
|
||||||
|
* strcmp() style return value for comparison of self & other.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
return mpz_cmp(self->addr, other->addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
MpAddr_assign(MpAddr *self, const MpAddr *src)
|
||||||
|
/***************************************************************
|
||||||
|
* Assign the value of src to ourself.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
mpz_set(self->addr, src->addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Entry*
|
||||||
|
Entry_constructor(Entry *self, const char *addr)
|
||||||
|
/***************************************************************
|
||||||
|
* Create an entry object for the supplied IP address string.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
memset(self, 0, sizeof(*self));
|
||||||
|
|
||||||
|
Entry *rtn= NULL;
|
||||||
|
|
||||||
|
MpAddr_constructor(&self->mp_addr);
|
||||||
|
MpAddr_constructor(&self->mp_closest_addr);
|
||||||
|
MpAddr_constructor(&self->mp_closest_prox);
|
||||||
|
|
||||||
|
if(MpAddr_inetAssign(&self->mp_addr, addr))
|
||||||
|
goto abort;
|
||||||
|
|
||||||
|
rtn= self;
|
||||||
|
|
||||||
|
abort:
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
Entry_destructor(Entry *self)
|
||||||
|
/***************************************************************
|
||||||
|
* Destructor.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
MpAddr_destructor(&self->mp_addr);
|
||||||
|
MpAddr_destructor(&self->mp_closest_addr);
|
||||||
|
MpAddr_destructor(&self->mp_closest_prox);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
Entry_print(const Entry *self)
|
||||||
|
/***************************************************************
|
||||||
|
* Print result to stdout.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned lineno= MAX(self->lineno, 1);
|
||||||
|
if(MpAddr_cmp(&self->mp_addr, &self->mp_closest_addr))
|
||||||
|
--lineno;
|
||||||
|
ez_fprintf(stdout, "%u", lineno);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
Entry_lineno_cmp(const void *const*pp1, const void *const* pp2)
|
||||||
|
/***************************************************************
|
||||||
|
* Comparison function we can use with PTRVEC_sort().
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
const Entry *e1= *(const Entry *const*)pp1,
|
||||||
|
*e2= *(const Entry *const*)pp2;
|
||||||
|
|
||||||
|
if(e1->lineno < e2->lineno)
|
||||||
|
return -1;
|
||||||
|
if(e1->lineno > e2->lineno)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
Entry_register(Entry *self, unsigned lineno, const MpAddr *mp_addr)
|
||||||
|
/***************************************************************
|
||||||
|
* Registers the address found on lineno.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
/* Ignore address of different family */
|
||||||
|
if(!MpAddr_isSameFamily(&self->mp_addr, mp_addr))
|
||||||
|
return;
|
||||||
|
|
||||||
|
static MpAddr prox;
|
||||||
|
MpAddr_sinit(&prox);
|
||||||
|
|
||||||
|
MpAdd_absDiff(&prox, &self->mp_addr, mp_addr);
|
||||||
|
|
||||||
|
if(!self->lineno || 0 < MpAddr_cmp(&self->mp_closest_prox, &prox)) {
|
||||||
|
self->lineno= lineno;
|
||||||
|
MpAddr_assign(&self->mp_closest_addr, mp_addr);
|
||||||
|
MpAddr_assign(&self->mp_closest_prox, &prox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
Entry_isSameFamily(const Entry *self, const MpAddr *mp_addr)
|
||||||
|
/***************************************************************
|
||||||
|
* Frontend for MpAddr_isSameFamily()
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
return MpAddr_isSameFamily(&self->mp_addr, mp_addr);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user