--- 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 #include #include +#include +#include +#include #ifdef DEBUG_MEMORY #include #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 +#include #include #include #include @@ -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 TOKEN_NUMBER %token TOKEN_STRING @@ -1410,7 +1475,7 @@ %token VAR_OID %type optional_number -%type optional_string quoted_string legal_string multiline_string +%type optional_string quoted_string legal_string multiline_string optional_multiline_string %type get_save %type get_method %type 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 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_DMALLOC_H +#include +#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 #include #include +#include #include #include #include @@ -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) {