]> git.proxmox.com Git - mirror_frr.git/blob - lib/agentx.c
*: fixup snmp support
[mirror_frr.git] / lib / agentx.c
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 #include "memory.h"
31
32 int agentx_enabled = 0;
33
34 /* AgentX node. */
35 static struct cmd_node agentx_node =
36 {
37 SMUX_NODE,
38 "" /* AgentX has no interface. */
39 };
40
41 /* Logging NetSNMP messages */
42 static int
43 agentx_log_callback(int major, int minor,
44 void *serverarg, void *clientarg)
45 {
46 struct snmp_log_message *slm = (struct snmp_log_message *)serverarg;
47 char *msg = XSTRDUP(MTYPE_TMP, slm->msg);
48 if (msg) msg[strlen(msg)-1] = '\0';
49 switch (slm->priority)
50 {
51 case LOG_EMERG: zlog_err ("snmp[emerg]: %s", msg?msg:slm->msg); break;
52 case LOG_ALERT: zlog_err ("snmp[alert]: %s", msg?msg:slm->msg); break;
53 case LOG_CRIT: zlog_err ("snmp[crit]: %s", msg?msg:slm->msg); break;
54 case LOG_ERR: zlog_err ("snmp[err]: %s", msg?msg:slm->msg); break;
55 case LOG_WARNING: zlog_warn ("snmp[warning]: %s", msg?msg:slm->msg); break;
56 case LOG_NOTICE: zlog_notice("snmp[notice]: %s", msg?msg:slm->msg); break;
57 case LOG_INFO: zlog_info ("snmp[info]: %s", msg?msg:slm->msg); break;
58 case LOG_DEBUG: zlog_debug ("snmp[debug]: %s", msg?msg:slm->msg); break;
59 }
60 XFREE(MTYPE_TMP, msg);
61 return SNMP_ERR_NOERROR;
62 }
63
64 static int
65 config_write_agentx (struct vty *vty)
66 {
67 if (agentx_enabled)
68 vty_out (vty, "agentx%s", VTY_NEWLINE);
69 return 0;
70 }
71
72 DEFUN (agentx_enable,
73 agentx_enable_cmd,
74 "agentx",
75 "SNMP AgentX protocol settings\n"
76 "SNMP AgentX settings\n")
77 {
78 if (!agentx_enabled)
79 {
80 init_snmp("quagga");
81 agentx_enabled = 1;
82 return CMD_SUCCESS;
83 }
84 vty_out (vty, "SNMP AgentX already enabled%s", VTY_NEWLINE);
85 return CMD_WARNING;
86 }
87
88 DEFUN (no_agentx,
89 no_agentx_cmd,
90 "no agentx",
91 NO_STR
92 "SNMP AgentX protocol settings\n"
93 "SNMP AgentX settings\n")
94 {
95 if (!agentx_enabled) return CMD_SUCCESS;
96 vty_out (vty, "SNMP AgentX support cannot be disabled once enabled%s", VTY_NEWLINE);
97 return CMD_WARNING;
98 }
99
100 void
101 smux_init (struct thread_master *tm)
102 {
103 netsnmp_enable_subagent ();
104 snmp_disable_log ();
105 snmp_enable_calllog ();
106 snmp_register_callback (SNMP_CALLBACK_LIBRARY,
107 SNMP_CALLBACK_LOGGING,
108 agentx_log_callback,
109 NULL);
110 init_agent ("quagga");
111
112 install_node (&agentx_node, config_write_agentx);
113 install_element (CONFIG_NODE, &agentx_enable_cmd);
114 install_element (CONFIG_NODE, &no_agentx_cmd);
115 }
116
117 void
118 smux_register_mib (const char *descr, struct variable *var,
119 size_t width, int num,
120 oid name[], size_t namelen)
121 {
122 register_mib (descr, var, width, num, name, namelen);
123 }
124
125 int
126 smux_trap (struct variable *vp, size_t vp_len,
127 const oid *ename, size_t enamelen,
128 const oid *name, size_t namelen,
129 const oid *iname, size_t inamelen,
130 const struct trap_object *trapobj, size_t trapobjlen,
131 u_char sptrap)
132 {
133 oid objid_snmptrap[] = { 1, 3, 6, 1, 6, 3, 1, 1, 4, 1, 0 };
134 size_t objid_snmptrap_len = sizeof objid_snmptrap / sizeof (oid);
135 oid notification_oid[MAX_OID_LEN];
136 size_t notification_oid_len;
137 unsigned int i;
138
139 netsnmp_variable_list *notification_vars = NULL;
140 if (!agentx_enabled) return 0;
141
142 /* snmpTrapOID */
143 oid_copy (notification_oid, ename, enamelen);
144 notification_oid[enamelen] = sptrap;
145 notification_oid_len = enamelen + 1;
146 snmp_varlist_add_variable (&notification_vars,
147 objid_snmptrap, objid_snmptrap_len,
148 ASN_OBJECT_ID,
149 (u_char *) notification_oid,
150 notification_oid_len * sizeof(oid));
151
152 /* Provided bindings */
153 for (i = 0; i < trapobjlen; i++)
154 {
155 unsigned int j;
156 oid oid[MAX_OID_LEN];
157 size_t oid_len, onamelen;
158 u_char *val;
159 size_t val_len;
160 WriteMethod *wm = NULL;
161 struct variable cvp;
162
163 /* Make OID. */
164 if (trapobj[i].namelen > 0)
165 {
166 /* Columnar object */
167 onamelen = trapobj[i].namelen;
168 oid_copy (oid, name, namelen);
169 oid_copy (oid + namelen, trapobj[i].name, onamelen);
170 oid_copy (oid + namelen + onamelen, iname, inamelen);
171 oid_len = namelen + onamelen + inamelen;
172 }
173 else
174 {
175 /* Scalar object */
176 onamelen = trapobj[i].namelen * (-1);
177 oid_copy (oid, name, namelen);
178 oid_copy (oid + namelen, trapobj[i].name, onamelen);
179 oid[onamelen + namelen] = 0;
180 oid_len = namelen + onamelen + 1;
181 }
182
183 /* Locate the appropriate function and type in the MIB registry. */
184 for (j = 0; j < vp_len; j++)
185 {
186 if (oid_compare (trapobj[i].name, onamelen, vp[j].name, vp[j].namelen) != 0)
187 continue;
188 /* We found the appropriate variable in the MIB registry. */
189 oid_copy(cvp.name, name, namelen);
190 oid_copy(cvp.name + namelen, vp[j].name, vp[j].namelen);
191 cvp.namelen = namelen + vp[j].namelen;
192 cvp.type = vp[j].type;
193 cvp.magic = vp[j].magic;
194 cvp.acl = vp[j].acl;
195 cvp.findVar = vp[j].findVar;
196 /* Grab the result. */
197 val = cvp.findVar (&cvp, oid, &oid_len, 1, &val_len, &wm);
198 if (!val) break;
199 snmp_varlist_add_variable (&notification_vars,
200 oid, oid_len,
201 vp[j].type,
202 val,
203 val_len);
204 break;
205 }
206 }
207
208
209 send_v2trap (notification_vars);
210 snmp_free_varbind (notification_vars);
211 return 1;
212 }
213
214 #endif /* HAVE_SNMP */