1: /* SNMP support
2: * Copyright (C) 2012 Vincent Bernat <bernat@luffy.cx>
3: *
4: * This file is part of GNU Zebra.
5: *
6: * GNU Zebra is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2, or (at your option) any
9: * later version.
10: *
11: * GNU Zebra is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of
13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14: * General Public License for more details.
15: *
16: * You should have received a copy of the GNU General Public License
17: * along with GNU Zebra; see the file COPYING. If not, write to the Free
18: * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19: * 02111-1307, USA.
20: */
21:
22: #include <zebra.h>
23:
24: #if defined HAVE_SNMP && defined SNMP_AGENTX
25: #include <net-snmp/net-snmp-config.h>
26: #include <net-snmp/net-snmp-includes.h>
27:
28: #include "command.h"
29: #include "smux.h"
30:
31: int agentx_enabled = 0;
32:
33: /* AgentX node. */
34: static struct cmd_node agentx_node =
35: {
36: SMUX_NODE,
37: "" /* AgentX has no interface. */
38: };
39:
40: /* Logging NetSNMP messages */
41: static int
42: agentx_log_callback(int major, int minor,
43: void *serverarg, void *clientarg)
44: {
45: struct snmp_log_message *slm = (struct snmp_log_message *)serverarg;
46: char *msg = strdup (slm->msg);
47: if (msg) msg[strlen(msg)-1] = '\0';
48: switch (slm->priority)
49: {
50: case LOG_EMERG: zlog_err ("snmp[emerg]: %s", msg?msg:slm->msg); break;
51: case LOG_ALERT: zlog_err ("snmp[alert]: %s", msg?msg:slm->msg); break;
52: case LOG_CRIT: zlog_err ("snmp[crit]: %s", msg?msg:slm->msg); break;
53: case LOG_ERR: zlog_err ("snmp[err]: %s", msg?msg:slm->msg); break;
54: case LOG_WARNING: zlog_warn ("snmp[warning]: %s", msg?msg:slm->msg); break;
55: case LOG_NOTICE: zlog_notice("snmp[notice]: %s", msg?msg:slm->msg); break;
56: case LOG_INFO: zlog_info ("snmp[info]: %s", msg?msg:slm->msg); break;
57: case LOG_DEBUG: zlog_debug ("snmp[debug]: %s", msg?msg:slm->msg); break;
58: }
59: free(msg);
60: return SNMP_ERR_NOERROR;
61: }
62:
63: static int
64: config_write_agentx (struct vty *vty)
65: {
66: if (agentx_enabled)
67: vty_out (vty, "agentx%s", VTY_NEWLINE);
68: return 0;
69: }
70:
71: DEFUN (agentx_enable,
72: agentx_enable_cmd,
73: "agentx",
74: "SNMP AgentX protocol settings\n"
75: "SNMP AgentX settings\n")
76: {
77: if (!agentx_enabled)
78: {
79: init_snmp("quagga");
80: agentx_enabled = 1;
81: return CMD_SUCCESS;
82: }
83: vty_out (vty, "SNMP AgentX already enabled%s", VTY_NEWLINE);
84: return CMD_WARNING;
85: }
86:
87: DEFUN (no_agentx,
88: no_agentx_cmd,
89: "no agentx",
90: NO_STR
91: "SNMP AgentX protocol settings\n"
92: "SNMP AgentX settings\n")
93: {
94: if (!agentx_enabled) return CMD_SUCCESS;
95: vty_out (vty, "SNMP AgentX support cannot be disabled once enabled%s", VTY_NEWLINE);
96: return CMD_WARNING;
97: }
98:
99: void
100: smux_init (struct thread_master *tm)
101: {
102: netsnmp_enable_subagent ();
103: snmp_disable_log ();
104: snmp_enable_calllog ();
105: snmp_register_callback (SNMP_CALLBACK_LIBRARY,
106: SNMP_CALLBACK_LOGGING,
107: agentx_log_callback,
108: NULL);
109: init_agent ("quagga");
110:
111: install_node (&agentx_node, config_write_agentx);
112: install_element (CONFIG_NODE, &agentx_enable_cmd);
113: install_element (CONFIG_NODE, &no_agentx_cmd);
114: }
115:
116: void
117: smux_register_mib (const char *descr, struct variable *var,
118: size_t width, int num,
119: oid name[], size_t namelen)
120: {
121: register_mib (descr, var, width, num, name, namelen);
122: }
123:
124: int
125: smux_trap (struct variable *vp, size_t vp_len,
126: const oid *ename, size_t enamelen,
127: const oid *name, size_t namelen,
128: const oid *iname, size_t inamelen,
129: const struct trap_object *trapobj, size_t trapobjlen,
130: u_char sptrap)
131: {
132: oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
133: size_t objid_snmptrap_len = sizeof objid_snmptrap / sizeof (oid);
134: oid notification_oid[MAX_OID_LEN];
135: size_t notification_oid_len;
136: unsigned int i;
137:
138: netsnmp_variable_list *notification_vars = NULL;
139: if (!agentx_enabled) return 0;
140:
141: /* snmpTrapOID */
142: oid_copy (notification_oid, ename, enamelen);
143: notification_oid[enamelen] = sptrap;
144: notification_oid_len = enamelen + 1;
145: snmp_varlist_add_variable (¬ification_vars,
146: objid_snmptrap, objid_snmptrap_len,
147: ASN_OBJECT_ID,
148: (u_char *) notification_oid,
149: notification_oid_len * sizeof(oid));
150:
151: /* Provided bindings */
152: for (i = 0; i < trapobjlen; i++)
153: {
154: unsigned int j;
155: oid oid[MAX_OID_LEN];
156: size_t oid_len, onamelen;
157: u_char *val;
158: size_t val_len;
159: WriteMethod *wm = NULL;
160: struct variable cvp;
161:
162: /* Make OID. */
163: if (trapobj[i].namelen > 0)
164: {
165: /* Columnar object */
166: onamelen = trapobj[i].namelen;
167: oid_copy (oid, name, namelen);
168: oid_copy (oid + namelen, trapobj[i].name, onamelen);
169: oid_copy (oid + namelen + onamelen, iname, inamelen);
170: oid_len = namelen + onamelen + inamelen;
171: }
172: else
173: {
174: /* Scalar object */
175: onamelen = trapobj[i].namelen * (-1);
176: oid_copy (oid, name, namelen);
177: oid_copy (oid + namelen, trapobj[i].name, onamelen);
178: oid[onamelen + namelen] = 0;
179: oid_len = namelen + onamelen + 1;
180: }
181:
182: /* Locate the appropriate function and type in the MIB registry. */
183: for (j = 0; j < vp_len; j++)
184: {
185: if (oid_compare (trapobj[i].name, onamelen, vp[j].name, vp[j].namelen) != 0)
186: continue;
187: /* We found the appropriate variable in the MIB registry. */
188: oid_copy(cvp.name, name, namelen);
189: oid_copy(cvp.name + namelen, vp[j].name, vp[j].namelen);
190: cvp.namelen = namelen + vp[j].namelen;
191: cvp.type = vp[j].type;
192: cvp.magic = vp[j].magic;
193: cvp.acl = vp[j].acl;
194: cvp.findVar = vp[j].findVar;
195: /* Grab the result. */
196: val = cvp.findVar (&cvp, oid, &oid_len, 1, &val_len, &wm);
197: if (!val) break;
198: snmp_varlist_add_variable (¬ification_vars,
199: oid, oid_len,
200: vp[j].type,
201: val,
202: val_len);
203: break;
204: }
205: }
206:
207:
208: send_v2trap (notification_vars);
209: snmp_free_varbind (notification_vars);
210: return 1;
211: }
212:
213: #endif /* HAVE_SNMP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>