aboutsummaryrefslogtreecommitdiff
path: root/net-mgmt/netmond
diff options
context:
space:
mode:
authorMartin Wilke <miwi@FreeBSD.org>2007-01-15 14:55:36 +0000
committerMartin Wilke <miwi@FreeBSD.org>2007-01-15 14:55:36 +0000
commit42ed8c136edaedec0b7c8b4d0c55690561c44cb3 (patch)
treecde678875b6213b53f6b235b7519aca2d599eb9d /net-mgmt/netmond
parentbb11ec302884579c93e3846a43a0267268a7e417 (diff)
downloadports-42ed8c136edaedec0b7c8b4d0c55690561c44cb3.tar.gz
ports-42ed8c136edaedec0b7c8b4d0c55690561c44cb3.zip
Notes
Diffstat (limited to 'net-mgmt/netmond')
-rw-r--r--net-mgmt/netmond/Makefile34
-rw-r--r--net-mgmt/netmond/distinfo6
-rw-r--r--net-mgmt/netmond/files/netmond.sh.in2
-rw-r--r--net-mgmt/netmond/files/patch-Makefile.in11
-rw-r--r--net-mgmt/netmond/files/patch-dns.c54
-rw-r--r--net-mgmt/netmond/files/patch-event.c11
-rw-r--r--net-mgmt/netmond/files/patch-netmon.h176
-rw-r--r--net-mgmt/netmond/files/patch-netmond.c270
-rw-r--r--net-mgmt/netmond/files/patch-netstate.c38
-rw-r--r--net-mgmt/netmond/files/patch-parseconf.y489
-rw-r--r--net-mgmt/netmond/files/patch-ping.c103
-rw-r--r--net-mgmt/netmond/files/patch-radius.c62
-rw-r--r--net-mgmt/netmond/files/patch-reconfig.c135
-rw-r--r--net-mgmt/netmond/files/patch-regex.c54
-rw-r--r--net-mgmt/netmond/files/patch-regex.h17
-rw-r--r--net-mgmt/netmond/files/patch-router.c62
-rw-r--r--net-mgmt/netmond/files/patch-scanconf.l92
-rw-r--r--net-mgmt/netmond/files/patch-session.c34
-rw-r--r--net-mgmt/netmond/files/patch-snmp.c54
-rw-r--r--net-mgmt/netmond/files/patch-tacacs.c53
-rw-r--r--net-mgmt/netmond/files/patch-tcp.c128
-rw-r--r--net-mgmt/netmond/files/patch-trap.c35
-rw-r--r--net-mgmt/netmond/files/patch-udp.c66
-rw-r--r--net-mgmt/netmond/files/patch-util.c131
-rw-r--r--net-mgmt/netmond/files/patch-variables.c39
-rw-r--r--net-mgmt/netmond/files/pipe.c1
-rw-r--r--net-mgmt/netmond/files/pkg-message.in4
-rw-r--r--net-mgmt/netmond/pkg-descr2
28 files changed, 2146 insertions, 17 deletions
diff --git a/net-mgmt/netmond/Makefile b/net-mgmt/netmond/Makefile
index dd21b43b7d6a..70693fa3936a 100644
--- a/net-mgmt/netmond/Makefile
+++ b/net-mgmt/netmond/Makefile
@@ -7,16 +7,21 @@
PORTNAME= netmond
PORTVERSION= 2.2b6
-PORTREVISION= 3
+PORTREVISION= 4
CATEGORIES= net-mgmt
MASTER_SITES= ftp://ftp.risp.ru/pub/RinetSoftware/
DISTNAME= netmond-2.2-b6
EXTRACT_SUFX= .tgz
+PATCH_SITES= http://vfom.narod.ru/download/
+PATCH_VERSION= 1
+PATCHFILES= ${DISTNAME}.patch${PATCH_VERSION}${EXTRACT_SUFX} ${DISTNAME}.docs${EXTRACT_SUFX}
+
MAINTAINER= vfom@narod.ru
COMMENT= Netmond - IP network monitoring daemon
#MK_IFGRAPH= yes
+PATCHDIR= ${WRKDIR}/patches
.if defined(MK_IFGRAPH)
LIB_DEPENDS= gd.4:${PORTSDIR}/graphics/gd
@@ -41,10 +46,12 @@ USE_RC_SUBR= netmond.sh
SUB_FILES+= pkg-message netmond_watchdog netmondctl
-PORTDOCS= README README.ru CHANGES README.port README.port.ru
+PORTDOCS= README README.ru CHANGES README.port.eng README.port.ru index.html netmond.css en/ ru/
-pre-build:
- ${CP} ${FILESDIR}/*.c ${WRKSRC}
+post-extract:
+ ${MKDIR} ${PATCHDIR}
+ ${TAR} -zxf ${DISTDIR}/${DISTNAME}.patch${PATCH_VERSION}${EXTRACT_SUFX} -C ${PATCHDIR}
+ ${CP} ${PATCHDIR}/pipe.c ${WRKSRC}
do-install:
@if pw user show netmon 2>/dev/null ; then \
@@ -63,20 +70,21 @@ do-install:
.endif
${INSTALL_SCRIPT} ${WRKDIR}/netmond_watchdog ${PREFIX}/sbin/netmond_watchdog
${INSTALL_SCRIPT} ${WRKDIR}/netmondctl ${PREFIX}/sbin/netmondctl
- ${INSTALL_DATA} ${WRKSRC}/netmon.conf.sample ${PREFIX}/etc//netmond.conf.sample
+ ${INSTALL_DATA} ${WRKSRC}/netmon.conf.sample ${PREFIX}/etc/netmond.conf.sample
${CHMOD} u+s ${PREFIX}/sbin/netmond
.if !defined(NOPORTDOCS)
${MKDIR} ${DOCSDIR}
- ${CHMOD} 555 ${DOCSDIR}
- ${INSTALL_DATA} ${WRKSRC}/README ${DOCSDIR}/README.ru
-
- ${INSTALL_DATA} ${WRKSRC}/CHANGES ${DOCSDIR}/
- ${INSTALL_DATA} ${FILESDIR}/README.port.ru ${DOCSDIR}/
- ${INSTALL_DATA} ${FILESDIR}/README.port.eng ${DOCSDIR}/README.port
- ${INSTALL_DATA} ${FILESDIR}/README.eng ${DOCSDIR}/README
+ ${CHMOD} 755 ${DOCSDIR}
+ ${TAR} -zxf ${DISTDIR}/${DISTNAME}.docs${EXTRACT_SUFX} -C ${DOCSDIR}
.endif
post-install:
${CAT} ${PKGMESSAGE}
-.include <bsd.port.mk>
+.include <bsd.port.pre.mk>
+
+.if ${OSVERSION} < 500000
+BROKEN= Does not compile on 4.x
+.endif
+
+.include <bsd.port.post.mk>
diff --git a/net-mgmt/netmond/distinfo b/net-mgmt/netmond/distinfo
index 8caeebd83358..cf91115f3aca 100644
--- a/net-mgmt/netmond/distinfo
+++ b/net-mgmt/netmond/distinfo
@@ -1,3 +1,9 @@
MD5 (netmond-2.2-b6.tgz) = 87e324702e60d1c4e1a83ae3649c1488
SHA256 (netmond-2.2-b6.tgz) = 2b31096f731e347b65ce2c2a11f1ce70af0d8d7a9ff0c49edf4b3c3b65d0befd
SIZE (netmond-2.2-b6.tgz) = 264500
+MD5 (netmond-2.2-b6.patch1.tgz) = c19002459fe22c64684e922c9829f24b
+SHA256 (netmond-2.2-b6.patch1.tgz) = 0fa7aae8dcfce5ba735af2ec0dfd3fc7a7d4e991cf2dc331ed6714e3ad9d08e5
+SIZE (netmond-2.2-b6.patch1.tgz) = 18574
+MD5 (netmond-2.2-b6.docs.tgz) = a92919c3ae22b75aa081fe5cc10fc72b
+SHA256 (netmond-2.2-b6.docs.tgz) = 4cdad1003455c99ee1d3067a4db7a01f1db11247d2d5fe683c384f6d05ed79e8
+SIZE (netmond-2.2-b6.docs.tgz) = 110692
diff --git a/net-mgmt/netmond/files/netmond.sh.in b/net-mgmt/netmond/files/netmond.sh.in
index 977c76b6f5e1..70896a3cfa04 100644
--- a/net-mgmt/netmond/files/netmond.sh.in
+++ b/net-mgmt/netmond/files/netmond.sh.in
@@ -20,7 +20,7 @@ rcvar=`set_rcvar`
command="%%PREFIX%%/sbin/${name}"
pidfile="/var/run/${name}.pid"
-required_files="${prefix}/etc/${name}.conf"
+required_files="%%PREFIX%%/etc/${name}.conf"
stop_postcmd="netmond_poststop"
diff --git a/net-mgmt/netmond/files/patch-Makefile.in b/net-mgmt/netmond/files/patch-Makefile.in
new file mode 100644
index 000000000000..63e6a2ccea12
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-Makefile.in
@@ -0,0 +1,11 @@
+--- Makefile.in.orig Tue Jul 20 19:28:20 2004
++++ Makefile.in Thu Nov 2 13:35:27 2006
+@@ -47,7 +47,7 @@
+
+ NETMOND_C = netmond.c netstate.c event.c session.c mib.c snmp.c router.c \
+ trap.c ping.c tcp.c udp.c dns.c radius.c tacacs.c md5.c util.c \
+- variables.c save.c regex.c malloc.c reconfig.c
++ variables.c save.c regex.c malloc.c reconfig.c pipe.c
+ NETMOND_Y = calc.y parseconf.y
+ NETMOND_L = scanconf.l
+ NETMOND_G = version.c
diff --git a/net-mgmt/netmond/files/patch-dns.c b/net-mgmt/netmond/files/patch-dns.c
new file mode 100644
index 000000000000..322c1b606953
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-dns.c
@@ -0,0 +1,54 @@
+--- dns.c.orig Mon Aug 25 18:19:04 2003
++++ dns.c Thu Nov 2 13:35:27 2006
+@@ -149,6 +149,8 @@
+ {
+ SESSION *sd = method->sd;
+ int reqid;
++ struct sockaddr_in *from;
++ char ipaddr[20];
+
+ /* sanity check */
+ if (!sd) return;
+@@ -161,6 +163,14 @@
+ return;
+ }
+
++ /* bind socket to local source address */
++
++ from = (struct sockaddr_in *)&sd->me;
++ if ( from->sin_addr.s_addr != INADDR_ANY ) {
++ if( bind(sd->sock, &sd->me, sizeof(struct sockaddr) ) == -1 )
++ report(LOG_WARNING, "dns_start : bind failed for %s: %s",
++ intoa(ipaddr,from->sin_addr), strerror(*(__error())) );
++ }
+ /* turn on non-blocking I/O */
+ if (set_socket_async(sd->sock, TRUE) < 0) {
+ dns_reply(errno, sd, 0);
+@@ -288,7 +298,7 @@
+ METHOD *method;
+ {
+ SESSION template;
+- struct sockaddr_in *to;
++ struct sockaddr_in *to, *from;
+
+ dprintf(("dns_init(%s/%s)\n", target->name, method->name));
+
+@@ -303,6 +313,10 @@
+ to->sin_family = AF_INET;
+ to->sin_port = htons(method->rport);
+ to->sin_addr = method->address ? method->ip_addr : target->ip_addr;
++ from = (struct sockaddr_in *)&template.me;
++ bzero((char *)from, sizeof(struct sockaddr_in));
++ from->sin_family = AF_INET;
++ from->sin_addr = target->ip_srcaddr;
+ template.timeout = method->timeout * 1000000L; /* make microseconds */
+ template.retries = method->retries;
+ template.send = dns_send;
+@@ -332,6 +346,7 @@
+ IPPROTO_UDP, /* network protocol */
+ NAMESERVER_PORT, /* server port */
+ 0, 0, /* timeout and retries undefined yet */
++ NULL,NULL, /* when variables unused */
+ { 0, 0 }, /* no parameters used */
+
+ /* Non-initialized data */
diff --git a/net-mgmt/netmond/files/patch-event.c b/net-mgmt/netmond/files/patch-event.c
new file mode 100644
index 000000000000..e4971eadb499
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-event.c
@@ -0,0 +1,11 @@
+--- event.c.orig Thu Feb 27 17:42:32 2003
++++ event.c Tue Nov 14 17:40:52 2006
+@@ -288,7 +288,7 @@
+ #ifdef HAVE_PTHREAD
+ pthread_mutex_lock(&localtime_lock);
+ #endif
+- tm = localtime(&tvp->tv_sec);
++ tm = localtime((time_t *)&tvp->tv_sec);
+ defect = tm->tm_sec + 60 * tm->tm_min + 3600 * tm->tm_hour + off;
+ #ifdef HAVE_PTHREAD
+ pthread_mutex_unlock(&localtime_lock);
diff --git a/net-mgmt/netmond/files/patch-netmon.h b/net-mgmt/netmond/files/patch-netmon.h
new file mode 100644
index 000000000000..ef3e977196ff
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-netmon.h
@@ -0,0 +1,176 @@
+--- netmon.h.orig Tue Aug 26 10:00:38 2003
++++ netmon.h Thu Dec 28 13:31:06 2006
+@@ -14,6 +14,9 @@
+ #include <sys/socket.h>
+ #include <sys/time.h>
+ #include <netinet/in.h>
++#include <pwd.h>
++#include <grp.h>
++#include <time.h>
+ #ifdef DEBUG_MEMORY
+ #include <assert.h>
+ #endif
+@@ -77,7 +80,10 @@
+ #endif
+
+ #define NETMON "netmon"
+-#define DEFAULT_CONFIG "/etc/netmon.conf"
++#define DEFAULT_CONFIG "/usr/local/etc/netmond.conf"
++#define USERNAME "netmon"
++#define GROUPNAME "netmon"
++#define PIDFILE_PATH "/var/run"
+ #define DEFAULT_WATCHDOG 600 /* 10 min */
+
+ #define POLLING_MIN 30 /* 30 sec */
+@@ -88,9 +94,13 @@
+ typedef struct timeval TIMEVAL;
+ typedef unsigned long oid;
+
++#define STATE_UNKNOWN 0
+ #define STATE_UP 1
+ #define STATE_DOWN 2
++#define STATE_DEGRADED 3
++#define STATE_WARNING 4
+ #define BGP_ESTABLISHED 6
++#define ENV_NORMAL 1
+ #define ENV_NOTPRESENT 5
+
+ #define OBJ_STATE 0
+@@ -111,6 +121,9 @@
+ #define TYPE_ENVFAN 9
+ #define TYPE_ENVPS 10
+
++#define WHEN_PROTO 10099
++#define PIPE_PROTO 10098
++
+ struct object_ent;
+ struct method_ent;
+
+@@ -250,6 +263,7 @@
+
+ int state; /* current operational status (UP/DOWN/...) */
+ int prev_state; /* previous operational status */
++ int ignore_state; /* if =1, ignore this interface while parent object state evaluating */
+ TIMEVAL last_request; /* last time interface requested */
+ TIMEVAL prev_request; /* previous time interface requested */
+ TIMEVAL last_reply; /* last time interface reply */
+@@ -294,6 +308,7 @@
+ int asn; /* AS number */
+ char *descr; /* AS description */
+ char *datadir; /* directory where store data */
++ int ignore_state; /* if =1, ignore this AS while parent object state evaluating */
+ SAVE *save_list; /* list of save methods */
+ GROUP_REF *ns_acl; /* netstate client access list */
+
+@@ -325,6 +340,7 @@
+ int type; /* type of gauge: TYPE_ENVTEMP, etc */
+ char *descr; /* env mon description */
+ char *datadir; /* directory where store data */
++ int ignore_state; /* if =1, ignore this ENV while parent object state evaluating */
+ SAVE *save_list; /* list of save methods */
+ GROUP_REF *ns_acl; /* netstate client access list */
+
+@@ -385,13 +401,14 @@
+ struct method_ent *method; /* session method */
+ int sock; /* socket file descriptor */
+ struct sockaddr peer; /* address of peer */
++ struct sockaddr me; /* my source address */
+ long timeout; /* number of microseconds until first timeout */
+ int retries; /* number of retries before timeout */
+ int (*connect) __P((struct session_ent *));
+ int (*send) __P((struct session_ent *, REQUEST *));
+ int (*recv) __P((struct session_ent *));
+ void (*read) __P((int, struct session_ent *, int));
+-
++ pid_t pid;
+ /* returned values */
+ int data_int; /* data length or chat-script matchs */
+ char *data_ptr; /* pointer to resulting data if any */
+@@ -428,6 +445,8 @@
+ u_short rport; /* remote port number, 0=unused */
+ int timeout; /* number of seconds until first timeout */
+ int retries; /* number of retries before timeout */
++ char *when; /* condition string */
++ char *when_fmt; /* message when condition is true */
+ union {
+ struct ping_param {
+ short send; /* ICMP echo request packets to send */
+@@ -530,7 +549,9 @@
+ char *descr; /* object description */
+ char *datadir; /* directory where store data */
+ char *address; /* domain name or dotted IP address */
++ char *srcaddress; /* domain name or dotted source IP address */
+ struct in_addr ip_addr; /* ip address of peer */
++ struct in_addr ip_srcaddr; /* source ip address */
+ int polling; /* polling period in seconds */
+ int saving; /* saving period in seconds */
+ int sync; /* polling counter to synchronize saving */
+@@ -544,6 +565,10 @@
+
+ int state; /* current operational status (UP/DOWN/...) */
+ int prev_state; /* previous operational status */
++ int ignore_state; /* if =1, ignore this obj while parent object state evaluating */
++ int mths_ok; /* count of Ok finished methods */
++ int mths_fail; /* count of Failed methods */
++ int smths_fail; /* count of Failed services methods */
+ TIMEVAL last_request; /* last time method requested */
+ TIMEVAL prev_request; /* previous time method requested */
+ TIMEVAL last_reply; /* last time method reply */
+@@ -574,17 +599,29 @@
+
+ typedef struct config_ent {
+ char *rootdir; /* default work directory */
++ char *chrootdir; /* chroot directory for EXEC children */
++ char *username; /* username for EXEC children */
++ uid_t uid; /* UID for EXEC children */
++ char *groupname; /* groupname for EXEC children */
++ gid_t gid; /* GID for EXEC children */
+ char *timefmt; /* strftime format of currtime for logging */
++ char *srcaddress; /* my default source domain name or dotted IP address */
++ struct in_addr ip_srcaddr; /* my default sorce ip address */
+ int polling; /* default polling interval in seconds */
+ int saving; /* default saving interval in seconds */
+ int timeout; /* default timeout in seconds */
+ int retries; /* default number of retries */
++ int compatibility_flag; /* */
+
+ int enable_traps; /* enable SNMP traps */
+ int source_traps; /* match src-addr and agent-addr of traps */
++ char *trap_address; /* Trap bind address */
++ struct in_addr trap_ip_addr; /* */
+
+ /* netstate server */
+ int ns_port; /* server port number */
++ char *ns_address; /* NetState bind address */
++ struct in_addr ns_ip_addr; /* */
+ int ns_timo; /* client timeout in seconds */
+ GROUP_REF *ns_acl; /* netstate client access list */
+
+@@ -616,6 +653,7 @@
+ extern int netstate_sock;
+ extern int Cflag;
+ extern int syslog_initialized;
++extern int compatibility_flag;
+
+ /*
+ * Function prototypes
+@@ -733,6 +771,19 @@
+ void tcp_start __P((METHOD *));
+ void tcp_stop __P((METHOD *));
+ int match_expect __P((SESSION *, CHATSCRIPT *, char *));
++int tcp_connect __P((SESSION *));
++int tcp_send __P((SESSION *,REQUEST *));
++int tcp_recv __P((SESSION *));
++void tcp_close __P((int, SESSION *, int));
++
++/* pipe.c */
++int pipe_init __P((OBJECT *, METHOD *));
++void pipe_start __P((METHOD *));
++void pipe_stop __P((METHOD *));
++
++int when_init __P((OBJECT *, METHOD *));
++void when_start __P((METHOD *));
++void when_stop __P((METHOD *));
+
+ /* udp.c */
+ int udp_init __P((OBJECT *, METHOD *));
diff --git a/net-mgmt/netmond/files/patch-netmond.c b/net-mgmt/netmond/files/patch-netmond.c
new file mode 100644
index 000000000000..fb8052fc770c
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-netmond.c
@@ -0,0 +1,270 @@
+--- netmond.c.orig Tue Jul 20 17:57:19 2004
++++ netmond.c Thu Dec 28 13:31:06 2006
+@@ -62,6 +62,8 @@
+ pid_t mypid; /* my self PID */
+ int syslog_initialized; /* syslog ready to use */
+ int syslog_facility; /* current syslog facility */
++int compatibility_flag = 1; /* version backward compatibility flag.
++ default - work like previous version */
+
+ #ifdef HAVE_PTHREAD
+ pthread_t main_thr;
+@@ -79,7 +81,6 @@
+ static int reconfig_pending;
+ static int watchdog_timeout;
+ static int watchdog_pending;
+-
+ static struct sighandler_ent {
+ int sig;
+ int flags;
+@@ -254,8 +255,7 @@
+ /*
+ * Make pid file.
+ */
+- (void)strcpy(buf, program_name);
+- (void)strcat(buf, ".pid");
++ snprintf(buf, sizeof(buf), "%s/%s.pid", PIDFILE_PATH, program_name);
+ if ((fp = fopen(buf, "w")) != NULL) {
+ fprintf(fp, "%d\n", (int)mypid);
+ fclose(fp);
+@@ -380,7 +380,8 @@
+ #ifdef HAVE_PTHREAD
+ reconfig_pending = 0;
+ #else
+- reconfig_pending = -1;
++ // reconfig_pending = -1;
++ reconfig_pending = 0;
+ #endif
+ }
+ }
+@@ -626,73 +627,159 @@
+ TIMEVAL tv;
+ VARIABLE *var;
+ OBJECT *service;
++ INTERFACE *interface;
++ BGP_AS *bgp;
++ BGP_PEER *bgp_peer;
++ ENV_MON *env;
++ ENV_GAUGE *gauge;
++ char *buf;
++ ssize_t buf_len;
+
+ /* current timestamp */
+ gettimeofday(&tv, NULL);
+-
+ /* save method diagnostic */
+- if (method && diag && (var = get_var(object->var_list, method->name)) != NULL)
+- str2var(var, diag);
+-
+- if (!method || !ok) {
+- /*
+- * Method list aborted or Start Trap received.
+- */
+-
+- /* update object operational status */
+- object->prev_state = object->state;
++ if (method && diag && (var = get_var(object->var_list, method->name)) != NULL) {
++ str2var(var, diag);
++ /* save method return value */
++ buf_len = strlen(method->name)+4;
++ buf = malloc(buf_len);
++ if ( buf ) {
++ snprintf(buf,buf_len,"%s.ok",method->name);
++ if ((var = get_var(object->var_list, buf)) != NULL)
++ set_var(var, INTEGER, &ok, sizeof(ok));
++ free(buf);
++ } else {
++ report(LOG_ERR, "method_finished(%s!):.ok malloc: %m", object->name,method->name);
++ }
++ }
++ if ( compatibility_flag ) {
++ if (!method || !ok) {
+ object->state = STATE_DOWN;
+-
+ if (object->state != object->prev_state)
+ object->last_change = tv;
+-
+ #ifdef DEBUG
+ if (object->prev_state != STATE_DOWN)
+ dprintf(("object \"%s\" change state to DOWN\n", object->name));
+ #endif
+-
+ /* stop anything here */
+ object_stop(object);
+-
+ for (service = object->service; service; service = service->next)
+ object_stop(service);
+
+ set_none_state(object);
+-
+ save_object_state(object);
+-
+ /* stop data saving on the object */
+ remove_event(save_object_data, object);
+-
+ /* keep touching the object if required */
+ if (object->polling > 0) {
+ tv.tv_sec += object->polling / 2;
+ add_event(&tv, start_method_list, object);
+ }
+ return;
+- }
+-
+- if (method->next) {
+- /*
+- * Advance to next object method.
+- */
+-
++ }
++ if (method->next) {
++ method = method->next;
++ (*method->start)(method);
++ return;
++ }
++ object->prev_reply = object->last_reply;
++ object->last_reply = tv; /* last reply timestamp */
++
++ /* update object operational status */
++ object->prev_state = object->state;
++ object->state = STATE_UP;
++
++ } else {
++ if (!method || !ok) {
++ object->mths_fail++;
++ } else {
++ object->mths_ok++;
++ }
++ if (method && method->next) {
++ /* Advance to next object method. */
+ method = method->next;
+ (*method->start)(method);
+ return;
+- }
++ }
++ /* Method list done. */
++ object->prev_reply = object->last_reply;
++ object->last_reply = tv; /* last reply timestamp */
++
++ /* update object operational status */
++ object->prev_state = object->state;
++ if ( object->mths_ok == 0 ) {
++ object->state = STATE_DOWN;
+
+- /*
+- * Method list done.
+- */
++ if (object->state != object->prev_state)
++ object->last_change = tv;
++#ifdef DEBUG
++ if (object->prev_state != STATE_DOWN)
++ dprintf(("object \"%s\" change state to DOWN\n", object->name));
++#endif
++ /* stop anything here */
++ object_stop(object);
+
+- object->prev_reply = object->last_reply;
+- object->last_reply = tv; /* last reply timestamp */
++ for (service = object->service; service; service = service->next)
++ object_stop(service);
+
+- /* update object operational status */
+- object->prev_state = object->state;
+- object->state = STATE_UP;
++ set_none_state(object);
++
++ save_object_state(object);
++
++ /* stop data saving on the object */
++ remove_event(save_object_data, object);
+
++ /* keep touching the object if required */
++ if (object->polling > 0) {
++ tv.tv_sec += object->polling / 2;
++ add_event(&tv, start_method_list, object);
++ }
++ return;
++ } else {
++ if ( object->mths_fail ) {
++ object->state = STATE_DEGRADED;
++ } else {
++ object->state = STATE_UP;
++ for (service = object->service; service; service = service->next) {
++ if (!service->ignore_state && service->state != STATE_UP) {
++ object->state = STATE_WARNING;
++ break;
++ }
++ }
++ for (interface = object->interface; interface; interface = interface->next) {
++ if (!interface->ignore_state && interface->state != STATE_UP) {
++ object->state = STATE_WARNING;
++ break;
++ }
++ }
++ for ( bgp = object->bgp; bgp; bgp = bgp->next) {
++ if (bgp->ignore_state ) continue;
++ for ( bgp_peer = bgp->peer; bgp_peer; bgp_peer=bgp_peer->next) {
++ if ( bgp_peer->state != BGP_ESTABLISHED){
++ object->state = STATE_WARNING;
++ break;
++ }
++ }
++ if (object->state == STATE_WARNING)
++ break;
++ }
++ for (env = object->env; env; env = env->next) {
++ if (env->ignore_state ) continue;
++ for( gauge = env->gauge; gauge; gauge=gauge->next) {
++ if (gauge->state != ENV_NORMAL && gauge->state != ENV_NOTPRESENT ) {
++ object->state = STATE_WARNING;
++ break;
++ }
++ }
++ if (object->state == STATE_WARNING)
++ break;
++ }
++ }
++ }
++ object->mths_ok = 0;
++ object->mths_fail = 0;
++ object->smths_fail = 0;
++ }
+ if (object->state != object->prev_state)
+ object->last_change = tv;
+
+@@ -827,10 +914,25 @@
+ /* child would be terminated by signals */
+ sigprocmask(SIG_SETMASK, NULL, &sigmask);
+ sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
+-
++ close(netstate_sock);
++
+ /* make session leader to be able killpg() latter */
+ setsid();
+
++ if ( cf->chrootdir) {
++ if ( chroot( cf->chrootdir ) < 0 ) {
++ report(LOG_ERR, "chroot %s: %s", cf->chrootdir,strerror(*(__error())) );
++ _exit(127);
++ }
++ }
++ if ( setgid(cf->gid) < 0 ) {
++ report(LOG_ERR, "setgid %s[%d]: %s", cf->groupname, cf->gid, strerror(*(__error())) );
++ _exit(127);
++ }
++ if ( (cf->uid != 0) & (setuid(cf->uid) < 0) ) {
++ report(LOG_ERR, "setuid %s[%d]: %s", cf->username, cf->uid, strerror(*(__error())) );
++ _exit(127);
++ }
+ execve(file, av, environ);
+ report(LOG_ERR, "execve %s: %m", file);
+ _exit(127);
+@@ -928,8 +1030,7 @@
+ #endif
+ {
+ char pidfile[100];
+- (void)strcpy(pidfile, program_name);
+- (void)strcat(pidfile, ".pid");
++ snprintf(pidfile, sizeof(pidfile), "%s/%s.pid", PIDFILE_PATH, program_name);
+ (void)unlink(pidfile);
+ report(LOG_CRIT, "aborted by signal %d", sig);
+ } else report(LOG_INFO, "interrupted by signal %d", sig);
diff --git a/net-mgmt/netmond/files/patch-netstate.c b/net-mgmt/netmond/files/patch-netstate.c
new file mode 100644
index 000000000000..c256b1451a29
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-netstate.c
@@ -0,0 +1,38 @@
+--- netstate.c.orig Tue Aug 26 10:54:09 2003
++++ netstate.c Thu Nov 2 13:35:27 2006
+@@ -128,7 +128,7 @@
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(cf->ns_port);
+- sin.sin_addr.s_addr = INADDR_ANY;
++ sin.sin_addr = cf->ns_ip_addr;
+ if (bind(netstate_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ report(LOG_ERR, "bind port %d: %m", ntohs(sin.sin_port));
+ close(netstate_sock);
+@@ -405,6 +405,14 @@
+ _exit(1);
+ }
+ #endif
++int
++iskoi8(unsigned char ch)
++{
++ if ( ch == 163 ) return 1;
++ if ( ch == 179 ) return 1;
++ if ( ch >= 192 ) return 1;
++ return 0;
++}
+
+ void *
+ netstate_serve(arg)
+@@ -505,9 +513,9 @@
+ set_timer(0, interrupt);
+ #endif
+ if (!cp) break;
+- while (isprint(*cp)) cp++;
++ while ( iskoi8(*cp) || isprint(*cp) ) cp++;
+ *cp = '\0';
+-
++
+ next = input;
+ if ((cp = my_strsep(&next, " ")) == NULL) {
+ bad_input++;
diff --git a/net-mgmt/netmond/files/patch-parseconf.y b/net-mgmt/netmond/files/patch-parseconf.y
new file mode 100644
index 000000000000..4ab921f1552e
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-parseconf.y
@@ -0,0 +1,489 @@
+--- parseconf.y.orig Tue Aug 26 10:53:30 2003
++++ parseconf.y Thu Dec 28 13:31:06 2006
+@@ -13,6 +13,7 @@
+ #endif
+
+ #include <sys/types.h>
++#include <sys/limits.h>
+ #include <netinet/in.h>
+ #include <arpa/inet.h>
+ #include <stdio.h>
+@@ -117,6 +118,7 @@
+ first_save = NULL;
+
+ global_var_list = 0;
++ config.compatibility_flag = 1;
+ }
+
+ static char *
+@@ -197,11 +199,37 @@
+ BGP_AS *bgp;
+ ENV_MON *env;
+ char *cp, buf[1024];
++ struct passwd *pwentry;
++ struct group *grentry;
+
+ if (!config.rootdir) {
+ report(LOG_ERR, "%s: rootdir unspecified", config_file);
+ return NULL;
+ }
++ compatibility_flag = config.compatibility_flag;
++ if (!config.srcaddress)
++ bzero(&config.ip_srcaddr, sizeof(struct in_addr));
++ if (!config.ns_address)
++ bzero(&config.ns_ip_addr, sizeof(struct in_addr));
++ if (!config.trap_address)
++ bzero(&config.trap_ip_addr, sizeof(struct in_addr));
++
++ if(!config.username) {
++ config.username = strdup(USERNAME);
++ if ((pwentry = getpwnam(USERNAME)) == (struct passwd *) NULL) {
++ report(LOG_ERR, "Bad default username: %s.",config.username);
++ return NULL;
++ }
++ config.uid = pwentry->pw_uid;
++ }
++ if(!config.groupname) {
++ config.groupname = strdup(GROUPNAME);
++ if ((grentry = getgrnam(GROUPNAME)) == (struct group *) NULL) {
++ report(LOG_ERR, "Bad default groupname: %s.",config.groupname);
++ return NULL;
++ }
++ config.gid = (gid_t)grentry->gr_gid;
++ }
+ if (config.polling) {
+ if (!config.timeout)
+ config.timeout = TIMEOUT_DEFAULT;
+@@ -273,6 +301,7 @@
+
+ for (service = target->service; service; service = service->next) {
+ service->ip_addr = target->ip_addr;
++ service->ip_srcaddr = target->ip_srcaddr;
+ service->parent = target;
+
+ (void)strcpy(cp, "/");
+@@ -329,6 +358,8 @@
+ METHOD *method;
+ CHATSCRIPT *cs;
+ REFERENCE *ref;
++ char *buf;
++ ssize_t buf_len;
+
+ /* sanity check */
+ if (!chain || !item) {
+@@ -362,6 +393,16 @@
+ yyerror("Out of memory");
+ return 0;
+ }
++ buf_len = strlen(method->name)+4 ;
++ buf = malloc( buf_len );
++ if (buf)
++ snprintf(buf,buf_len,"%s.ok",method->name);
++ if (!buf || !add_var(&curr->var_list, buf)) {
++ yyerror("Out of memory");
++ return 0;
++ }
++ free(buf);
++
+ /* bind variable references */
+ for (cs = method->chatscript; cs; cs = cs->next) {
+ for (ref = cs->var_ref; ref; ref = ref->next) {
+@@ -854,7 +895,7 @@
+ }
+ /* check for duplicates */
+ for (curr = *chain; curr; curr = curr->next) {
+- if (!strcasecmp(curr->name, item->name)) {
++ if ( chain == &first_save && !strcasecmp(curr->name, item->name)) {
+ yyerror("save name \"%s\" duplicated", item->name);
+ return 0;
+ }
+@@ -901,7 +942,9 @@
+ char *argument;
+ {
+ METHOD *new;
+-
++ char arg_list[1024], *av[MAX_ARGS+2];
++ int ac = 0;
++
+ if ((new = (METHOD *)malloc(sizeof(METHOD))) == NULL) {
+ yyerror("Out of memory");
+ return NULL;
+@@ -915,10 +958,24 @@
+ yyerror("Out of memory");
+ return 0;
+ }
+- if (argument)
++ if (argument) {
+ new->argument = argument;
+- else if (new->argument)
++ (void)strncpy(arg_list, argument, sizeof(arg_list));
++ arg_list[sizeof(arg_list)-1] = '\0';
++ } else if (new->argument) {
+ new->argument = strdup(new->argument);
++ (void)strncpy(arg_list, new->argument, sizeof(arg_list));
++ arg_list[sizeof(arg_list)-1] = '\0';
++ } else arg_list[0] = '\0';
++ av[ac++] = new->name;
++ ac += make_argv(arg_list, (char ***)&av[ac], MAX_ARGS);
++ av[ac] = NULL;
++
++ if (new->when && (new->when = insert_args(new->when, av, ac)) == NULL)
++ return NULL;
++ if (new->when_fmt && (new->when_fmt = insert_args(new->when_fmt, av, ac)) == NULL)
++ return NULL;
++
+ if (new->chatscript) {
+ new->chatscript = dup_chatscript(new->name, new->argument, new->chatscript);
+ if (!new->chatscript) return NULL;
+@@ -1342,11 +1399,15 @@
+
+ /* Lexical analyzer return values */
+ %token TOKEN_ROOTDIR
++%token TOKEN_CHROOTDIR
++%token TOKEN_USERNAME
++%token TOKEN_GROUPNAME
+ %token TOKEN_TIMEFMT
+ %token TOKEN_POLLING
+ %token TOKEN_SAVING
+ %token TOKEN_TIMEOUT
+ %token TOKEN_RETRIES
++%token TOKEN_OMULSTATES
+
+ %token TOKEN_GROUP
+ %token TOKEN_PERMIT
+@@ -1354,6 +1415,7 @@
+
+ %token TOKEN_NETSTATE
+ %token TOKEN_PORT
++%token TOKEN_BINDADDRESS
+
+ %token TOKEN_SAVE
+ %token TOKEN_FILE
+@@ -1365,6 +1427,7 @@
+
+ %token TOKEN_OBJECT
+ %token TOKEN_ADDRESS
++%token TOKEN_SRCADDRESS
+ %token TOKEN_DESCRIPTION
+ %token TOKEN_SERVICE
+ %token TOKEN_INTERFACE
+@@ -1398,11 +1461,13 @@
+ %token TOKEN_V2
+
+ %token TOKEN_TRAP
++%token TOKEN_TRAPBINDADDRESS
+ %token TOKEN_SOURCECHECK
+ %token TOKEN_COMMUNITY
+ %token TOKEN_ENTERPRISE
+ %token TOKEN_SPECIFIC
+ %token TRAP_GENERIC
++%token TOKEN_IGNORESTATE
+
+ %token <number> TOKEN_NUMBER
+ %token <string> TOKEN_STRING
+@@ -1410,7 +1475,7 @@
+ %token <string> VAR_OID
+
+ %type <number> optional_number
+-%type <string> optional_string quoted_string legal_string multiline_string
++%type <string> optional_string quoted_string legal_string multiline_string optional_multiline_string
+ %type <save> get_save
+ %type <method> get_method
+ %type <trap> get_trap
+@@ -1442,6 +1507,60 @@
+ YYABORT;
+ }
+ }
++ | TOKEN_CHROOTDIR quoted_string
++ {
++ if (config.chrootdir) {
++ yyerror("ChRootDir statement duplicated");
++ YYABORT;
++ }
++ config.chrootdir = $2;
++ }
++ | TOKEN_USERNAME quoted_string
++ {
++ struct passwd *pwentry;
++
++ if (config.username) {
++ yyerror("UserName statement duplicated");
++ YYABORT;
++ }
++ if ((pwentry = getpwnam($2)) == (struct passwd *)NULL) {
++ yyerror("UserName %s unknown.", $2);
++ YYABORT;
++ }
++ config.uid = pwentry->pw_uid;
++ config.username = $2;
++ }
++
++ | TOKEN_GROUPNAME quoted_string
++ {
++ struct group *grentry;
++
++ if (config.groupname) {
++ yyerror("GroupName statement duplicated");
++ YYABORT;
++ }
++ if ((grentry = getgrnam($2)) == (struct group *)NULL) {
++ yyerror("GroupName %s unknown.", $2);
++ YYABORT;
++ }
++ config.gid = grentry->gr_gid;
++ config.groupname = $2;
++ }
++
++ | TOKEN_SRCADDRESS quoted_string
++ {
++ struct in_addr ip_srcaddr;
++
++ if (config.srcaddress) {
++ yyerror("config source address duplicated");
++ YYABORT;
++ }
++ if (!gethostaddr(&ip_srcaddr, $2)) {
++ YYABORT;
++ }
++ config.srcaddress = $2;
++ memcpy(&config.ip_srcaddr, &ip_srcaddr, sizeof(struct in_addr));
++ }
+ | TOKEN_TIMEFMT quoted_string
+ {
+ if (config.timefmt) {
+@@ -1485,6 +1604,10 @@
+ }
+ config.retries = $2;
+ }
++ | TOKEN_OMULSTATES
++ {
++ config.compatibility_flag = 0;
++ }
+ | TOKEN_NETSTATE '{' netstate_config '}'
+ {
+ if (!config.ns_port) {
+@@ -1531,6 +1654,17 @@
+ {
+ config.source_traps = 1;
+ }
++ | TOKEN_TRAPBINDADDRESS quoted_string
++ {
++ if (config.trap_address) {
++ yyerror("bindaddress duplicated");
++ YYABORT;
++ }
++ if (!gethostaddr(&config.trap_ip_addr, $2)) {
++ YYABORT;
++ }
++ config.trap_address = $2;
++ }
+ | TOKEN_TRAP legal_string '{' trap_config '}'
+ {
+ trap.name = $2;
+@@ -1556,6 +1690,13 @@
+ yyerror("object address unspecified");
+ YYABORT;
+ }
++ if (!object.srcaddress) {
++ if (!config.srcaddress) {
++ bzero(&object.ip_srcaddr, sizeof(struct in_addr));
++ } else {
++ memcpy(&object.ip_srcaddr, &config.ip_srcaddr, sizeof(struct in_addr));
++ }
++ }
+ /* if ((object.interface || object.ifgroup ||
+ object.bgp || object.env) &&
+ !find_method(object.method_list, "ROUTER")) {
+@@ -1637,6 +1778,17 @@
+ YYABORT;
+ }
+ }
++ | TOKEN_BINDADDRESS quoted_string
++ {
++ if (config.ns_address) {
++ yyerror("bindaddress duplicated");
++ YYABORT;
++ }
++ if (!gethostaddr(&config.ns_ip_addr, $2)) {
++ YYABORT;
++ }
++ config.ns_address = $2;
++ }
+ | TOKEN_PERMIT quoted_string
+ {
+ /* for backward compatibility */
+@@ -1701,7 +1853,7 @@
+ }
+ save.state = $2;
+ }
+- | TOKEN_WHEN multiline_string TOKEN_NUMBER optional_string
++ | TOKEN_WHEN multiline_string TOKEN_NUMBER optional_multiline_string
+ {
+ if (save.when) {
+ yyerror("save when condition duplicated");
+@@ -1763,6 +1915,19 @@
+ method.start = echo_start;
+ method.stop = echo_stop;
+ }
++ | TOKEN_PIPE quoted_string
++ {
++ if (method.protocol) {
++ yyerror("method protocol duplicated");
++ YYABORT;
++ }
++ method.protocol = PIPE_PROTO;
++ method.when = $2;
++ method.init = pipe_init;
++ method.start = pipe_start;
++ method.stop = tcp_stop;
++ method.retries = 1;
++ }
+ | TOKEN_PORT TOKEN_NUMBER
+ {
+ if (method.protocol &&
+@@ -1808,12 +1973,30 @@
+ }
+ }
+ }
++ | TOKEN_WHEN multiline_string TOKEN_NUMBER optional_multiline_string
++ {
++ method.protocol = WHEN_PROTO;
++ if (method.when) {
++ yyerror("Method 'when condition' duplicated");
++ YYABORT;
++ }
++ method.init = when_init;
++ method.start = when_start;
++ method.stop = when_stop;
++ method.when = $2;
++ method.timeout = $3;
++ method.when_fmt = $4;
++ }
+ | TOKEN_TIMEOUT TOKEN_NUMBER
+ {
+ if (method.timeout) {
+ yyerror("timeout statement duplicated");
+ YYABORT;
+ }
++ if (method.protocol == WHEN_PROTO) {
++ yyerror("timeout was defined in WHEN statement");
++ YYABORT;
++ }
+ if ($2 < 1 || $2 > POLLING_MIN) {
+ yyerror("invalid timeout value (min 1 max %d sec.)",
+ POLLING_MIN);
+@@ -1827,6 +2010,10 @@
+ yyerror("retries statement duplicated");
+ YYABORT;
+ }
++ if (method.protocol == PIPE_PROTO) {
++ yyerror("no retries possible in PIPE method");
++ YYABORT;
++ }
+ if ($2 < 1 || $2 > POLLING_MIN) {
+ yyerror("invalid retries number (min 1 max %d)",
+ POLLING_MIN);
+@@ -1838,7 +2025,8 @@
+ {
+ if (method.protocol &&
+ method.protocol != IPPROTO_TCP &&
+- method.protocol != IPPROTO_UDP) {
++ method.protocol != IPPROTO_UDP &&
++ method.protocol != PIPE_PROTO) {
+ yyerror("no suitable method protocol");
+ YYABORT;
+ }
+@@ -2095,6 +2283,18 @@
+ }
+ object.address = $2;
+ }
++ | TOKEN_SRCADDRESS quoted_string
++ {
++ if (object.srcaddress) {
++ yyerror("object source address duplicated");
++ YYABORT;
++ }
++ if (!gethostaddr(&object.ip_srcaddr, $2)) {
++ YYABORT;
++ }
++ object.srcaddress = $2;
++ }
++
+ | TOKEN_POLLING TOKEN_NUMBER
+ {
+ if (object.polling) {
+@@ -2241,7 +2441,7 @@
+ }
+ | TOKEN_INTERFACE TOKEN_NUMBER
+ {
+- if ($2 < 1 || $2 > 65535) {
++ if ($2 < 1 || $2 > INT_MAX) {
+ yyerror("interface index out of range");
+ YYABORT;
+ }
+@@ -2252,7 +2452,7 @@
+ }
+ | TOKEN_INTERFACE TOKEN_NUMBER '{' interface_config '}'
+ {
+- if ($2 < 1 || $2 > 65535) {
++ if ($2 < 1 || $2 > INT_MAX ) {
+ yyerror("interface index out of range");
+ YYABORT;
+ }
+@@ -2473,6 +2673,10 @@
+ YYABORT;
+ }
+ }
++ | TOKEN_IGNORESTATE
++ {
++ subobject.ignore_state = 1;
++ }
+ ;
+
+ interface_config: /* empty */
+@@ -2530,6 +2734,10 @@
+ YYABORT;
+ }
+ }
++ | TOKEN_IGNORESTATE
++ {
++ interface.ignore_state = 1;
++ }
+ ;
+
+ bgp_config: /* empty */
+@@ -2580,6 +2788,10 @@
+ }
+ free($2);
+ }
++ | TOKEN_IGNORESTATE
++ {
++ bgp_as.ignore_state = 1;
++ }
+ ;
+
+ env_config: /* empty */
+@@ -2629,6 +2841,10 @@
+ YYABORT;
+ }
+ }
++ | TOKEN_IGNORESTATE
++ {
++ env_mon.ignore_state = 1;
++ }
+ ;
+
+ get_save: legal_string optional_string
+@@ -2918,6 +3134,12 @@
+ $$ = NULL;
+ }
+ | quoted_string
++ ;
++optional_multiline_string:
++ {
++ $$ = NULL;
++ }
++ | multiline_string
+ ;
+
+ %%
diff --git a/net-mgmt/netmond/files/patch-ping.c b/net-mgmt/netmond/files/patch-ping.c
new file mode 100644
index 000000000000..e593b8c43c98
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-ping.c
@@ -0,0 +1,103 @@
+--- ping.c.orig Fri Aug 22 11:07:53 2003
++++ ping.c Thu Dec 28 13:31:06 2006
+@@ -352,7 +352,8 @@
+ dprintf(("check_netpath(%s)\n", target->name));
+
+ for (nexthop = target->nexthop; nexthop; nexthop = nexthop->next) {
+- if ((nexthop->target && nexthop->target->state != STATE_UP) ||
++ if ((nexthop->target && nexthop->target->state == STATE_UNKNOWN) ||
++ (nexthop->target && nexthop->target->state == STATE_DOWN) ||
+ (nexthop->interface && nexthop->interface->state != STATE_UP))
+ return 0;
+ }
+@@ -368,6 +369,7 @@
+ u_char buf[MAX_PACKETSZ];
+ struct ip *ip;
+ struct icmp *icmp;
++ struct sockaddr_in *from = (struct sockaddr_in *)&sd->me;
+ struct sockaddr_in *to = (struct sockaddr_in *)&sd->peer;
+ int header_len = sizeof(struct ip);
+ int total_len = method->rport ? method->rport : MIN_PACKETSZ;
+@@ -400,7 +402,7 @@
+ #endif
+ ip->ip_ttl = IPDEFTTL;
+ ip->ip_p = IPPROTO_ICMP;
+- /* ip->ip_src <-- filled by kernel (hopefulness) */
++ ip->ip_src = from->sin_addr; /* replaced by kernel if=INADDR_ANY (hopefulness) */
+ ip->ip_dst = to->sin_addr;
+
+ if (rr_opt) { /* IP Option: Record Route */
+@@ -423,6 +425,7 @@
+ memcpy(icmp->icmp_data, &sd->buf, sizeof(TIMEVAL *));
+
+ icmp->icmp_cksum = in_cksum((u_short *)icmp, total_len - header_len);
++
+ #ifdef NO_ICMP_ERRORS
+ total_len = send(sd->sock, (char *)buf, total_len, 0);
+ #else
+@@ -600,6 +603,8 @@
+ {
+ SESSION *sd = method->sd;
+ int tmpval;
++ char ipaddr[20];
++ struct sockaddr_in *from;
+
+ /* sanity check */
+ if (!sd) return;
+@@ -616,6 +621,13 @@
+ echo_reply(errno, sd, 0);
+ return;
+ }
++ /* bind RAW socket to local source address */
++ from = (struct sockaddr_in *)&sd->me;
++ if ( from->sin_addr.s_addr != INADDR_ANY ) {
++ if( bind(sd->sock, &sd->me, sizeof(struct sockaddr) ) == -1 )
++ report(LOG_WARNING, "echo_start : bind failed for %s: %s",
++ intoa(ipaddr,from->sin_addr), strerror(*(__error())) );
++ }
+ #ifdef SO_BSDCOMPAT
+ /* The following option is only necessary on Linux machines because
+ * they have the unusual behavior of returning some ICMP errors to
+@@ -701,7 +713,12 @@
+ if (sd->pkt_recv > 1) msec /= (double)sd->pkt_recv;
+ sprintf(buf, "%g", msec);
+ diag = buf;
+- } else diag = "0.000";
++ if ( msec >= 10 ) {
++ sprintf(buf, "%d", (int)msec);
++ } else {
++ sprintf(buf, "%g", msec);
++ }
++ } else diag = "0.0";
+ } else {
+ op = -1;
+ diag = icmp_error(sd->data_int);
+@@ -740,8 +757,9 @@
+ METHOD *method;
+ {
+ SESSION template;
+- struct sockaddr_in *to;
++ struct sockaddr_in *to, *from;
+ char varname[100];
++ char ipaddr[20];
+
+ dprintf(("echo_init(%s/%s)\n", target->name, method->name));
+
+@@ -758,6 +776,9 @@
+ to = (struct sockaddr_in *)&template.peer;
+ to->sin_family = AF_INET;
+ to->sin_addr = method->address ? method->ip_addr : target->ip_addr;
++ from = (struct sockaddr_in *)&template.me;
++ from->sin_family = AF_INET;
++ from->sin_addr = target->ip_srcaddr;
+ template.timeout = method->timeout * 1000000L; /* make microseconds */
+ template.retries = method->retries;
+ template.send = echo_send;
+@@ -798,6 +819,7 @@
+ IPPROTO_ICMP, /* network protocol */
+ 0, /* no packet size for built-in method */
+ 0, 0, /* timeout and retries undefined yet */
++ NULL,NULL, /* when variables unused */
+ { 1, 1 }, /* send/expect packet counter */
+
+ /* Non-initialized data */
diff --git a/net-mgmt/netmond/files/patch-radius.c b/net-mgmt/netmond/files/patch-radius.c
new file mode 100644
index 000000000000..ff600dd10987
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-radius.c
@@ -0,0 +1,62 @@
+--- radius.c.orig Mon Aug 25 18:20:03 2003
++++ radius.c Mon Nov 13 16:58:49 2006
+@@ -33,7 +33,7 @@
+ * RADIUS specification according to RFC2138.
+ */
+
+-#define RADIUSSERVER_PORT 1645 /* 1812 suggested */
++#define RADIUSSERVER_PORT 1812 /* 1812 suggested */
+ #define HEADER_LEN 20
+ #define MIN_PACKETSZ HEADER_LEN
+ #define MAX_PACKETSZ 4096
+@@ -208,6 +208,8 @@
+ {
+ SESSION *sd = method->sd;
+ int reqid;
++ struct sockaddr_in *from;
++ char ipaddr[20];
+
+ /* sanity check */
+ if (!sd) return;
+@@ -220,6 +222,13 @@
+ return;
+ }
+
++ /* bind socket to local source address */
++ from = (struct sockaddr_in *)&sd->me;
++ if ( from->sin_addr.s_addr != INADDR_ANY ) {
++ if( bind(sd->sock, &sd->me, sizeof(struct sockaddr) ) == -1 )
++ report(LOG_WARNING, "radius_start : bind failed for %s: %s",
++ intoa(ipaddr,from->sin_addr), strerror(*(__error())) );
++ }
+ /* turn on non-blocking I/O */
+ if (set_socket_async(sd->sock, TRUE) < 0) {
+ radius_reply(errno, sd, 0);
+@@ -311,7 +320,7 @@
+ METHOD *method;
+ {
+ SESSION template;
+- struct sockaddr_in *to;
++ struct sockaddr_in *to, *from;
+
+ dprintf(("radius_init(%s/%s)\n", target->name, method->name));
+
+@@ -326,6 +335,10 @@
+ to->sin_family = AF_INET;
+ to->sin_port = htons(method->rport);
+ to->sin_addr = method->address ? method->ip_addr : target->ip_addr;
++ from = (struct sockaddr_in *)&template.me;
++ bzero((char *)from, sizeof(struct sockaddr_in));
++ from->sin_family = AF_INET;
++ from->sin_addr = target->ip_srcaddr;
+ template.timeout = method->timeout * 1000000L; /* make microseconds */
+ template.retries = method->retries;
+ template.send = radius_send;
+@@ -355,6 +368,7 @@
+ IPPROTO_UDP, /* network protocol */
+ RADIUSSERVER_PORT, /* server port */
+ 0, 0, /* timeout and retries undefined yet */
++ NULL,NULL, /* when variables unused */
+ { 0, 0 }, /* no parameters used */
+
+ /* Non-initialized data */
diff --git a/net-mgmt/netmond/files/patch-reconfig.c b/net-mgmt/netmond/files/patch-reconfig.c
new file mode 100644
index 000000000000..d98356a5cc09
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-reconfig.c
@@ -0,0 +1,135 @@
+--- reconfig.c.orig Tue Aug 26 10:54:37 2003
++++ reconfig.c Thu Dec 28 13:31:06 2006
+@@ -175,6 +175,7 @@
+
+ rescan = (old->bandwidth != new->bandwidth); /* to force rescan */
+ old->bandwidth = new->bandwidth;
++ old->ignore_state = new->ignore_state;
+
+ splice_var_list(&old->var_list, &new->var_list);
+
+@@ -260,6 +261,7 @@
+
+ /* setup new list of peers */
+ old->handconf = new->handconf;
++ old->ignore_state = new->ignore_state;
+ free_bgp_peers(old, 1);
+ old->peer = new->peer;
+ new->peer = NULL;
+@@ -340,6 +342,7 @@
+
+ /* setup new list of peers */
+ old->handconf = new->handconf;
++ old->ignore_state = new->ignore_state;
+ free_env_gauges(old, 1);
+ old->gauge = new->gauge;
+ new->gauge = NULL;
+@@ -395,7 +398,7 @@
+ OBJECT *parent;
+ OBJECT *old, *new;
+ {
+- void *ip_addr;
++ void *ip_addr, *ip_srcaddr;
+ OBJECT *service;
+
+ object_stop(old);
+@@ -403,9 +406,13 @@
+ ptrswap(&old->descr, &new->descr);
+ ptrswap(&old->datadir, &new->datadir);
+ ptrswap(&old->address, &new->address);
+- if (parent)
++ if (parent) {
+ ip_addr = &parent->ip_addr;
+- else ip_addr = &new->ip_addr;
++ ip_srcaddr = &parent->ip_srcaddr;
++ } else {
++ ip_addr = &new->ip_addr;
++ ip_srcaddr = &new->ip_srcaddr;
++ }
+ old->parent = parent;
+
+ if (memcmp(&old->ip_addr, ip_addr, sizeof(old->ip_addr))) {
+@@ -418,6 +425,8 @@
+ memset(old->snmpdata, 0, sizeof(SNMP_DATA));
+ }
+ }
++ if (memcmp(&old->ip_srcaddr, ip_srcaddr, sizeof(old->ip_srcaddr)))
++ memcpy(&old->ip_srcaddr, ip_srcaddr, sizeof(old->ip_srcaddr));
+
+ old->polling = new->polling;
+ old->saving = new->saving;
+@@ -450,6 +459,8 @@
+ service = splice_object_list(old, &old->service, &new->service);
+ for (; service; service = service->next) {
+ service->ip_addr = old->ip_addr;
++ service->ip_srcaddr = old->ip_srcaddr;
++ service->ignore_state = old->ignore_state;
+ service->parent = old;
+ object_init(service);
+ }
+@@ -516,21 +527,42 @@
+ }
+ if (cf_new->rootdir) free(cf_new->rootdir);
+
++ ptrswap(&cf->chrootdir, &cf_new->chrootdir);
++ if (cf_new->chrootdir) free(cf_new->chrootdir);
++
++ ptrswap(&cf->username, &cf_new->username);
++ if (cf_new->username) free(cf_new->username);
++ cf->uid = cf_new->uid;
++
++ ptrswap(&cf->groupname, &cf_new->groupname);
++ if (cf_new->groupname) free(cf_new->groupname);
++ cf->gid = cf_new->gid;
++
+ ptrswap(&cf->timefmt, &cf_new->timefmt);
+ if (cf_new->timefmt) free(cf_new->timefmt);
+
++ ptrswap(&cf->srcaddress, &cf_new->srcaddress);
++ if (cf_new->srcaddress) free(cf_new->srcaddress);
++ memcpy( &cf->ip_srcaddr, &cf_new->ip_srcaddr, sizeof(struct in_addr));
+ cf->polling = cf_new->polling;
+ cf->saving = cf_new->saving;
+ cf->timeout = cf_new->timeout;
+ cf->retries = cf_new->retries;
++ compatibility_flag = cf->compatibility_flag = cf_new->compatibility_flag;
+
+- if (cf->enable_traps != cf_new->enable_traps) {
++ if ((cf->enable_traps != cf_new->enable_traps) || memcmp(&cf->trap_ip_addr, &cf_new->trap_ip_addr, sizeof(struct in_addr)) ) {
++ ptrswap(&cf->trap_address, &cf_new->trap_address);
++ if (cf_new->trap_address) free(cf_new->trap_address);
++ memcpy( &cf->trap_ip_addr, &cf_new->trap_ip_addr, sizeof(struct in_addr));
+ cf->enable_traps = cf_new->enable_traps;
+ trap_init(cf->enable_traps > 0);
+ }
+ cf->source_traps = cf_new->source_traps;
+
+- if (cf->ns_port != cf_new->ns_port) {
++ if ((cf->ns_port != cf_new->ns_port) || memcmp(&cf->ns_ip_addr, &cf_new->ns_ip_addr, sizeof(struct in_addr))) {
++ ptrswap(&cf->ns_address, &cf_new->ns_address);
++ if (cf_new->ns_address) free(cf_new->ns_address);
++ memcpy( &cf->ns_ip_addr, &cf_new->ns_ip_addr, sizeof(struct in_addr));
+ cf->ns_port = cf_new->ns_port;
+ netstate_init(cf->ns_port);
+ }
+@@ -576,6 +608,12 @@
+ free_object_list(cf_cur->target);
+
+ if (cf_cur->rootdir) free(cf_cur->rootdir);
++ if (cf_cur->chrootdir) free(cf_cur->chrootdir);
++ if (cf_cur->username) free(cf_cur->username);
++ if (cf_cur->groupname) free(cf_cur->groupname);
++ if (cf_cur->srcaddress) free(cf_cur->srcaddress);
++ if (cf_cur->ns_address) free(cf_cur->ns_address);
++ if (cf_cur->trap_address) free(cf_cur->trap_address);
+ if (cf_cur->timefmt) free(cf_cur->timefmt);
+
+ trap_init(cf_cur->enable_traps > 0);
+@@ -649,6 +687,7 @@
+ if (obj->descr) free(obj->descr);
+ if (obj->datadir) free(obj->datadir);
+ if (obj->address) free(obj->address);
++ if (obj->srcaddress) free(obj->srcaddress);
+ free_trap_list(obj->trap_list);
+ free_var_list(obj->var_list);
+ free_save_list(obj->save_list);
diff --git a/net-mgmt/netmond/files/patch-regex.c b/net-mgmt/netmond/files/patch-regex.c
new file mode 100644
index 000000000000..7060dfb720b3
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-regex.c
@@ -0,0 +1,54 @@
+--- regex.c.orig Mon Feb 24 14:52:12 2003
++++ regex.c Thu Nov 2 13:35:27 2006
+@@ -554,12 +554,12 @@
+ * the bitset form, since we may wish to extend it
+ * in the future for other character classifications.
+ *
+- * TRUE for 0-9 A-Z a-z _
++ * TRUE for 0-9 A-Z a-z _ Á-Ñ á-ñ
+ */
+ static char chrtyp[MAXCHR] = {
+- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
+@@ -569,10 +569,23 @@
+ 1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+- 1, 1, 1, 0, 0, 0, 0, 0
++ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, // 120-129
++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 130-139
++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 140-149
++ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, // 160-169 163=£
++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, // 170-179 179=³
++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 180-189
++ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, // 190-199
++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 200-209
++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 210-219
++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 220-229
++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 230-239
++ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 240-249
++ 1, 1, 1, 1, 1, 1 // 250-255
+ };
+
+-#define inascii(x) (0177&(x))
++//#define inascii(x) (0177&(x))
++#define inascii(x) (0255&(x))
+ #define iswordc(x) chrtyp[inascii(x)]
+ #define isinset(x, y) ((x)[((y)&BLKIND)>>3] & (1<<((y)&BITIND)))
+
+@@ -583,7 +596,7 @@
+
+ #define ANYSKIP 2 /* CLO ANY END ... */
+ #define CHRSKIP 3 /* CLO CHR chr END ... */
+-#define CCLSKIP 18 /* CLO CCL 16bytes END ... */
++#define CCLSKIP BITBLK+2 /* CLO CCL 32bytes END ... */
+
+ static char *
+ pmatch(prog, lp, ap)
diff --git a/net-mgmt/netmond/files/patch-regex.h b/net-mgmt/netmond/files/patch-regex.h
new file mode 100644
index 000000000000..c45dd5e2747e
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-regex.h
@@ -0,0 +1,17 @@
+--- regex.h.orig Mon Feb 24 14:39:49 2003
++++ regex.h Thu Nov 2 13:38:39 2006
+@@ -21,12 +21,12 @@
+ */
+ #define MAXDFA 1024
+ #define MAXTAG 10
+-#define MAXCHR 128
++#define MAXCHR 256
+ #define CHRBIT 8
+ #define BITBLK MAXCHR/CHRBIT
+ #define BLKIND 0170
+ #define BITIND 07
+-#define ASCIIB 0177
++#define ASCIIB 0255
+
+ typedef /*unsigned*/ char CHAR;
+
diff --git a/net-mgmt/netmond/files/patch-router.c b/net-mgmt/netmond/files/patch-router.c
new file mode 100644
index 000000000000..2eb2219ca321
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-router.c
@@ -0,0 +1,62 @@
+--- router.c.orig Mon Aug 25 16:07:07 2003
++++ router.c Thu Dec 28 13:31:06 2006
+@@ -309,6 +309,7 @@
+ for (group_ref = proto->ns_acl; group_ref; group_ref = group_ref->next)
+ add_group_ref_copy(&iface->ns_acl, group_ref);
+
++ iface->ignore_state = proto->ignore_state;
+ if (last)
+ last->next = iface;
+ else object->interface = iface;
+@@ -2214,6 +2215,8 @@
+ METHOD *method;
+ {
+ SESSION *sd = method->sd;
++ struct sockaddr_in *from;
++ char ipaddr[20];
+
+ /* sanity check */
+ if (!sd) {
+@@ -2229,7 +2232,13 @@
+ router_reply(errno, sd, 0);
+ return;
+ }
+-
++ /* bind socket to local source address */
++ from = (struct sockaddr_in *)&sd->me;
++ if ( from->sin_addr.s_addr != INADDR_ANY ) {
++ if( bind(sd->sock, &sd->me, sizeof(struct sockaddr) ) == -1 )
++ report(LOG_WARNING, "router_start : bind failed for %s: %s",
++ intoa(ipaddr,from->sin_addr), strerror(*(__error())) );
++ }
+ /* turn on non-blocking I/O */
+ if (set_socket_async(sd->sock, TRUE) < 0) {
+ router_reply(errno, sd, 0);
+@@ -2306,7 +2315,7 @@
+ METHOD *method;
+ {
+ SESSION template;
+- struct sockaddr_in *to;
++ struct sockaddr_in *to, *from;
+
+ dprintf(("router_init(%s/%s)\n", target->name, method->name));
+
+@@ -2321,6 +2330,10 @@
+ to->sin_family = AF_INET;
+ to->sin_port = htons(method->rport);
+ to->sin_addr = method->address ? method->ip_addr : target->ip_addr;
++ from = (struct sockaddr_in *)&template.me;
++ bzero((char *)from, sizeof (struct sockaddr_in));
++ from->sin_family = AF_INET;
++ from->sin_addr = target->ip_srcaddr;
+ template.timeout = method->timeout * 1000000L; /* make microseconds */
+ template.retries = method->retries;
+ template.send = snmp_send;
+@@ -2359,6 +2372,7 @@
+ IPPROTO_UDP, /* network protocol */
+ SNMPSERVER_PORT,/* server port */
+ 0, 0, /* timeout and retries undefined yet */
++ NULL,NULL, /* when variables unused */
+ { SNMP_VERSION_1, /* version number */
+ BATCH_DEFAULT },/* batch value */
+
diff --git a/net-mgmt/netmond/files/patch-scanconf.l b/net-mgmt/netmond/files/patch-scanconf.l
new file mode 100644
index 000000000000..ae2bc50376e1
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-scanconf.l
@@ -0,0 +1,92 @@
+--- scanconf.l.orig Thu Sep 18 09:59:48 2003
++++ scanconf.l Thu Dec 28 13:31:06 2006
+@@ -88,11 +88,15 @@
+
+ /* token names */
+ ROOTDIR [Rr]oot[Dd]ir
++CHROOTDIR [Cc]h[Rr]oot[Dd]ir
++USERNAME [Uu]ser[Nn]ame
++GROUPNAME [Gg]roup[Nn]ame
+ TIMEFMT [Tt]ime[Ff]mt
+ POLLING [Pp]olling
+ SAVING [Ss]aving
+ TIMEOUT [Tt]imeout
+ RETRIES [Rr]etries
++OMULSTATES [Oo]bject[Mm]ultiple[Ss]tates
+
+ GROUP [Gg]roup
+ PERMIT [Pp]ermit
+@@ -111,6 +115,8 @@
+
+ OBJECT [Oo]bject
+ ADDRESS [Aa]ddress
++SRCADDRESS [Ss]rc[Aa]ddress
++BINDADDRESS [Bb]ind[Aa]ddress
+ DESCRIPTION [Dd]escription|[Cc]omment
+ SERVICE [Ss]ervice
+ INTERFACE [Ii]nterface
+@@ -144,11 +150,13 @@
+ V2 [Vv]2
+
+ TRAP [Tt]rap
++TRAPBINDADDRESS [Tt]rap[Bb]ind[Aa]ddress
+ SOURCECHECK [Ss]ource[Cc]heck
+ COMMUNITY [Cc]ommunity
+ ENTERPRISE [Ee]nterprise
+ SPECIFIC [Ss]pecific
+ GENERIC GENERIC|[Gg]eneric
++IGNORESTATE [Ii]gnore[Ss]tate
+
+ LETTER [a-zA-Z]
+ DIGIT [0-9]
+@@ -186,6 +194,12 @@
+
+ {ROOTDIR} { return TOKEN_ROOTDIR; }
+
++{USERNAME} { return TOKEN_USERNAME; }
++
++{GROUPNAME} { return TOKEN_GROUPNAME; }
++
++{CHROOTDIR} { return TOKEN_CHROOTDIR; }
++
+ {TIMEFMT} { return TOKEN_TIMEFMT; }
+
+ {POLLING} { return TOKEN_POLLING; }
+@@ -196,6 +210,8 @@
+
+ {RETRIES} { return TOKEN_RETRIES; }
+
++{OMULSTATES} { return TOKEN_OMULSTATES; }
++
+ {GROUP} { return TOKEN_GROUP; }
+
+ {PERMIT} { return TOKEN_PERMIT; }
+@@ -224,6 +240,10 @@
+
+ {ADDRESS} { return TOKEN_ADDRESS; }
+
++{SRCADDRESS} { return TOKEN_SRCADDRESS; }
++
++{BINDADDRESS} { return TOKEN_BINDADDRESS; }
++
+ {DESCRIPTION} { return TOKEN_DESCRIPTION; }
+
+ {SERVICE} { return TOKEN_SERVICE; }
+@@ -286,6 +306,8 @@
+
+ {TRAP} { return TOKEN_TRAP; }
+
++{TRAPBINDADDRESS} { return TOKEN_TRAPBINDADDRESS; }
++
+ {SOURCECHECK} { return TOKEN_SOURCECHECK; }
+
+ {COMMUNITY} { return TOKEN_COMMUNITY; }
+@@ -295,6 +317,8 @@
+ {SPECIFIC} { return TOKEN_SPECIFIC; }
+
+ {GENERIC} { return TRAP_GENERIC; }
++
++{IGNORESTATE} { return TOKEN_IGNORESTATE; }
+
+ \${LETTER}({LETTER}|{DIGIT}|_)+(\.{DIGIT}+)* {
+ yylval.string = &yytext[1];
diff --git a/net-mgmt/netmond/files/patch-session.c b/net-mgmt/netmond/files/patch-session.c
new file mode 100644
index 000000000000..1b5b938be566
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-session.c
@@ -0,0 +1,34 @@
+--- session.c.orig Sat Aug 2 11:26:38 2003
++++ session.c Thu Nov 2 13:35:27 2006
+@@ -59,6 +59,7 @@
+ curr_session->method = template->method;
+ curr_session->sock = template->sock;
+ curr_session->peer = template->peer;
++ curr_session->me = template->me;
+ curr_session->timeout = template->timeout;
+ curr_session->retries = template->retries;
+ curr_session->connect = template->connect;
+@@ -302,7 +303,6 @@
+ int active = 0, pending = 0;
+
+ timerclear(&earliest);
+-
+ /*
+ * For each request outstanding, add it's socket to the readfds,
+ * and if it is the earliest timeout to expire, mark it as lowest.
+@@ -352,7 +352,6 @@
+ int reqid;
+ {
+ REQUEST *sr;
+-
+ if (reqid == 0) /* for single request per session (like tcp or icmp) */
+ return sd->request;
+
+@@ -443,7 +442,6 @@
+ int reqid;
+
+ gettimeofday(&now, NULL);
+-
+ /*
+ * For each request outstanding, check to see if it has expired.
+ */
diff --git a/net-mgmt/netmond/files/patch-snmp.c b/net-mgmt/netmond/files/patch-snmp.c
new file mode 100644
index 000000000000..04759120ca90
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-snmp.c
@@ -0,0 +1,54 @@
+--- snmp.c.orig Tue Jul 20 17:51:25 2004
++++ snmp.c Thu Nov 2 13:35:27 2006
+@@ -1214,6 +1214,8 @@
+ {
+ SESSION *sd = method->sd;
+ int reqid;
++ struct sockaddr_in *from;
++ char ipaddr[20];
+
+ /* sanity check */
+ if (!sd) return;
+@@ -1225,7 +1227,13 @@
+ snmp_reply(errno, sd, 0);
+ return;
+ }
+-
++ /* bind datagram socket to local source address */
++ from = (struct sockaddr_in *)&sd->me;
++ if ( from->sin_addr.s_addr != INADDR_ANY ) {
++ if( bind(sd->sock, &sd->me, sizeof(struct sockaddr) ) == -1 )
++ report(LOG_WARNING, "snmp_start : bind failed for %s: %s",
++ intoa(ipaddr,from->sin_addr), strerror(*(__error())) );
++ }
+ /* turn on non-blocking I/O */
+ if (set_socket_async(sd->sock, TRUE) < 0) {
+ snmp_reply(errno, sd, 0);
+@@ -1290,7 +1298,7 @@
+ METHOD *method;
+ {
+ SESSION template;
+- struct sockaddr_in *to;
++ struct sockaddr_in *to, *from;
+
+ dprintf(("snmp_init(%s/%s)\n", target->name, method->name));
+
+@@ -1305,6 +1313,10 @@
+ to->sin_family = AF_INET;
+ to->sin_port = htons(method->rport);
+ to->sin_addr = method->address ? method->ip_addr : target->ip_addr;
++ from = (struct sockaddr_in *)&template.me;
++ bzero((char *)from, sizeof(struct sockaddr_in ));
++ from->sin_family = AF_INET;
++ from->sin_addr = target->ip_srcaddr;
+ template.timeout = method->timeout * 1000000L; /* make microseconds */
+ template.retries = method->retries;
+ template.send = snmp_send;
+@@ -1334,6 +1346,7 @@
+ IPPROTO_UDP, /* network protocol */
+ SNMPSERVER_PORT,/* server port */
+ 0, 0, /* timeout and retries undefined yet */
++ NULL,NULL, /* when variables unused */
+ { SNMP_VERSION_1,/* version number */
+ 0 }, /* no parameter used */
+
diff --git a/net-mgmt/netmond/files/patch-tacacs.c b/net-mgmt/netmond/files/patch-tacacs.c
new file mode 100644
index 000000000000..0822f150c062
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-tacacs.c
@@ -0,0 +1,53 @@
+--- tacacs.c.orig Mon Aug 25 18:20:41 2003
++++ tacacs.c Thu Nov 2 13:35:27 2006
+@@ -302,6 +302,8 @@
+ {
+ SESSION *sd = method->sd;
+ int reqid;
++ struct sockaddr_in *from;
++ char ipaddr[20];
+
+ /* sanity check */
+ if (!sd) return;
+@@ -314,6 +316,13 @@
+ return;
+ }
+
++ /* bind socket to local source address */
++ from = (struct sockaddr_in *)&sd->me;
++ if ( from->sin_addr.s_addr != INADDR_ANY ) {
++ if( bind(sd->sock, &sd->me, sizeof(struct sockaddr) ) == -1 )
++ report(LOG_WARNING, "tacacs_start : bind failed for %s: %s",
++ intoa(ipaddr,from->sin_addr), strerror(*(__error())) );
++ }
+ /* turn on non-blocking I/O before connecting */
+ if (set_socket_async(sd->sock, TRUE) < 0) {
+ tacacs_reply(errno, sd, 0);
+@@ -415,7 +424,7 @@
+ METHOD *method;
+ {
+ SESSION template;
+- struct sockaddr_in *to;
++ struct sockaddr_in *to, *from;
+
+ dprintf(("tacacs_init(%s/%s)\n", target->name, method->name));
+
+@@ -430,6 +439,10 @@
+ to->sin_family = AF_INET;
+ to->sin_port = htons(method->rport);
+ to->sin_addr = method->address ? method->ip_addr : target->ip_addr;
++ from = (struct sockaddr_in *)&template.me;
++ bzero((char *)from, sizeof(struct sockaddr_in));
++ from->sin_family = AF_INET;
++ from->sin_addr = target->ip_srcaddr;
+ template.timeout = method->timeout * 1000000L; /* make microseconds */
+ template.retries = method->retries;
+ template.connect = tacacs_connect;
+@@ -460,6 +473,7 @@
+ IPPROTO_TCP, /* network protocol */
+ TACACSSERVER_PORT, /* server port */
+ 0, 0, /* timeout and retries undefined yet */
++ NULL,NULL, /* when variables unused */
+ { 0, 0 }, /* no parameters used */
+
+ /* Non-initialized data */
diff --git a/net-mgmt/netmond/files/patch-tcp.c b/net-mgmt/netmond/files/patch-tcp.c
new file mode 100644
index 000000000000..6f95352a51fa
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-tcp.c
@@ -0,0 +1,128 @@
+--- tcp.c.orig Wed Sep 17 12:55:52 2003
++++ tcp.c Thu Nov 2 13:35:27 2006
+@@ -16,6 +16,7 @@
+ #include <netinet/in.h>
+ #include <stdio.h>
+ #include <string.h>
++#include <signal.h>
+ #include <unistd.h>
+ #include <syslog.h>
+ #include <errno.h>
+@@ -30,12 +31,10 @@
+
+ extern int errno;
+
+-static void tcp_close __P((int, SESSION *, int));
+-
+ /*
+ * Check to see if an TCP connection established at this session.
+ */
+-static int
++int
+ tcp_connect(sd)
+ SESSION *sd;
+ {
+@@ -89,7 +88,7 @@
+ /*
+ * Send the data through TCP session.
+ */
+-static int
++int
+ tcp_send(sd, request)
+ SESSION *sd;
+ REQUEST *request;
+@@ -191,7 +190,7 @@
+ /*
+ * Receive data through TCP session.
+ */
+-static int
++int
+ tcp_recv(sd)
+ SESSION *sd;
+ {
+@@ -319,6 +318,8 @@
+ {
+ SESSION *sd = method->sd;
+ int tmpval;
++ struct sockaddr_in *from;
++ char ipaddr[20];
+
+ /* sanity check */
+ if (!sd) return;
+@@ -330,17 +331,13 @@
+ tcp_close(errno, sd, 0);
+ return;
+ }
+-
++ from = (struct sockaddr_in *)&sd->me;
+ /* allocate local port if required */
+ if (method->lport_min) {
+- struct sockaddr_in sin;
+-
+- sin.sin_family = AF_INET;
+- sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ tmpval = method->lport_min;
+ do {
+- sin.sin_port = htons((u_short)tmpval);
+- if (!bind(sd->sock, (struct sockaddr *)&sin, sizeof(sin))) {
++ from->sin_port = htons((u_short)tmpval);
++ if (!bind(sd->sock, &sd->me, sizeof(struct sockaddr))) {
+ tmpval = 0;
+ break;
+ }
+@@ -354,6 +351,13 @@
+ tcp_close(EAGAIN, sd, 0);
+ return;
+ }
++ } else {
++ /* bind socket to local source address */
++ if ( from->sin_addr.s_addr != INADDR_ANY ) {
++ if( bind(sd->sock, &sd->me, sizeof(struct sockaddr) ) == -1 )
++ report(LOG_WARNING, "tcp_start : bind failed for %s: %s",
++ intoa(ipaddr,from->sin_addr), strerror(*(__error())) );
++ }
+ }
+
+ /* turn on non-blocking I/O before connecting */
+@@ -378,7 +382,7 @@
+ }
+ }
+
+-static void
++void
+ tcp_close(op, sd, reqid)
+ int op;
+ SESSION *sd;
+@@ -414,6 +418,7 @@
+ dump_var_list(target->var_list);
+
+ tcp_stop(method);
++ if ((method->sd)->pid > 0) { kill((method->sd)->pid, SIGTERM); (method->sd)->pid=-1; }
+
+ method_finished(target, method, diag, !op);
+ }
+@@ -424,7 +429,7 @@
+ METHOD *method;
+ {
+ SESSION template;
+- struct sockaddr_in *to;
++ struct sockaddr_in *to, *from;
+
+ dprintf(("tcp_init(%s/%s)\n", target->name, method->name));
+
+@@ -435,10 +440,15 @@
+ template.owner = target;
+ template.method = method;
+ template.sock = -1; /* not yet opened */
++ template.pid = -1;
+ to = (struct sockaddr_in *)&template.peer;
+ to->sin_family = AF_INET;
+ to->sin_port = htons(method->rport);
+ to->sin_addr = method->address ? method->ip_addr : target->ip_addr;
++ from = (struct sockaddr_in *)&template.me;
++ bzero((char *)from, sizeof(struct sockaddr_in));
++ from->sin_family = AF_INET;
++ from->sin_addr = target->ip_srcaddr;
+ template.timeout = method->timeout * 1000000L; /* make microseconds */
+ template.retries = method->retries;
+ template.connect = tcp_connect;
diff --git a/net-mgmt/netmond/files/patch-trap.c b/net-mgmt/netmond/files/patch-trap.c
new file mode 100644
index 000000000000..30e4835e5235
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-trap.c
@@ -0,0 +1,35 @@
+--- trap.c.orig Thu Aug 21 09:45:25 2003
++++ trap.c Thu Nov 2 13:35:27 2006
+@@ -40,9 +40,10 @@
+ {
+ static struct sockaddr_in sin;
+
++ if (trap_sock != -1) /* already enabled */
++ close(trap_sock);
++
+ if (enable) {
+- if (trap_sock != -1) /* already enabled */
+- return 0;
+
+ if ((trap_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ report(LOG_ERR, "socket: %m");
+@@ -51,17 +52,15 @@
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_port = htons(SNMPTRAP_PORT);
+- sin.sin_addr.s_addr = INADDR_ANY;
++ sin.sin_addr = cf->trap_ip_addr;
+ if (bind(trap_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+ report(LOG_ERR, "bind port %d: %m", ntohs(sin.sin_port));
+ close(trap_sock);
+ trap_sock = -1;
+ return -1;
+ }
+- } else if (trap_sock != -1) {
+- close(trap_sock);
++ } else
+ trap_sock = -1;
+- }
+ return 0;
+ }
+
diff --git a/net-mgmt/netmond/files/patch-udp.c b/net-mgmt/netmond/files/patch-udp.c
new file mode 100644
index 000000000000..a08ca866284a
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-udp.c
@@ -0,0 +1,66 @@
+--- udp.c.orig Sat Aug 2 11:40:56 2003
++++ udp.c Thu Nov 2 13:35:27 2006
+@@ -197,6 +197,8 @@
+ {
+ SESSION *sd = method->sd;
+ int tmpval;
++ struct sockaddr_in *from;
++ char ipaddr[20];
+
+ /* sanity check */
+ if (!sd) return;
+@@ -208,17 +210,13 @@
+ udp_close(errno, sd, 0);
+ return;
+ }
+-
++ from = (struct sockaddr_in *)&sd->me;
+ /* allocate local port if required */
+ if (method->lport_min) {
+- struct sockaddr_in sin;
+-
+- sin.sin_family = AF_INET;
+- sin.sin_addr.s_addr = htonl(INADDR_ANY);
+ tmpval = method->lport_min;
+ do {
+- sin.sin_port = htons((u_short)tmpval);
+- if (!bind(sd->sock, (struct sockaddr *)&sin, sizeof(sin))) {
++ from->sin_port = htons((u_short)tmpval);
++ if (!bind(sd->sock, &sd->me, sizeof(struct sockaddr))) {
+ tmpval = 0;
+ break;
+ }
+@@ -232,6 +230,13 @@
+ udp_close(EAGAIN, sd, 0);
+ return;
+ }
++ } else {
++ /* bind socket to local source address */
++ if ( from->sin_addr.s_addr != INADDR_ANY ) {
++ if( bind(sd->sock, &sd->me, sizeof(struct sockaddr) ) == -1 )
++ report(LOG_WARNING, "udp_start : bind failed for %s: %s",
++ intoa(ipaddr,from->sin_addr), strerror(*(__error())) );
++ }
+ }
+
+ /* turn on non-blocking I/O */
+@@ -298,7 +303,7 @@
+ METHOD *method;
+ {
+ SESSION template;
+- struct sockaddr_in *to;
++ struct sockaddr_in *to, *from;
+
+ dprintf(("udp_init(%s/%s)\n", target->name, method->name));
+
+@@ -313,6 +318,10 @@
+ to->sin_family = AF_INET;
+ to->sin_port = htons(method->rport);
+ to->sin_addr = method->address ? method->ip_addr : target->ip_addr;
++ from = (struct sockaddr_in *)&template.me;
++ bzero((char *)from, sizeof(struct sockaddr_in));
++ from->sin_family = AF_INET;
++ from->sin_addr = target->ip_srcaddr;
+ template.timeout = method->timeout * 1000000L; /* make microseconds */
+ template.retries = method->retries;
+ template.send = udp_send;
diff --git a/net-mgmt/netmond/files/patch-util.c b/net-mgmt/netmond/files/patch-util.c
new file mode 100644
index 000000000000..c253b3888efb
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-util.c
@@ -0,0 +1,131 @@
+--- util.c.orig Tue Aug 26 10:53:17 2003
++++ util.c Thu Dec 28 13:31:06 2006
+@@ -275,6 +275,8 @@
+ if (method->address) free(method->address);
+ if (method->sd) session_free(method->sd);
+ if (method->chatscript) free_chatscript(method->chatscript);
++ if (method->when) free(method->when);
++ if (method->when_fmt) free(method->when_fmt);
+ if (method->snmpreq) {
+ free_var_ref(method->snmpreq->var_ref);
+ free(method->snmpreq);
+@@ -1236,11 +1238,9 @@
+ if (method->address)
+ printf("%s\tAddress = \"%s\" [%s]\n", prepend,
+ method->address, intoa(ipaddr, method->ip_addr));
+- if ((proto = getprotobynumber(method->protocol)) == NULL) {
+- printf("%s\tUnknown protocol %d\n", prepend, method->protocol);
+- continue;
++ if ((proto = getprotobynumber(method->protocol)) != NULL) {
++ printf("%s\t%s ", prepend, proto->p_name);
+ }
+- printf("%s\t%s ", prepend, proto->p_name);
+ switch (method->protocol) {
+ case IPPROTO_ICMP:
+ if (method->rport)
+@@ -1265,6 +1265,14 @@
+ printf("..%d", method->lport_max);
+ }
+ break;
++ case WHEN_PROTO:
++ printf("%s\tWHEN = \"%s\"",prepend, method->when);
++ printf(" delay = %d sec.", method->timeout);
++ printf(" Report Format = \"%s\"", method->when_fmt);
++ break;
++ case PIPE_PROTO:
++ printf("%s\tPIPE programm = \"%s\"",prepend, method->when);
++ break;
+ default:
+ printf("Unsupported");
+ }
+@@ -1409,22 +1417,36 @@
+ if (cf->saving > 0)
+ printf("Saving = %d sec.\n", cf->saving);
+ else printf("Saving disabled\n");
++ if (cf->compatibility_flag > 0)
++ printf("Compatibility flag SET\n");
++ else printf("Compatibility flag NOT SET\n");
+
+ print_group_list("", cf->group_list);
+
+ printf("NetState %s\n", cf->ns_port ? "enabled" : "disabled");
+ if (cf->ns_port) {
+ printf("\tPort = %d\n", cf->ns_port);
++ if (cf->ns_address)
++ printf("\tBindAddress = \"%s\" [%s]\n", cf->ns_address, intoa(ipaddr, cf->ns_ip_addr));
+ #ifndef HAVE_PTHREAD
+ printf("\tTimeout = %d sec.\n", cf->ns_timo);
+ #endif
+ print_group_ref("\t", cf->ns_acl);
+ }
++ printf("SrcAddress = \"%s\" [%s]\n", (cf->srcaddress!=NULL ) ? cf->srcaddress : "default",
++ intoa(ipaddr, cf->ip_srcaddr));
++
++ printf("UserName = \"%s\" [%d]\n", cf->username, cf->uid);
++ printf("GroupName = \"%s\" [%d]\n", cf->groupname, cf->gid);
+
++ if (cf->chrootdir)
++ printf("ChRootDir = \"%s\"\n", cf->chrootdir );
+ printf("Traps ");
+ if (cf->enable_traps > 0) {
+ printf("enabled");
+ if (cf->source_traps > 0) printf(" (sourcecheck)");
++ if (cf->trap_address)
++ printf("\n\tTrapBindAddress = \"%s\" [%s]", cf->trap_address, intoa(ipaddr, cf->trap_ip_addr));
+ } else printf("disabled");
+ printf("\n");
+
+@@ -1434,6 +1456,8 @@
+ printf("\tDescription = \"%s\"\n", target->descr);
+ printf("\tAddress = \"%s\" [%s]\n", target->address,
+ intoa(ipaddr, target->ip_addr));
++ printf("\tSrcAddress = \"%s\" [%s]\n", (target->srcaddress!=NULL) ? target->srcaddress : "default",
++ intoa(ipaddr, target->ip_srcaddr));
+ if (target->polling > 0)
+ printf("\tPolling = %d sec.\n", target->polling);
+ else printf("\tPolling disabled\n");
+@@ -1463,6 +1487,8 @@
+ if (iface->ns_acl)
+ print_group_ref("\t\tNetState ", iface->ns_acl);
+ else printf("\t\tNetState Group = free access\n");
++ if (iface->ignore_state)
++ printf("\t\tIgnoreState flag set.\n");
+ print_var_list("\t\t", iface->var_list);
+ print_save_list("\t\t", iface->save_list);
+ }
+@@ -1475,6 +1501,8 @@
+ if (iface->ns_acl)
+ print_group_ref("\t\tNetState ", iface->ns_acl);
+ else printf("\t\tNetState Group = free access\n");
++ if (iface->ignore_state)
++ printf("\t\tIgnoreState flag set.\n");
+ print_var_list("\t\t", iface->var_list);
+ print_save_list("\t\t", iface->save_list);
+ }
+@@ -1495,6 +1523,8 @@
+ if (bgp->ns_acl)
+ print_group_ref("\t\tNetState ", bgp->ns_acl);
+ else printf("\t\tNetState Group = free access\n");
++ if (bgp->ignore_state)
++ printf("\t\tIgnoreState flag set.\n");
+ print_save_list("\t\t", bgp->save_list);
+ }
+
+@@ -1514,6 +1544,8 @@
+ if (env->ns_acl)
+ print_group_ref("\t\tNetState ", env->ns_acl);
+ else printf("\t\tNetState Group = free access\n");
++ if (env->ignore_state)
++ printf("\t\tIgnoreState flag set.\n");
+ print_save_list("\t\t", env->save_list);
+ }
+
+@@ -1524,6 +1556,8 @@
+ if (service->ns_acl)
+ print_group_ref("\t\tNetState ", service->ns_acl);
+ else printf("\t\tNetState Group = free access\n");
++ if (service->ignore_state)
++ printf("\t\tIgnoreState flag set.\n");
+ print_var_list("\t\t", service->var_list);
+ print_method_list("\t\t", service->method_list);
+ print_trap_list("\t\t", service->trap_list);
diff --git a/net-mgmt/netmond/files/patch-variables.c b/net-mgmt/netmond/files/patch-variables.c
new file mode 100644
index 000000000000..3c01f588c478
--- /dev/null
+++ b/net-mgmt/netmond/files/patch-variables.c
@@ -0,0 +1,39 @@
+--- variables.c.orig Tue Aug 26 10:55:14 2003
++++ variables.c Thu Nov 2 13:35:27 2006
+@@ -39,8 +39,8 @@
+ static char buf[BUFSIZ];
+ static char *strbuf = NULL;
+
+-static char *obj_states[2] = {
+- "UP", "DOWN" };
++static char *obj_states[4] = {
++ "UP", "DOWN","DEGRADED","WARNING" };
+ static char *if_states[5] = {
+ "UP", "DOWN", "TESTING", "UNKNOWN", "DORMANT" };
+ static char *bgp_states[6] = {
+@@ -52,7 +52,7 @@
+ int size;
+ char **name;
+ } states[4] = {
+- { 2, obj_states },
++ { 4, obj_states },
+ { 5, if_states },
+ { 6, bgp_states },
+ { 5, env_states },
+@@ -69,7 +69,7 @@
+
+ sp = &states[what];
+ if (!state)
+- cp = "NONE";
++ cp = "UNKNOWN";
+ else if (state > 0 && state <= sp->size)
+ cp = sp->name[state-1];
+ else cp = "ERROR";
+@@ -1511,6 +1511,7 @@
+ }
+ memcpy(var, vb, len);
+ var[len] = '\0';
++
+ len = 0;
+ next = var;
+ while ((vb = my_strsep(&next, "!")) != NULL) {
diff --git a/net-mgmt/netmond/files/pipe.c b/net-mgmt/netmond/files/pipe.c
index e7e5725e91b4..b18eb7454ebe 100644
--- a/net-mgmt/netmond/files/pipe.c
+++ b/net-mgmt/netmond/files/pipe.c
@@ -166,6 +166,7 @@ pipe_execfile(file, args, p_pid, target)
/* child would be terminated by signals */
sigprocmask(SIG_SETMASK, NULL, &sigmask);
sigprocmask(SIG_UNBLOCK, &sigmask, NULL);
+ close(netstate_sock);
/* make session leader to be able killpg() latter */
setsid();
diff --git a/net-mgmt/netmond/files/pkg-message.in b/net-mgmt/netmond/files/pkg-message.in
index 6016ddde285a..812e7831019f 100644
--- a/net-mgmt/netmond/files/pkg-message.in
+++ b/net-mgmt/netmond/files/pkg-message.in
@@ -5,7 +5,7 @@
You need to create a configuration file netmond.conf
in directory %%PREFIX%%/etc prior to launch netmond.
- Look at http://soft.risp.ru/netmond/ for the configuration guide
- or try to use net-mgmt/TkNetmon to create configuration semiautomatically.
+ Look at %%PREFIX%%/share/doc/netmond/ for the configuration guide
+ or try to use net-mgmt/tknetmon to create configuration semiautomatically.
######################################################################
diff --git a/net-mgmt/netmond/pkg-descr b/net-mgmt/netmond/pkg-descr
index 758300053832..9c4f21d5c5cb 100644
--- a/net-mgmt/netmond/pkg-descr
+++ b/net-mgmt/netmond/pkg-descr
@@ -3,7 +3,7 @@ Can check hosts availability (via ICMP ping), collect SNMP counters,
check simple TCP/UDP services (with internal chat), handle SNMP traps.
GUI frontends exist for netmond:
- - net-mgmt/TkNetmon ( tcl/tk )
+ - net-mgmt/tknetmon ( tcl/tk )
- ftp://ftp.risp.ru/RinetSoft/netmond-spyboat-0.5.tgz ( with QT )
WWW: http://soft.risp.ru/netmond/