diff options
Diffstat (limited to 'lib/agentx.c')
| -rw-r--r-- | lib/agentx.c | 447 | 
1 files changed, 223 insertions, 224 deletions
diff --git a/lib/agentx.c b/lib/agentx.c index 11d5c9385d..c36e642c89 100644 --- a/lib/agentx.c +++ b/lib/agentx.c @@ -16,7 +16,7 @@   * You should have received a copy of the GNU General Public License   * along with GNU Zebra; see the file COPYING.  If not, write to the Free   * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA.   + * 02111-1307, USA.   */  #include <zebra.h> @@ -41,131 +41,137 @@ static struct list *events = NULL;  static void agentx_events_update(void); -static int -agentx_timeout(struct thread *t) +static int agentx_timeout(struct thread *t)  { -  timeout_thr = NULL; +	timeout_thr = NULL; -  snmp_timeout (); -  run_alarms (); -  netsnmp_check_outstanding_agent_requests (); -  agentx_events_update (); -  return 0; +	snmp_timeout(); +	run_alarms(); +	netsnmp_check_outstanding_agent_requests(); +	agentx_events_update(); +	return 0;  } -static int -agentx_read(struct thread *t) +static int agentx_read(struct thread *t)  { -  fd_set fds; -  struct listnode *ln = THREAD_ARG (t); -  list_delete_node (events, ln); +	fd_set fds; +	struct listnode *ln = THREAD_ARG(t); +	list_delete_node(events, ln); -  FD_ZERO (&fds); -  FD_SET (THREAD_FD (t), &fds); -  snmp_read (&fds); +	FD_ZERO(&fds); +	FD_SET(THREAD_FD(t), &fds); +	snmp_read(&fds); -  netsnmp_check_outstanding_agent_requests (); -  agentx_events_update (); -  return 0; +	netsnmp_check_outstanding_agent_requests(); +	agentx_events_update(); +	return 0;  } -static void -agentx_events_update(void) +static void agentx_events_update(void)  { -  int maxfd = 0; -  int block = 1; -  struct timeval timeout = { .tv_sec = 0, .tv_usec = 0 }; -  fd_set fds; -  struct listnode *ln; -  struct thread *thr; -  int fd, thr_fd; - -  THREAD_OFF (timeout_thr); - -  FD_ZERO (&fds); -  snmp_select_info (&maxfd, &fds, &timeout, &block); - -  if (!block) -    timeout_thr = thread_add_timer_tv (agentx_tm, agentx_timeout, NULL, &timeout); - -  ln = listhead (events); -  thr = ln ? listgetdata (ln) : NULL; -  thr_fd = thr ? THREAD_FD (thr) : -1; - -  /* "two-pointer" / two-list simultaneous iteration -   * ln/thr/thr_fd point to the next existing event listener to hit while -   * fd counts to catch up */ -  for (fd = 0; fd < maxfd; fd++) -    { -      /* caught up */ -      if (thr_fd == fd) -        { -          struct listnode *nextln = listnextnode (ln); -          if (!FD_ISSET (fd, &fds)) -            { -              thread_cancel (thr); -              list_delete_node (events, ln); -            } -          ln = nextln; -          thr = ln ? listgetdata (ln) : NULL; -          thr_fd = thr ? THREAD_FD (thr) : -1; -        } -      /* need listener, but haven't hit one where it would be */ -      else if (FD_ISSET (fd, &fds)) -        { -          struct listnode *newln; -          thr = thread_add_read (agentx_tm, agentx_read, NULL, fd); -          newln = listnode_add_before (events, ln, thr); -          thr->arg = newln; -        } -    } - -  /* leftover event listeners at this point have fd > maxfd, delete them */ -  while (ln) -    { -      struct listnode *nextln = listnextnode (ln); -      thread_cancel (listgetdata (ln)); -      list_delete_node (events, ln); -      ln = nextln; -    } +	int maxfd = 0; +	int block = 1; +	struct timeval timeout = {.tv_sec = 0, .tv_usec = 0}; +	fd_set fds; +	struct listnode *ln; +	struct thread *thr; +	int fd, thr_fd; + +	THREAD_OFF(timeout_thr); + +	FD_ZERO(&fds); +	snmp_select_info(&maxfd, &fds, &timeout, &block); + +	if (!block) +		timeout_thr = thread_add_timer_tv(agentx_tm, agentx_timeout, +						  NULL, &timeout); + +	ln = listhead(events); +	thr = ln ? listgetdata(ln) : NULL; +	thr_fd = thr ? THREAD_FD(thr) : -1; + +	/* "two-pointer" / two-list simultaneous iteration +	 * ln/thr/thr_fd point to the next existing event listener to hit while +	 * fd counts to catch up */ +	for (fd = 0; fd < maxfd; fd++) { +		/* caught up */ +		if (thr_fd == fd) { +			struct listnode *nextln = listnextnode(ln); +			if (!FD_ISSET(fd, &fds)) { +				thread_cancel(thr); +				list_delete_node(events, ln); +			} +			ln = nextln; +			thr = ln ? listgetdata(ln) : NULL; +			thr_fd = thr ? THREAD_FD(thr) : -1; +		} +		/* need listener, but haven't hit one where it would be */ +		else if (FD_ISSET(fd, &fds)) { +			struct listnode *newln; +			thr = thread_add_read(agentx_tm, agentx_read, NULL, fd); +			newln = listnode_add_before(events, ln, thr); +			thr->arg = newln; +		} +	} + +	/* leftover event listeners at this point have fd > maxfd, delete them +	 */ +	while (ln) { +		struct listnode *nextln = listnextnode(ln); +		thread_cancel(listgetdata(ln)); +		list_delete_node(events, ln); +		ln = nextln; +	}  }  /* AgentX node. */ -static struct cmd_node agentx_node = -{ -  SMUX_NODE, -  ""                            /* AgentX has no interface. */ +static struct cmd_node agentx_node = { +	SMUX_NODE, "" /* AgentX has no interface. */  };  /* Logging NetSNMP messages */ -static int -agentx_log_callback(int major, int minor, -		    void *serverarg, void *clientarg) +static int agentx_log_callback(int major, int minor, void *serverarg, +			       void *clientarg)  { -  struct snmp_log_message *slm = (struct snmp_log_message *)serverarg; -  char *msg = XSTRDUP(MTYPE_TMP, slm->msg); -  if (msg) msg[strlen(msg)-1] = '\0'; -  switch (slm->priority) -    { -    case LOG_EMERG:   zlog_err   ("snmp[emerg]: %s",   msg?msg:slm->msg); break; -    case LOG_ALERT:   zlog_err   ("snmp[alert]: %s",   msg?msg:slm->msg); break; -    case LOG_CRIT:    zlog_err   ("snmp[crit]: %s",    msg?msg:slm->msg); break; -    case LOG_ERR:     zlog_err   ("snmp[err]: %s",     msg?msg:slm->msg); break; -    case LOG_WARNING: zlog_warn  ("snmp[warning]: %s", msg?msg:slm->msg); break; -    case LOG_NOTICE:  zlog_notice("snmp[notice]: %s",  msg?msg:slm->msg); break; -    case LOG_INFO:    zlog_info  ("snmp[info]: %s",    msg?msg:slm->msg); break; -    case LOG_DEBUG:   zlog_debug ("snmp[debug]: %s",   msg?msg:slm->msg); break; -    } -  XFREE(MTYPE_TMP, msg); -  return SNMP_ERR_NOERROR; +	struct snmp_log_message *slm = (struct snmp_log_message *)serverarg; +	char *msg = XSTRDUP(MTYPE_TMP, slm->msg); +	if (msg) +		msg[strlen(msg) - 1] = '\0'; +	switch (slm->priority) { +	case LOG_EMERG: +		zlog_err("snmp[emerg]: %s", msg ? msg : slm->msg); +		break; +	case LOG_ALERT: +		zlog_err("snmp[alert]: %s", msg ? msg : slm->msg); +		break; +	case LOG_CRIT: +		zlog_err("snmp[crit]: %s", msg ? msg : slm->msg); +		break; +	case LOG_ERR: +		zlog_err("snmp[err]: %s", msg ? msg : slm->msg); +		break; +	case LOG_WARNING: +		zlog_warn("snmp[warning]: %s", msg ? msg : slm->msg); +		break; +	case LOG_NOTICE: +		zlog_notice("snmp[notice]: %s", msg ? msg : slm->msg); +		break; +	case LOG_INFO: +		zlog_info("snmp[info]: %s", msg ? msg : slm->msg); +		break; +	case LOG_DEBUG: +		zlog_debug("snmp[debug]: %s", msg ? msg : slm->msg); +		break; +	} +	XFREE(MTYPE_TMP, msg); +	return SNMP_ERR_NOERROR;  } -static int -config_write_agentx (struct vty *vty) +static int config_write_agentx(struct vty *vty)  { -  if (agentx_enabled) -      vty_out (vty, "agentx%s", VTY_NEWLINE); -  return 0; +	if (agentx_enabled) +		vty_out(vty, "agentx%s", VTY_NEWLINE); +	return 0;  }  DEFUN (agentx_enable, @@ -174,16 +180,15 @@ DEFUN (agentx_enable,         "SNMP AgentX protocol settings\n"         "SNMP AgentX settings\n")  { -  if (!agentx_enabled) -    { -      init_snmp(FRR_SMUX_NAME); -      events = list_new(); -      agentx_events_update (); -      agentx_enabled = 1; -      return CMD_SUCCESS; -    } -  vty_out (vty, "SNMP AgentX already enabled%s", VTY_NEWLINE); -  return CMD_WARNING; +	if (!agentx_enabled) { +		init_snmp(FRR_SMUX_NAME); +		events = list_new(); +		agentx_events_update(); +		agentx_enabled = 1; +		return CMD_SUCCESS; +	} +	vty_out(vty, "SNMP AgentX already enabled%s", VTY_NEWLINE); +	return CMD_WARNING;  }  DEFUN (no_agentx, @@ -193,126 +198,120 @@ DEFUN (no_agentx,         "SNMP AgentX protocol settings\n"         "SNMP AgentX settings\n")  { -  if (!agentx_enabled) return CMD_SUCCESS; -  vty_out (vty, "SNMP AgentX support cannot be disabled once enabled%s", VTY_NEWLINE); -  return CMD_WARNING; +	if (!agentx_enabled) +		return CMD_SUCCESS; +	vty_out(vty, "SNMP AgentX support cannot be disabled once enabled%s", +		VTY_NEWLINE); +	return CMD_WARNING;  } -void -smux_init (struct thread_master *tm) +void smux_init(struct thread_master *tm)  { -  agentx_tm = tm; - -  netsnmp_enable_subagent (); -  snmp_disable_log (); -  snmp_enable_calllog (); -  snmp_register_callback (SNMP_CALLBACK_LIBRARY, -			  SNMP_CALLBACK_LOGGING, -			  agentx_log_callback, -			  NULL); -  init_agent (FRR_SMUX_NAME); - -  install_node (&agentx_node, config_write_agentx); -  install_element (CONFIG_NODE, &agentx_enable_cmd); -  install_element (CONFIG_NODE, &no_agentx_cmd); +	agentx_tm = tm; + +	netsnmp_enable_subagent(); +	snmp_disable_log(); +	snmp_enable_calllog(); +	snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_LOGGING, +			       agentx_log_callback, NULL); +	init_agent(FRR_SMUX_NAME); + +	install_node(&agentx_node, config_write_agentx); +	install_element(CONFIG_NODE, &agentx_enable_cmd); +	install_element(CONFIG_NODE, &no_agentx_cmd);  } -void -smux_register_mib (const char *descr, struct variable *var,  -		   size_t width, int num, -		   oid name[], size_t namelen) +void smux_register_mib(const char *descr, struct variable *var, size_t width, +		       int num, oid name[], size_t namelen)  { -  register_mib (descr, var, width, num, name, namelen); +	register_mib(descr, var, width, num, name, namelen);  } -int -smux_trap (struct variable *vp, size_t vp_len, -	   const oid *ename, size_t enamelen, -	   const oid *name, size_t namelen, -	   const oid *iname, size_t inamelen, -	   const struct trap_object *trapobj, size_t trapobjlen, -	   u_char sptrap) +int smux_trap(struct variable *vp, size_t vp_len, const oid *ename, +	      size_t enamelen, const oid *name, size_t namelen, +	      const oid *iname, size_t inamelen, +	      const struct trap_object *trapobj, size_t trapobjlen, +	      u_char sptrap)  { -  oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 }; -  size_t objid_snmptrap_len = sizeof objid_snmptrap / sizeof (oid); -  oid notification_oid[MAX_OID_LEN]; -  size_t notification_oid_len; -  unsigned int i; - -  netsnmp_variable_list *notification_vars = NULL; -  if (!agentx_enabled) return 0; - -  /* snmpTrapOID */ -  oid_copy (notification_oid, ename, enamelen); -  notification_oid[enamelen] = sptrap; -  notification_oid_len = enamelen + 1; -  snmp_varlist_add_variable (¬ification_vars, -			     objid_snmptrap, objid_snmptrap_len, -			     ASN_OBJECT_ID, -			     (u_char *) notification_oid, -			     notification_oid_len * sizeof(oid)); - -  /* Provided bindings */ -  for (i = 0; i < trapobjlen; i++) -    { -      unsigned int j; -      oid oid[MAX_OID_LEN]; -      size_t oid_len, onamelen; -      u_char *val; -      size_t val_len; -      WriteMethod *wm = NULL; -      struct variable cvp; - -      /* Make OID. */ -      if (trapobj[i].namelen > 0) -        { -	  /* Columnar object */ -	  onamelen = trapobj[i].namelen; -	  oid_copy (oid, name, namelen); -	  oid_copy (oid + namelen, trapobj[i].name, onamelen); -	  oid_copy (oid + namelen + onamelen, iname, inamelen); -	  oid_len = namelen + onamelen + inamelen; -        } -      else -        { -	  /* Scalar object */ -	  onamelen = trapobj[i].namelen * (-1); -	  oid_copy (oid, name, namelen); -	  oid_copy (oid + namelen, trapobj[i].name, onamelen); -	  oid[onamelen + namelen] = 0; -	  oid_len = namelen + onamelen + 1; -        } - -      /* Locate the appropriate function and type in the MIB registry. */ -      for (j = 0; j < vp_len; j++) -	{ -	  if (oid_compare (trapobj[i].name, onamelen, vp[j].name, vp[j].namelen) != 0) -	    continue; -	  /* We found the appropriate variable in the MIB registry. */ -	  oid_copy(cvp.name, name, namelen); -	  oid_copy(cvp.name + namelen, vp[j].name, vp[j].namelen); -	  cvp.namelen = namelen + vp[j].namelen; -	  cvp.type = vp[j].type; -	  cvp.magic = vp[j].magic; -	  cvp.acl = vp[j].acl; -	  cvp.findVar = vp[j].findVar; -	  /* Grab the result. */ -	  val = cvp.findVar (&cvp, oid, &oid_len, 1, &val_len, &wm); -	  if (!val) break; -	  snmp_varlist_add_variable (¬ification_vars, -				     oid, oid_len, -				     vp[j].type, -				     val, -				     val_len); -	  break; +	oid objid_snmptrap[] = {1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0}; +	size_t objid_snmptrap_len = sizeof objid_snmptrap / sizeof(oid); +	oid notification_oid[MAX_OID_LEN]; +	size_t notification_oid_len; +	unsigned int i; + +	netsnmp_variable_list *notification_vars = NULL; +	if (!agentx_enabled) +		return 0; + +	/* snmpTrapOID */ +	oid_copy(notification_oid, ename, enamelen); +	notification_oid[enamelen] = sptrap; +	notification_oid_len = enamelen + 1; +	snmp_varlist_add_variable(¬ification_vars, objid_snmptrap, +				  objid_snmptrap_len, ASN_OBJECT_ID, +				  (u_char *)notification_oid, +				  notification_oid_len * sizeof(oid)); + +	/* Provided bindings */ +	for (i = 0; i < trapobjlen; i++) { +		unsigned int j; +		oid oid[MAX_OID_LEN]; +		size_t oid_len, onamelen; +		u_char *val; +		size_t val_len; +		WriteMethod *wm = NULL; +		struct variable cvp; + +		/* Make OID. */ +		if (trapobj[i].namelen > 0) { +			/* Columnar object */ +			onamelen = trapobj[i].namelen; +			oid_copy(oid, name, namelen); +			oid_copy(oid + namelen, trapobj[i].name, onamelen); +			oid_copy(oid + namelen + onamelen, iname, inamelen); +			oid_len = namelen + onamelen + inamelen; +		} else { +			/* Scalar object */ +			onamelen = trapobj[i].namelen * (-1); +			oid_copy(oid, name, namelen); +			oid_copy(oid + namelen, trapobj[i].name, onamelen); +			oid[onamelen + namelen] = 0; +			oid_len = namelen + onamelen + 1; +		} + +		/* Locate the appropriate function and type in the MIB registry. +		 */ +		for (j = 0; j < vp_len; j++) { +			if (oid_compare(trapobj[i].name, onamelen, vp[j].name, +					vp[j].namelen) +			    != 0) +				continue; +			/* We found the appropriate variable in the MIB +			 * registry. */ +			oid_copy(cvp.name, name, namelen); +			oid_copy(cvp.name + namelen, vp[j].name, vp[j].namelen); +			cvp.namelen = namelen + vp[j].namelen; +			cvp.type = vp[j].type; +			cvp.magic = vp[j].magic; +			cvp.acl = vp[j].acl; +			cvp.findVar = vp[j].findVar; +			/* Grab the result. */ +			val = cvp.findVar(&cvp, oid, &oid_len, 1, &val_len, +					  &wm); +			if (!val) +				break; +			snmp_varlist_add_variable(¬ification_vars, oid, +						  oid_len, vp[j].type, val, +						  val_len); +			break; +		}  	} -    } -  send_v2trap (notification_vars); -  snmp_free_varbind (notification_vars); -  agentx_events_update (); -  return 1; +	send_v2trap(notification_vars); +	snmp_free_varbind(notification_vars); +	agentx_events_update(); +	return 1;  }  #endif /* SNMP_AGENTX */  | 
