summaryrefslogtreecommitdiffstats
path: root/net-mgmt/arpwatch-devel/files/patch-ai
diff options
context:
space:
mode:
Diffstat (limited to 'net-mgmt/arpwatch-devel/files/patch-ai')
-rw-r--r--net-mgmt/arpwatch-devel/files/patch-ai304
1 files changed, 268 insertions, 36 deletions
diff --git a/net-mgmt/arpwatch-devel/files/patch-ai b/net-mgmt/arpwatch-devel/files/patch-ai
index ef25122..ae8c0ec 100644
--- a/net-mgmt/arpwatch-devel/files/patch-ai
+++ b/net-mgmt/arpwatch-devel/files/patch-ai
@@ -1,39 +1,271 @@
---- arpsnmp.c.orig Mon Jan 18 01:47:40 1999
-+++ arpsnmp.c Thu Feb 22 22:47:29 2001
-@@ -68,6 +68,8 @@
-
- char *prog;
-
-+char *Watcher;
-+
- extern int optind;
- extern int opterr;
- extern char *optarg;
-@@ -90,7 +92,7 @@
+--- ../arpwatch.orig/db.c Sat Sep 30 19:39:58 2000
++++ ./db.c Mon Sep 15 13:17:07 2003
+@@ -41,6 +41,7 @@
+ #include <string.h>
+ #include <syslog.h>
+ #include <unistd.h>
++#include <pthread.h>
+
+ #include "gnuc.h"
+ #ifdef HAVE_OS_PROTO_H
+@@ -54,18 +55,9 @@
+ #include "report.h"
+ #include "util.h"
+
+-#define HASHSIZE (2 << 15)
+-
+ #define NEWACTIVITY_DELTA (6*30*24*60*60) /* 6 months in seconds */
+ #define FLIPFLIP_DELTA (24*60*60) /* 24 hours in seconds */
+
+-/* Ethernet info */
+-struct einfo {
+- u_char e[6]; /* ether address */
+- char h[34]; /* simple hostname */
+- time_t t; /* timestamp */
+-};
+-
+ /* Address info */
+ struct ainfo {
+ u_int32_t a; /* ip address */
+@@ -78,22 +70,69 @@
+ /* Address hash table */
+ static struct ainfo ainfo_table[HASHSIZE];
+
++
++/* Ethernet hash table */
++struct einfo einfo_table[HASHSIZE];
++int et_cnt = 0;
++
+ static void alist_alloc(struct ainfo *);
+ int cmpeinfo(const void *, const void *);
+-static struct einfo *elist_alloc(u_int32_t, u_char *, time_t, char *);
++static struct einfo *elist_alloc(u_int32_t, u_char *, time_t, char *, char *);
+ static struct ainfo *ainfo_find(u_int32_t);
++static struct einfo *einfo_find(u_char *);
+ static void check_hname(struct ainfo *);
+ struct ainfo *newainfo(void);
+
++pthread_mutex_t mtx_einfo, mtx_ainfo;
++
+ int
+-ent_add(register u_int32_t a, register u_char *e, time_t t, register char *h)
++ent_add(register u_int32_t a, register u_char *e, time_t t, register char *h, register char *interface)
+ {
+ register struct ainfo *ap;
+- register struct einfo *ep;
++ struct einfo *ep;
+ register int i;
+ register u_int len;
+ u_char *e2;
+ time_t t2;
++ register evt_type event = NULL;
++ char *if2 = NULL;
++
++ pthread_mutex_lock(&mtx_einfo);
++
++ /* Lookup ethernet address */
++ ep = einfo_find(e);
++
++ /* New einfo? (elist_alloc makes 16 at a time -- no thanks) */
++ if (ep == NULL && ! initializing) {
++ if (et_cnt >= HASHSIZE) {
++ syslog(LOG_ERR, "ERROR: einfo_table too big");
++ } else {
++ ep = &einfo_table[et_cnt++];
++ BCOPY(e, ep->e, sizeof(ep->e));
++ if (h == NULL)
++ h = getsname(a);
++ if (h != NULL && !isdigit((int)*h))
++ strncpy(ep->h, h, sizeof(ep->h));
++ ep->t = t;
++ strncpy(ep->iface, interface, sizeof(ep->iface));
++ event |= ETHER_NEW;
++ e2 = NULL;
++ t2 = NULL;
++ }
++ } else if (! initializing) {
++ if (strncmp(ep->iface, interface, sizeof(ep->iface)) != 0) {
++ event |= ETHER_IFCHG;
++ asprintf(&if2, "%s", ep->iface);
++ memset((char *)ep->iface, 0, sizeof(ep->iface));
++ BCOPY(interface, ep->iface, sizeof(ep->iface));
++ e2 = NULL;
++ t2 = ep->t;
++ ep->t = t;
++ }
++ }
++
++ pthread_mutex_unlock(&mtx_einfo);
++ pthread_mutex_lock(&mtx_ainfo);
+
+ /* Lookup ip address */
+ ap = ainfo_find(a);
+@@ -101,28 +140,30 @@
+ /* Check for the usual case first */
+ if (ap->ecount > 0) {
+ ep = ap->elist[0];
+- if (MEMCMP(e, ep->e, 6) == 0) {
++ if (MEMCMP(e, ep->e, sizeof(ep->e)) == 0) {
+ if (t - ep->t > NEWACTIVITY_DELTA) {
+- report("new activity", a, e, NULL, &t, &ep->t);
++ event |= ACTIVITY_NEW;
++ e2 = NULL;
++ t2 = ep->t;
+ check_hname(ap);
+ }
+ ep->t = t;
+- return (1);
+ }
+ }
+
+ /* Check for a virgin ainfo record */
+ if (ap->ecount == 0) {
+ ap->ecount = 1;
+- ap->elist[0] = elist_alloc(a, e, t, h);
+- report("new station", a, e, NULL, &t, NULL);
+- return (1);
++ ap->elist[0] = elist_alloc(a, e, t, h, interface);
++ event |= IP_NEW;
++ e2 = NULL;
++ t2 = NULL;
+ }
+
+ /* Check for a flip-flop */
+ if (ap->ecount > 1) {
+ ep = ap->elist[1];
+- if (MEMCMP(e, ep->e, 6) == 0) {
++ if (MEMCMP(e, ep->e, sizeof(ep->e)) == 0) {
+ /*
+ * Suppress report when less than
+ * FLIPFLOP_DELTA and one of the two ethernet
+@@ -131,48 +172,76 @@
+ t2 = ap->elist[0]->t;
+ e2 = ap->elist[0]->e;
+ if (t - t2 < FLIPFLIP_DELTA &&
+- (isdecnet(e) || isdecnet(e2)))
++ (isdecnet(e) || isdecnet(e2))) {
+ dosyslog(LOG_INFO,
+ "suppressed DECnet flip flop", a, e, e2);
+- else
+- report("flip flop", a, e, e2, &t, &t2);
++ event |= FLIPFLOP_DECNET;
++ } else {
++ event |= FLIPFLOP;
++ }
++
+ ap->elist[1] = ap->elist[0];
+ ap->elist[0] = ep;
+ ep->t = t;
+ check_hname(ap);
+- return (1);
+ }
}
-
- opterr = 0;
-- while ((op = getopt(argc, argv, "df:")) != EOF)
-+ while ((op = getopt(argc, argv, "df:m:")) != EOF)
- switch (op) {
-
- case 'd':
-@@ -105,6 +107,10 @@
- arpfile = optarg;
- break;
-
-+ case 'm':
-+ Watcher = optarg;
-+ break;
-+
- default:
- usage();
+
+ for (i = 2; i < ap->ecount; ++i) {
+ ep = ap->elist[i];
+- if (MEMCMP(e, ep->e, 6) == 0) {
++ if (MEMCMP(e, ep->e, sizeof(ep->e)) == 0) {
+ /* An old entry comes to life */
+ e2 = ap->elist[0]->e;
+ t2 = ap->elist[0]->t;
+ dosyslog(LOG_NOTICE, "reused old ethernet address",
+ a, e, e2);
++ event |= IP_ETHER_REUSE;
+ /* Shift entries down */
+ len = i * sizeof(ap->elist[0]);
+ BCOPY(&ap->elist[0], &ap->elist[1], len);
+ ap->elist[0] = ep;
+ ep->t = t;
+ check_hname(ap);
+- return (1);
}
-@@ -184,6 +190,6 @@
-
- (void)fprintf(stderr, "Version %s\n", version);
- (void)fprintf(stderr,
-- "usage: %s [-d] [-f datafile] file [...]\n", prog);
-+ "usage: %s [-d] [-f datafile] [-m email] file [...]\n", prog);
- exit(1);
+ }
+
+- /* New ether address */
+- e2 = ap->elist[0]->e;
+- t2 = ap->elist[0]->t;
+- report("changed ethernet address", a, e, e2, &t, &t2);
+- /* Make room at head of list */
+- alist_alloc(ap);
+- len = ap->ecount * sizeof(ap->elist[0]);
+- BCOPY(&ap->elist[0], &ap->elist[1], len);
+- ap->elist[0] = elist_alloc(a, e, t, h);
+- ++ap->ecount;
+- return (1);
++ /* as originally written, any of these conditions would cause this
++ * block never to be reached. ETHER_NEW and ETHER_IFCHG have been added to that list.
++ */
++ if (event & ~(ACTIVITY_NEW | IP_NEW | FLIPFLOP | FLIPFLOP_DECNET | IP_ETHER_REUSE | ETHER_NEW | ETHER_IFCHG)) {
++ /* New ether address */
++ e2 = ap->elist[0]->e;
++ t2 = ap->elist[0]->t;
++ event |= IP_ETHERCHG;
++ /* Make room at head of list */
++ alist_alloc(ap);
++ len = ap->ecount * sizeof(ap->elist[0]);
++ BCOPY(&ap->elist[0], &ap->elist[1], len);
++ ap->elist[0] = elist_alloc(a, e, t, h, interface);
++ ++ap->ecount;
++ }
++
++ pthread_mutex_unlock(&mtx_ainfo);
++
++ report(event, a, e, e2, &t, &t2, interface, if2);
++
++ if (if2 != NULL)
++ free(if2);
++
++ return(1);
++}
++
++static struct einfo *
++einfo_find(register u_char *e)
++{
++ register int i;
++
++ for (i=0; i < et_cnt; i++) {
++ if (MEMCMP(einfo_table[i].e, e, sizeof(einfo_table[i].e)) == 0)
++ return(&einfo_table[i]);
++ }
++
++ return(NULL);
+ }
+
+ static struct ainfo *
+@@ -259,7 +328,7 @@
+ /* Allocate and initialize a elist struct */
+ static struct einfo *
+ elist_alloc(register u_int32_t a, register u_char *e, register time_t t,
+- register char *h)
++ register char *h, register char *interface)
+ {
+ register struct einfo *ep;
+ register u_int size;
+@@ -280,12 +349,16 @@
+
+ ep = elist++;
+ --eleft;
+- BCOPY(e, ep->e, 6);
++ BCOPY(e, ep->e, sizeof(ep->e));
+ if (h == NULL && !initializing)
+ h = getsname(a);
+ if (h != NULL && !isdigit((int)*h))
+- strcpy(ep->h, h);
++ strncpy(ep->h, h, sizeof(ep->h));
+ ep->t = t;
++
++ if (interface != NULL)
++ strncpy(ep->iface, interface, sizeof(ep->iface));
++
+ return (ep);
+ }
+
+@@ -304,7 +377,7 @@
+ if (!isdigit((int)*h) && strcmp(h, ep->h) != 0) {
+ syslog(LOG_INFO, "hostname changed %s %s %s -> %s",
+ intoa(ap->a), e2str(ep->e), ep->h, h);
+- strcpy(ep->h, h);
++ strncpy(ep->h, h, sizeof(ep->h));
+ }
}
+
OpenPOWER on IntegriCloud