diff options
Diffstat (limited to 'net-mgmt/arpwatch-devel/files/patch-ai')
-rw-r--r-- | net-mgmt/arpwatch-devel/files/patch-ai | 304 |
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)); + } } + |