freebsd-ports/net-mgmt/netmond/files/patch-AA
Rene Ladan 1510b743f2 Bring net-mgmt/netmond back into shape.
From PR submitter:
- Fix build (partially)
- Clean up patches
- Unexpire
- Mark jobs unsafe
- Bump PORTREVISION

From myself:
- Stage support, introduce pkg-plist
- Use option helpers
- Convert patch site for documentation into an optional distribution file

PR:		ports/186654
Submitted by:	Vsevolod Volkov <vvv@colocall.net>
2014-03-07 16:20:41 +00:00

2390 lines
66 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--- 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
--- 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 */
--- 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);
--- 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 *));
--- 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);
--- 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++;
--- 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
;
%%
--- 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 */
--- /dev/null 2014-03-07 15:59:00.000000000 +0200
+++ pipe.c 2014-01-24 02:14:07.000000000 +0200
@@ -0,0 +1,273 @@
+/*
+ * Copyright (c) 1999-2002 Rinet Corp., Novosibirsk, Russia
+ * partial (c) vfom@narod.ru
+ *
+ * Redistribution and use in source forms, with and without modification,
+ * are permitted provided that this entire comment appears intact.
+ *
+ * THIS SOURCE CODE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <errno.h>
+#ifdef HAVE_DMALLOC_H
+#include <dmalloc.h>
+#else
+#include "malloc.h"
+#endif
+#include "assert.h"
+
+#include "netmon.h"
+#include "regex.h"
+
+extern int errno;
+extern CONFIG *cf; /* current configuration */
+
+static int pipe_execfile __P ((char *, char *,pid_t *, OBJECT *));
+
+void
+pipe_start(method)
+ METHOD *method;
+{
+ SESSION *sd = method->sd;
+ OBJECT *target = sd->owner;
+ int tmpval;
+
+ /* sanity check */
+ if (!sd) return;
+
+ tcp_stop(method); /* stop the method if still running */
+ if ((method->sd)->pid > 0) { kill((method->sd)->pid, SIGTERM); }
+ sd->pid = -1;
+
+ /* open stream socket near before TCP session */
+ if ((sd->sock = pipe_execfile(method->when, method->argument, &(sd->pid), target)) < 0) {
+ tcp_close(errno, sd, 0);
+ return;
+ }
+
+ /* turn on non-blocking I/O before connecting */
+ if (set_socket_async(sd->sock, TRUE) < 0) {
+ tcp_close(errno, sd, 0);
+ if ((method->sd)->pid > 0) { kill((method->sd)->pid, SIGTERM); }
+ return;
+ }
+
+ /* timeout and retries for connection */
+ sd->timeout = method->timeout * 1000000L; /* make miscroseconds */
+ sd->retries = method->retries;
+ sd->connect = tcp_connect; /* `awaiting' connection */
+
+ if ((tmpval = session_start(sd, NULL)) != 0) {
+ dprintf(("pipe_start(%s/%s): reqid=%d\n",
+ sd->owner->name, method->name, tmpval));
+//report(LOG_INFO, "pipe_start(%s/%s): reqid=%d\n",
+// sd->owner->name, method->name, tmpval);
+ }
+}
+
+int
+pipe_init(target, method)
+ OBJECT *target;
+ METHOD *method;
+{
+ SESSION template;
+
+ dprintf(("pipe_init(%s/%s)\n", target->name, method->name));
+// report(LOG_INFO,"pipe_init(%s/%s)\n", target->name, method->name);
+
+ if (method->sd)
+ session_free(method->sd);
+
+ memset(&template, 0, sizeof(template));
+ template.owner = target;
+ template.method = method;
+ template.sock = -1; /* not yet opened */
+ template.pid = -1;
+ template.timeout = method->timeout * 1000000L; /* make microseconds */
+ template.retries = method->retries;
+ template.connect = tcp_connect;
+ template.send = tcp_send;
+ template.recv = tcp_recv;
+ template.read = tcp_close;
+
+ if ((method->sd = session_create(&template)) == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ return 0;
+}
+
+#define MAX_ARGS 50
+int
+pipe_execfile(file, args, p_pid, target)
+ char *file, *args;
+ pid_t *p_pid;
+ OBJECT *target;
+{
+ sigset_t sigmask;
+ int ac = 0, fildes[2];
+ char *av[MAX_ARGS+2];
+ extern char **environ;
+ pid_t pid;
+
+ dprintf(("pipe_execfile: %s %s\n", file, args ? args : "null"));
+// report(LOG_INFO,"pipe_execfile: %s %s\n", file, args ? args : "null");
+
+ if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fildes) < 0) {
+ report(LOG_ERR, "socketpair: %m");
+ return(-1);
+ }
+
+ if (*file != '/') {
+ av[ac++] = "sh";
+ av[ac++] = "-c";
+ av[ac++] = file;
+#ifdef _PATH_BSHELL
+ file = _PATH_BSHELL;
+#else
+ file = "/bin/sh";
+#endif
+ } else av[ac++] = strippath(file);
+
+ ac += make_argv(args, (char ***) &av[ac], MAX_ARGS);
+ av[ac] = NULL;
+
+ switch (pid=vfork()) {
+ case -1:
+ report(LOG_ERR, "fork: %m");
+ close(fildes[0]);
+ close(fildes[1]);
+ return(-1);
+ case 0: /* child */
+ if (fcntl(fildes[0], F_SETFD, 0) < 0) {
+ report(LOG_ERR," fcntl (F_SETFD, 0): %m");
+ _exit(127);
+ }
+ if (fildes[0] != 0) {
+ dup2(fildes[0], 0);
+ close(fildes[0]);
+ }
+ dup2(0, 1);
+ dup2(0, 2);
+
+ /* 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);
+ }
+
+ setenv ("OBJECT_NAME",target->name,1 );
+ setenv ("OBJECT_ADDRESS",target->address,1 );
+ if (target->srcaddress)
+ setenv ("OBJECT_SRC_ADDRESS",target->srcaddress,1 );
+ if (target->datadir)
+ setenv ("OBJECT_DATADIR",target->datadir,1 );
+ execve(file, av, environ);
+ report(LOG_ERR, "execve %s: %m", file);
+ _exit(127);
+ }
+ /* parent */
+ if ( p_pid != NULL ) { *p_pid = pid; };
+ close(fildes[0]);
+ return(fildes[1]);
+}
+
+void
+when_stop(method)
+ METHOD *method;
+{
+// session_stop(method->sd, 1);
+}
+
+void
+when_start(method)
+ METHOD *method;
+{
+ SESSION *sd = method->sd;
+ OBJECT *target = sd->owner;
+ TIMEVAL tv_now;
+
+ char *diag, buf[4096];
+ int tmpval, matched;
+
+ /* sanity check */
+ if (!sd) return;
+
+ sd->sock=-1;
+
+ /* calculate condition */
+ insert_variables(buf, sizeof(buf), method->when, TYPE_OBJECT, target);
+ matched = (calculate(buf) ? 1 : 0);
+// report(LOG_WARNING, "when_start EVAL: '%s' %d %s %d",buf,matched,target->name,sd->tv_sum.tv_sec);
+ diag = "OK" ;
+ if ( matched ) {
+ gettimeofday(&tv_now,NULL);
+ if ( (u_int64_t)sd->tv_sum.tv_sec != 0 ) {
+ if ( ( (u_int64_t)(tv_now.tv_sec) - (u_int64_t)(sd->tv_sum.tv_sec) ) > method->timeout ) {
+ insert_variables(buf, sizeof(buf), method->when_fmt, TYPE_OBJECT, target);
+ diag = buf;
+ }
+ } else {
+ sd->tv_sum.tv_sec = tv_now.tv_sec;
+ matched = 0;
+ }
+ } else {
+ sd->tv_sum.tv_sec=0;
+ }
+// report(LOG_WARNING, "when_start DIAG: '%s' %d %d",diag,matched,sd->tv_sum.tv_sec);
+
+ dump_var_list(target->var_list);
+ method_finished(target, method, diag, !matched);
+}
+
+int
+when_init(target, method)
+ OBJECT *target;
+ METHOD *method;
+{
+ SESSION template;
+ dprintf(("when_init(%s/%s)\n", target->name, method->name));
+
+ if (method->sd)
+ session_free(method->sd);
+
+ memset(&template, 0, sizeof(template));
+ template.owner = target;
+ template.method = method;
+ template.sock = -1; /* never used socket */
+ if ((method->sd = session_create(&template)) == NULL) {
+ errno = ENOMEM;
+ return -1;
+ }
+ return 0;
+}
--- 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 */
--- 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);
--- 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)
--- 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;
--- 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 */
--- 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];
--- 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.
*/
--- 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 */
--- 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 */
--- 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;
--- 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;
}
--- 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;
--- 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);
--- 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) {