Package: arpwatch
Version: 2.1a15-7
Severity: wishlist
Hello,
I want to share patch which adds ability to load blacklist from a file.
'-B' option was implemented, it allows to specify file which contains
list of ipv4 addresses (one per line) and act similar to '-z' option.
By default up to 1024 addresses can be loaded.
Initially patch was done for arpwatch-2.1a15-4, looks like it can't be
applied to latest sources anymore , so I've forked
'https://salsa.debian.org/pkg-security-team/arpwatch' and updated patch
to be compatible with that sources.
-- System Information:
Debian Release: buster/sid
APT prefers testing
APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Kernel: Linux 4.19.0-2-amd64 (SMP w/1 CPU core)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=ANSI_X3.4-1968)
(ignored: LC_ALL set to C), LANGUAGE=en_US.UTF-8
(charmap=ANSI_X3.4-1968) (ignored: LC_ALL set to C)
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
Versions of packages arpwatch depends on:
ii adduser 3.118
ii gawk 1:4.2.1+dfsg-1
ii libc6 2.28-7
ii libpcap0.8 1.8.1-6
ii lsb-base 10.2018112800
Versions of packages arpwatch recommends:
ii ieee-data 20180805.1
arpwatch suggests no packages.
-- no debconf information
diff --git a/arpwatch.c b/arpwatch.c
index 38e5e34..dc40d54 100644
--- a/arpwatch.c
+++ b/arpwatch.c
@@ -170,7 +170,7 @@ main(int argc, char **argv)
interface = NULL;
rfilename = NULL;
pd = NULL;
- while ((op = getopt(argc, argv, "df:i:n:Nr:")) != EOF)
+ while ((op = getopt(argc, argv, "df:i:n:Nr:B:")) != EOF)
switch (op) {
case 'd':
@@ -202,6 +202,11 @@ main(int argc, char **argv)
rfilename = optarg;
break;
+ case 'B':
+ fprintf(stderr, "setting blacklistfile to %s\n", optarg);
+ blacklistfile = optarg;
+ break;
+
default:
usage();
}
@@ -397,6 +402,19 @@ process_ether(register u_char *u, register const struct pcap_pkthdr *h,
return;
}
+
+ if( blacklistfile != NULL && blacklist_entries > 0 ) {
+ int i;
+ for( i=0; i<blacklist_entries; i++ ) {
+ if( sia == blacklist[i].s_addr ) {
+ if (debug) {
+ syslog(LOG_INFO, "ignored_b", sia, sea, sha);
+ }
+ return;
+ }
+ }
+ }
+
/* Got a live one */
t = h->ts.tv_sec;
can_checkpoint = 0;
@@ -751,6 +769,6 @@ usage(void)
(void)fprintf(stderr, "Version %s\n", version);
(void)fprintf(stderr, "usage: %s [-dN] [-f datafile] [-i interface]"
- " [-n net[/width]] [-r file]\n", prog);
+ " [-n net[/width]] [-r file] [-B blacklistfile]\n", prog);
exit(1);
}
diff --git a/util.c b/util.c
index 4794a36..6eac027 100644
--- a/util.c
+++ b/util.c
@@ -39,6 +39,9 @@ static const char rcsid[] =
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
@@ -54,11 +57,16 @@ static const char rcsid[] =
char *arpdir = ARPDIR;
char *arpfile = ARPFILE;
char *ethercodes = ETHERCODES;
+char *blacklistfile = (void *) NULL;
/* Broadcast ethernet addresses */
u_char zero[6] = { 0, 0, 0, 0, 0, 0 };
u_char allones[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+/* Blacklist pointer & entries counter */
+struct in_addr *blacklist;
+u_int32_t blacklist_entries;
+
int debug = 0;
int initializing = 1; /* true if initializing */
@@ -141,8 +149,11 @@ dump(void)
int
readdata(void)
{
+ char *buf = NULL;
+ size_t len = 0;
register FILE *f;
+
if ((f = fopen(arpfile, "r")) == NULL) {
syslog(LOG_ERR, "fopen(%s): %m", arpfile);
return(0);
@@ -159,6 +170,32 @@ readdata(void)
(void)fclose(f);
}
+ if( blacklistfile != NULL ) {
+ if( (f = fopen(blacklistfile, "r")) == NULL ) {
+ syslog(LOG_ERR, "fopen(%s): %m", blacklistfile);
+ return(0);
+ }
+ blacklist_entries = 0;
+ blacklist = malloc( sizeof(struct in_addr) * BLACKLIST_MAX );
+ while( getline( &buf, &len, f ) > 0 ) {
+ if( blacklist_entries >= BLACKLIST_MAX ) {
+ syslog(LOG_ERR, "blacklist is full, too many entries in %s", blacklistfile);
+ break;
+ }
+ buf[strcspn(buf, "\n")] = '\0';
+ if(inet_aton(buf, &blacklist[blacklist_entries] ) == 0 ) {
+ syslog(LOG_ERR, "blacklist invalid ip: %s", buf);
+ continue;
+ }
+ blacklist_entries++;
+ }
+ if( buf != NULL ) {
+ free(buf);
+ buf = NULL;
+ }
+ (void)fclose(f);
+ }
+
return(1);
}
diff --git a/util.h b/util.h
index 824a1b5..31bb1e0 100644
--- a/util.h
+++ b/util.h
@@ -1,5 +1,11 @@
/* @(#) $Header: util.h,v 1.2 96/10/06 03:22:13 leres Exp $ (LBL) */
+#ifndef BLACKLIST_MAX
+/* Maximum number of addresses which can be added to blacklist */
+#define BLACKLIST_MAX 1024
+#endif
+
+
void dosyslog(int, char *, u_int32_t, u_char *, u_char *);
int dump(void);
void dumpone(u_int32_t, u_char *, time_t, char *);
@@ -11,6 +17,9 @@ extern char *newarpfile;
extern char *arpfile;
extern char *oldarpfile;
extern char *ethercodes;
+extern char *blacklistfile;
+extern struct in_addr *blacklist;
+extern u_int32_t blacklist_entries;
extern u_char zero[6];
extern u_char allones[6];