]> git.ipfire.org Git - thirdparty/lldpd.git/blame - src/agent.c
Add smart mode support.
[thirdparty/lldpd.git] / src / agent.c
CommitLineData
43c02e7b
VB
1/*
2 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "lldpd.h"
18
19#include <net-snmp/net-snmp-config.h>
20#include <net-snmp/net-snmp-includes.h>
21#include <net-snmp/agent/net-snmp-agent-includes.h>
22#include <net-snmp/agent/snmp_vars.h>
23#include <net-snmp/agent/util_funcs.h>
24
25static oid lldp_oid[] = {1, 0, 8802, 1, 1, 2};
26
27/* For net-snmp */
28extern int register_sysORTable(oid *, size_t, const char *);
29extern int unregister_sysORTable(oid *, size_t);
30extern struct timeval starttime;
31
32/* Global variable because no way to pass it as argument. Should not be used
33 * elsewhere. */
8888d191 34static struct lldpd *scfg;
43c02e7b
VB
35
36static inline uint8_t
37swap_bits(uint8_t n)
38{
39 n = ((n&0xF0) >>4 ) | ( (n&0x0F) <<4);
40 n = ((n&0xCC) >>2 ) | ( (n&0x33) <<2);
41 n = ((n&0xAA) >>1 ) | ( (n&0x55) <<1);
42
43 return n;
44};
45
8888d191 46static struct lldpd_hardware*
43c02e7b
VB
47header_portindexed_table(struct variable *vp, oid *name, size_t *length,
48 int exact, size_t *var_len, WriteMethod **write_method)
49{
50 struct lldpd_hardware *hardware, *phardware = NULL;
51 unsigned int port, aport = 0, distance;
52
53 if (header_simple_table(vp, name, length, exact, var_len, write_method, -1))
54 return NULL;
55
56 port = name[*length - 1];
57 distance = -1;
58 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) {
6e75df87
VB
59 aport = hardware->h_ifindex;
60 if (aport == port) {
61 /* Exact match */
62 return hardware;
63 }
64 if (aport < port)
65 continue;
66 if (aport - port < distance) {
67 phardware = hardware;
68 distance = aport - port;
43c02e7b
VB
69 }
70 }
71 if (phardware == NULL)
72 return NULL;
73 if (exact)
74 return NULL;
75 if (distance == -1)
76 return NULL;
77 aport = distance + port;
78 name[*length - 1] = aport;
79 return phardware;
80}
81
fd6aa9a3 82#ifdef ENABLE_LLDPMED
1dcd4665
VB
83#define PMED_VARIANT_POLICY 0
84#define PMED_VARIANT_LOCATION 1
85static void*
86header_pmedindexed_table(struct variable *vp, oid *name, size_t *length,
87 int exact, size_t *var_len, WriteMethod **write_method, int variant)
fd6aa9a3
VB
88{
89 struct lldpd_hardware *hardware;
1dcd4665
VB
90 void *squid, *psquid = NULL;
91 int result, target_len, i, max;
fd6aa9a3
VB
92 oid *target, current[2], best[2];
93
94 if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) {
95 memcpy(name, vp->name, sizeof(oid) * vp->namelen);
96 *length = vp->namelen;
97 }
98
99 *write_method = 0;
100 *var_len = sizeof(long);
101
102 best[0] = best[1] = MAX_SUBID;
103 target = &name[vp->namelen];
104 target_len = *length - vp->namelen;
105 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) {
1dcd4665
VB
106 max = (variant == PMED_VARIANT_POLICY)?
107 LLDPMED_APPTYPE_LAST:LLDPMED_LOCFORMAT_LAST;
108 for (i = 0;
109 i < max;
110 i++) {
111 if (variant == PMED_VARIANT_POLICY) {
112 if (hardware->h_lport.p_med_policy[i].type != i+1)
113 continue;
114 squid = &(hardware->h_lport.p_med_policy[i]);
115 } else {
116 if (hardware->h_lport.p_med_location[i].format != i+1)
117 continue;
118 squid = &(hardware->h_lport.p_med_location[i]);
119 }
fd6aa9a3
VB
120 current[0] = hardware->h_ifindex;
121 current[1] = i+1;
122 if ((result = snmp_oid_compare(current, 2, target,
123 target_len)) < 0)
124 continue;
125 if ((result == 0) && !exact)
126 continue;
127 if (result == 0)
1dcd4665 128 return squid;
fd6aa9a3
VB
129 if (snmp_oid_compare(current, 2, best, 2) < 0) {
130 memcpy(best, current, sizeof(oid) * 2);
1dcd4665 131 psquid = squid;
fd6aa9a3
VB
132 }
133 }
134 }
1dcd4665 135 if (psquid == NULL)
fd6aa9a3
VB
136 return NULL;
137 if (exact)
138 return NULL;
139 if ((best[0] == best[1]) &&
140 (best[0] == MAX_SUBID))
141 return NULL;
142 memcpy(target, best, sizeof(oid) * 2);
143 *length = vp->namelen + 2;
144
1dcd4665 145 return psquid;
fd6aa9a3
VB
146}
147#endif
148
4a2acc8e
VB
149#define TPR_VARIANT_NONE 0
150#define TPR_VARIANT_IP 1
151#define TPR_VARIANT_MED_POLICY 2
152#define TPR_VARIANT_MED_LOCATION 3
7a53c5b9 153static struct lldpd_port*
43c02e7b 154header_tprindexed_table(struct variable *vp, oid *name, size_t *length,
4a2acc8e 155 int exact, size_t *var_len, WriteMethod **write_method, int variant)
43c02e7b 156{
7a53c5b9
VB
157 struct lldpd_hardware *hardware = NULL;
158 struct lldpd_port *port, *pport = NULL;
43c02e7b
VB
159 oid *target, current[9], best[9];
160 int result, target_len, oid_len;
4a2acc8e 161 int i, j, k;
43c02e7b
VB
162
163 if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) {
164 memcpy(name, vp->name, sizeof(oid) * vp->namelen);
165 *length = vp->namelen;
166 }
167
168 *write_method = 0;
169 *var_len = sizeof(long);
170
4a2acc8e
VB
171 switch (variant) {
172 case TPR_VARIANT_IP:
173 oid_len = 9; break;
174#ifdef ENABLE_LLDPMED
175 case TPR_VARIANT_MED_POLICY:
176 case TPR_VARIANT_MED_LOCATION:
177 oid_len = 4; break;
178#endif
179 case TPR_VARIANT_NONE:
180 default:
181 oid_len = 3;
182 }
43c02e7b
VB
183 for (i = 0; i < oid_len; i++) best[i] = MAX_SUBID;
184 target = &name[vp->namelen];
185 target_len = *length - vp->namelen;
186 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) {
7a53c5b9 187 TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
42b39485 188 if (SMART_HIDDEN(scfg, port)) continue;
4a2acc8e 189 if ((variant == TPR_VARIANT_IP) &&
7a53c5b9 190 (port->p_chassis->c_mgmt.s_addr == INADDR_ANY))
43c02e7b 191 continue;
7a53c5b9 192 if (port->p_lastchange > starttime.tv_sec)
777c32ea 193 current[0] =
7a53c5b9 194 (port->p_lastchange - starttime.tv_sec)*100;
777c32ea
VB
195 else
196 current[0] = 0;
6e75df87 197 current[1] = hardware->h_ifindex;
7a53c5b9 198 current[2] = port->p_chassis->c_index;
4a2acc8e
VB
199 k = j = 0;
200 switch (variant) {
201 case TPR_VARIANT_IP:
202 current[3] = 1;
203 current[4] = 4;
7a53c5b9
VB
204 current[8] = port->p_chassis->c_mgmt.s_addr >> 24;
205 current[7] = (port->p_chassis->c_mgmt.s_addr &
4a2acc8e 206 0xffffff) >> 16;
7a53c5b9 207 current[6] = (port->p_chassis->c_mgmt.s_addr &
4a2acc8e 208 0xffff) >> 8;
7a53c5b9 209 current[5] = port->p_chassis->c_mgmt.s_addr &
4a2acc8e
VB
210 0xff;
211 break;
212#ifdef ENABLE_LLDPMED
213 case TPR_VARIANT_MED_POLICY:
214 j = LLDPMED_APPTYPE_LAST;
215 break;
216 case TPR_VARIANT_MED_LOCATION:
217 j = LLDPMED_LOCFORMAT_LAST;
218 break;
219#endif
220 }
221 do {
222 if (j > 0)
223 current[3] = ++k;
224 if ((result = snmp_oid_compare(current, oid_len, target,
225 target_len)) < 0)
226 continue;
227 if ((result == 0) && !exact)
228 continue;
229 if (result == 0)
7a53c5b9 230 return port;
4a2acc8e
VB
231 if (snmp_oid_compare(current, oid_len, best, oid_len) < 0) {
232 memcpy(best, current, sizeof(oid) * oid_len);
7a53c5b9 233 pport = port;
4a2acc8e
VB
234 }
235 } while (k < j);
43c02e7b
VB
236 }
237 }
7a53c5b9 238 if (pport == NULL)
43c02e7b
VB
239 return NULL;
240 if (exact)
241 return NULL;
242 for (i = 0; i < oid_len; i++)
243 if (best[i] != MAX_SUBID) break;
244 if (i == oid_len)
245 return NULL;
246 memcpy(target, best, sizeof(oid) * oid_len);
247 *length = vp->namelen + oid_len;
248
7a53c5b9 249 return pport;
43c02e7b
VB
250}
251
a1347cd8 252#ifdef ENABLE_DOT1
8888d191 253static struct lldpd_vlan*
43c02e7b
VB
254header_pvindexed_table(struct variable *vp, oid *name, size_t *length,
255 int exact, size_t *var_len, WriteMethod **write_method)
256{
257 struct lldpd_hardware *hardware;
258 struct lldpd_vlan *vlan, *pvlan = NULL;
259 oid *target, current[2], best[2];
260 int result, target_len;
261
262 if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) {
263 memcpy(name, vp->name, sizeof(oid) * vp->namelen);
264 *length = vp->namelen;
265 }
266
267 *write_method = 0;
268 *var_len = sizeof(long);
269
270 best[0] = best[1] = MAX_SUBID;
271 target = &name[vp->namelen];
272 target_len = *length - vp->namelen;
273 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) {
6e75df87
VB
274 TAILQ_FOREACH(vlan, &hardware->h_lport.p_vlans, v_entries) {
275 current[0] = hardware->h_ifindex;
276 current[1] = vlan->v_vid;
277 if ((result = snmp_oid_compare(current, 2, target,
278 target_len)) < 0)
279 continue;
280 if ((result == 0) && !exact)
281 continue;
282 if (result == 0)
283 return vlan;
284 if (snmp_oid_compare(current, 2, best, 2) < 0) {
285 memcpy(best, current, sizeof(oid) * 2);
286 pvlan = vlan;
287 }
43c02e7b
VB
288 }
289 }
290 if (pvlan == NULL)
291 return NULL;
292 if (exact)
293 return NULL;
294 if ((best[0] == best[1]) &&
295 (best[0] == MAX_SUBID))
296 return NULL;
297 memcpy(target, best, sizeof(oid) * 2);
298 *length = vp->namelen + 2;
299
300 return pvlan;
301}
302
8888d191 303static struct lldpd_vlan*
43c02e7b
VB
304header_tprvindexed_table(struct variable *vp, oid *name, size_t *length,
305 int exact, size_t *var_len, WriteMethod **write_method)
306{
307 struct lldpd_hardware *hardware;
7a53c5b9 308 struct lldpd_port *port;
43c02e7b
VB
309 struct lldpd_vlan *vlan, *pvlan = NULL;
310 oid *target, current[4], best[4];
311 int result, target_len;
312
313 if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) {
314 memcpy(name, vp->name, sizeof(oid) * vp->namelen);
315 *length = vp->namelen;
316 }
317
318 *write_method = 0;
319 *var_len = sizeof(long);
320
321 best[0] = best[1] = best[2] = best[3] = MAX_SUBID;
322 target = &name[vp->namelen];
323 target_len = *length - vp->namelen;
324 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) {
7a53c5b9 325 TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
42b39485 326 if (SMART_HIDDEN(scfg, port)) continue;
7a53c5b9
VB
327 TAILQ_FOREACH(vlan, &port->p_vlans, v_entries) {
328 if (port->p_lastchange > starttime.tv_sec)
777c32ea 329 current[0] =
7a53c5b9 330 (port->p_lastchange - starttime.tv_sec)*100;
777c32ea
VB
331 else
332 current[0] = 0;
6e75df87 333 current[1] = hardware->h_ifindex;
7a53c5b9 334 current[2] = port->p_chassis->c_index;
43c02e7b
VB
335 current[3] = vlan->v_vid;
336 if ((result = snmp_oid_compare(current, 4, target,
337 target_len)) < 0)
338 continue;
339 if ((result == 0) && !exact)
340 continue;
341 if (result == 0)
342 return vlan;
343 if (snmp_oid_compare(current, 4, best, 4) < 0) {
344 memcpy(best, current, sizeof(oid) * 4);
345 pvlan = vlan;
346 }
347 }
348 }
349 }
350 if (pvlan == NULL)
351 return NULL;
352 if (exact)
353 return NULL;
354 if ((best[0] == best[1]) && (best[1] == best[2]) &&
355 (best[2] == best[3]) && (best[0] == MAX_SUBID))
356 return NULL;
357 memcpy(target, best, sizeof(oid) * 4);
358 *length = vp->namelen + 4;
359
360 return pvlan;
361}
a1347cd8 362#endif
43c02e7b
VB
363
364/* Scalars */
365#define LLDP_SNMP_TXINTERVAL 1
366#define LLDP_SNMP_TXMULTIPLIER 2
367#define LLDP_SNMP_REINITDELAY 3
368#define LLDP_SNMP_TXDELAY 4
369#define LLDP_SNMP_NOTIFICATION 5
370#define LLDP_SNMP_LASTUPDATE 6
371#define LLDP_SNMP_STATS_INSERTS 7
372#define LLDP_SNMP_STATS_DELETES 8
373#define LLDP_SNMP_STATS_DROPS 9
374#define LLDP_SNMP_STATS_AGEOUTS 10
375/* Local chassis */
376#define LLDP_SNMP_LOCAL_CIDSUBTYPE 1
377#define LLDP_SNMP_LOCAL_CID 2
378#define LLDP_SNMP_LOCAL_SYSNAME 3
379#define LLDP_SNMP_LOCAL_SYSDESCR 4
380#define LLDP_SNMP_LOCAL_SYSCAP_SUP 5
381#define LLDP_SNMP_LOCAL_SYSCAP_ENA 6
382/* Stats */
383#define LLDP_SNMP_STATS_TX_PORTNUM 1
384#define LLDP_SNMP_STATS_TX 2
385#define LLDP_SNMP_STATS_RX_PORTNUM 3
386#define LLDP_SNMP_STATS_RX_DISCARDED 4
387#define LLDP_SNMP_STATS_RX_ERRORS 5
388#define LLDP_SNMP_STATS_RX 6
389#define LLDP_SNMP_STATS_RX_TLVDISCARDED 7
390#define LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED 8
391#define LLDP_SNMP_STATS_RX_AGEOUTS 9
392/* Local ports */
393#define LLDP_SNMP_LOCAL_PORTNUM 1
394#define LLDP_SNMP_LOCAL_PIDSUBTYPE 2
395#define LLDP_SNMP_LOCAL_PID 3
396#define LLDP_SNMP_LOCAL_PORTDESC 4
397#define LLDP_SNMP_LOCAL_DOT3_AUTONEG_SUPPORT 5
398#define LLDP_SNMP_LOCAL_DOT3_AUTONEG_ENABLED 6
399#define LLDP_SNMP_LOCAL_DOT3_AUTONEG_ADVERTISED 7
400#define LLDP_SNMP_LOCAL_DOT3_AUTONEG_MAU 8
401#define LLDP_SNMP_LOCAL_DOT3_AGG_STATUS 9
402#define LLDP_SNMP_LOCAL_DOT3_AGG_ID 10
548109b2 403#define LLDP_SNMP_LOCAL_DOT3_MFS 11
75b3469d 404#define LLDP_SNMP_LOCAL_DOT1_PVID 12
43c02e7b
VB
405/* Remote ports */
406#define LLDP_SNMP_REMOTE_CIDSUBTYPE 1
407#define LLDP_SNMP_REMOTE_CID 2
408#define LLDP_SNMP_REMOTE_PIDSUBTYPE 3
409#define LLDP_SNMP_REMOTE_PID 4
410#define LLDP_SNMP_REMOTE_PORTDESC 5
411#define LLDP_SNMP_REMOTE_SYSNAME 6
412#define LLDP_SNMP_REMOTE_SYSDESC 7
413#define LLDP_SNMP_REMOTE_SYSCAP_SUP 8
414#define LLDP_SNMP_REMOTE_SYSCAP_ENA 9
415#define LLDP_SNMP_REMOTE_DOT3_AUTONEG_SUPPORT 10
416#define LLDP_SNMP_REMOTE_DOT3_AUTONEG_ENABLED 11
417#define LLDP_SNMP_REMOTE_DOT3_AUTONEG_ADVERTISED 12
418#define LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU 13
419#define LLDP_SNMP_REMOTE_DOT3_AGG_STATUS 14
420#define LLDP_SNMP_REMOTE_DOT3_AGG_ID 15
548109b2 421#define LLDP_SNMP_REMOTE_DOT3_MFS 16
75b3469d 422#define LLDP_SNMP_REMOTE_DOT1_PVID 17
43c02e7b
VB
423/* Local vlans */
424#define LLDP_SNMP_LOCAL_DOT1_VLANNAME 1
425/* Remote vlans */
426#define LLDP_SNMP_REMOTE_DOT1_VLANNAME 1
427/* Management address */
428#define LLDP_SNMP_LOCAL_ADDR_LEN 1
429#define LLDP_SNMP_LOCAL_ADDR_IFSUBTYPE 2
430#define LLDP_SNMP_LOCAL_ADDR_IFID 3
431#define LLDP_SNMP_LOCAL_ADDR_OID 4
432#define LLDP_SNMP_REMOTE_ADDR_IFSUBTYPE 5
433#define LLDP_SNMP_REMOTE_ADDR_IFID 6
434#define LLDP_SNMP_REMOTE_ADDR_OID 7
1d88c843
VB
435/* LLDP-MED local */
436#define LLDP_SNMP_MED_LOCAL_CLASS 1
437#define LLDP_SNMP_MED_LOCAL_HW 2
438#define LLDP_SNMP_MED_LOCAL_FW 3
439#define LLDP_SNMP_MED_LOCAL_SW 4
440#define LLDP_SNMP_MED_LOCAL_SN 5
441#define LLDP_SNMP_MED_LOCAL_MANUF 6
442#define LLDP_SNMP_MED_LOCAL_MODEL 7
443#define LLDP_SNMP_MED_LOCAL_ASSET 8
fd6aa9a3
VB
444#define LLDP_SNMP_MED_LOCAL_POLICY_VID 9
445#define LLDP_SNMP_MED_LOCAL_POLICY_PRIO 10
446#define LLDP_SNMP_MED_LOCAL_POLICY_DSCP 11
447#define LLDP_SNMP_MED_LOCAL_POLICY_UNKNOWN 12
448#define LLDP_SNMP_MED_LOCAL_POLICY_TAGGED 13
1dcd4665 449#define LLDP_SNMP_MED_LOCAL_LOCATION 14
8e44f2dc 450/* No more than 17 since we reuse LLDP_SNMP_MED_POE_DEVICETYPE and above */
1d88c843 451/* LLDP-MED remote */
40ecae87
VB
452#define LLDP_SNMP_MED_REMOTE_CAP_AVAILABLE 1
453#define LLDP_SNMP_MED_REMOTE_CAP_ENABLED 2
454#define LLDP_SNMP_MED_REMOTE_CLASS 3
455#define LLDP_SNMP_MED_REMOTE_HW 4
456#define LLDP_SNMP_MED_REMOTE_FW 5
457#define LLDP_SNMP_MED_REMOTE_SW 6
458#define LLDP_SNMP_MED_REMOTE_SN 7
459#define LLDP_SNMP_MED_REMOTE_MANUF 8
460#define LLDP_SNMP_MED_REMOTE_MODEL 9
461#define LLDP_SNMP_MED_REMOTE_ASSET 10
4a2acc8e
VB
462#define LLDP_SNMP_MED_REMOTE_POLICY_VID 11
463#define LLDP_SNMP_MED_REMOTE_POLICY_PRIO 12
464#define LLDP_SNMP_MED_REMOTE_POLICY_DSCP 13
465#define LLDP_SNMP_MED_REMOTE_POLICY_UNKNOWN 14
466#define LLDP_SNMP_MED_REMOTE_POLICY_TAGGED 15
467#define LLDP_SNMP_MED_REMOTE_LOCATION 16
8e44f2dc
VB
468#define LLDP_SNMP_MED_POE_DEVICETYPE 17
469#define LLDP_SNMP_MED_POE_PSE_POWERVAL 19
470#define LLDP_SNMP_MED_POE_PSE_POWERSOURCE 20
471#define LLDP_SNMP_MED_POE_PSE_POWERPRIORITY 21
472#define LLDP_SNMP_MED_POE_PD_POWERVAL 22
473#define LLDP_SNMP_MED_POE_PD_POWERSOURCE 23
474#define LLDP_SNMP_MED_POE_PD_POWERPRIORITY 24
43c02e7b
VB
475
476static u_char*
477agent_h_scalars(struct variable *vp, oid *name, size_t *length,
478 int exact, size_t *var_len, WriteMethod **write_method)
479{
480 static unsigned long long_ret;
481 struct lldpd_hardware *hardware;
7a53c5b9 482 struct lldpd_port *port;
43c02e7b
VB
483
484 if (header_generic(vp, name, length, exact, var_len, write_method))
485 return NULL;
486
487 switch (vp->magic) {
488 case LLDP_SNMP_TXINTERVAL:
489 long_ret = scfg->g_delay;
490 return (u_char *)&long_ret;
491 case LLDP_SNMP_TXMULTIPLIER:
7a53c5b9 492 long_ret = LOCAL_CHASSIS(scfg)->c_ttl / scfg->g_delay;
43c02e7b
VB
493 return (u_char *)&long_ret;
494 case LLDP_SNMP_REINITDELAY:
495 long_ret = 1;
496 return (u_char *)&long_ret;
497 case LLDP_SNMP_TXDELAY:
498 long_ret = LLDPD_TX_MSGDELAY;
499 return (u_char *)&long_ret;
500 case LLDP_SNMP_NOTIFICATION:
501 long_ret = 5;
502 return (u_char *)&long_ret;
503 case LLDP_SNMP_LASTUPDATE:
504 long_ret = 0;
505 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries)
42b39485
VB
506 TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
507 if (SMART_HIDDEN(scfg, port)) continue;
7a53c5b9
VB
508 if (port->p_lastchange > long_ret)
509 long_ret = port->p_lastchange;
42b39485 510 }
43c02e7b
VB
511 if (long_ret)
512 long_ret = (long_ret - starttime.tv_sec) * 100;
513 return (u_char *)&long_ret;
514 case LLDP_SNMP_STATS_INSERTS:
515 /* We assume this is equal to valid frames received on all ports */
516 long_ret = 0;
517 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries)
518 long_ret += hardware->h_rx_cnt;
519 return (u_char *)&long_ret;
520 case LLDP_SNMP_STATS_AGEOUTS:
521 long_ret = 0;
522 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries)
523 long_ret += hardware->h_rx_ageout_cnt;
524 return (u_char *)&long_ret;
525 case LLDP_SNMP_STATS_DELETES:
526 long_ret = 0;
527 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries)
528 long_ret += hardware->h_rx_ageout_cnt +
529 hardware->h_rx_cnt?(hardware->h_rx_cnt - 1):0;
530 return (u_char *)&long_ret;
531 case LLDP_SNMP_STATS_DROPS:
532 /* We assume that we never have insufficient resources */
533 long_ret = 0;
534 return (u_char *)&long_ret;
535 default:
536 break;
537 }
538 return NULL;
539}
540
1d88c843 541#ifdef ENABLE_LLDPMED
8e44f2dc
VB
542static unsigned long
543agent_h_med_power(struct variable *vp, struct lldpd_med_power *power)
544{
545 unsigned long long_ret;
546
547 switch (vp->magic) {
548 case LLDP_SNMP_MED_POE_DEVICETYPE:
549 switch (power->devicetype) {
550 case LLDPMED_POW_TYPE_PSE:
551 long_ret = 2; break;
552 case LLDPMED_POW_TYPE_PD:
553 long_ret = 3; break;
554 case 0:
555 long_ret = 4; break;
556 default:
557 long_ret = 1;
558 }
559 return long_ret;
560 case LLDP_SNMP_MED_POE_PSE_POWERVAL:
561 case LLDP_SNMP_MED_POE_PD_POWERVAL:
562 if (((vp->magic == LLDP_SNMP_MED_POE_PSE_POWERVAL) &&
563 (power->devicetype ==
564 LLDPMED_POW_TYPE_PSE)) ||
565 ((vp->magic == LLDP_SNMP_MED_POE_PD_POWERVAL) &&
566 (power->devicetype ==
567 LLDPMED_POW_TYPE_PD))) {
568 long_ret = power->val;
569 return long_ret;
570 }
571 break;
572 case LLDP_SNMP_MED_POE_PSE_POWERSOURCE:
573 if (power->devicetype ==
574 LLDPMED_POW_TYPE_PSE) {
575 switch (power->source) {
576 case LLDPMED_POW_SOURCE_PRIMARY:
577 long_ret = 2; break;
578 case LLDPMED_POW_SOURCE_BACKUP:
579 long_ret = 3; break;
580 default:
581 long_ret = 1;
582 }
583 return long_ret;
584 }
585 break;
586 case LLDP_SNMP_MED_POE_PD_POWERSOURCE:
587 if (power->devicetype ==
588 LLDPMED_POW_TYPE_PD) {
589 switch (power->source) {
590 case LLDPMED_POW_SOURCE_PSE:
591 long_ret = 2; break;
592 case LLDPMED_POW_SOURCE_LOCAL:
593 long_ret = 3; break;
594 case LLDPMED_POW_SOURCE_BOTH:
595 long_ret = 4; break;
596 default:
597 long_ret = 1;
598 }
599 return long_ret;
600 }
601 break;
602 case LLDP_SNMP_MED_POE_PSE_POWERPRIORITY:
603 case LLDP_SNMP_MED_POE_PD_POWERPRIORITY:
604 if (((vp->magic == LLDP_SNMP_MED_POE_PSE_POWERPRIORITY) &&
605 (power->devicetype ==
606 LLDPMED_POW_TYPE_PSE)) ||
607 ((vp->magic == LLDP_SNMP_MED_POE_PD_POWERPRIORITY) &&
608 (power->devicetype ==
609 LLDPMED_POW_TYPE_PD))) {
610 switch (power->priority) {
611 case LLDPMED_POW_PRIO_CRITICAL:
612 long_ret = 2; break;
613 case LLDPMED_POW_PRIO_HIGH:
614 long_ret = 3; break;
615 case LLDPMED_POW_PRIO_LOW:
616 long_ret = 4; break;
617 default:
618 long_ret = 1;
619 }
620 return long_ret;
621 }
622 break;
623 }
624
625 return (unsigned long)-1;
626}
627
1d88c843
VB
628static u_char*
629agent_h_local_med(struct variable *vp, oid *name, size_t *length,
630 int exact, size_t *var_len, WriteMethod **write_method)
631{
632 static unsigned long long_ret;
8e44f2dc
VB
633 struct lldpd_hardware *hardware;
634 struct lldpd_med_power *power;
635 int pse;
1d88c843 636
7a53c5b9 637 if (!LOCAL_CHASSIS(scfg)->c_med_cap_available)
1d88c843
VB
638 return NULL;
639
4a2acc8e 640 if (header_generic(vp, name, length, exact, var_len, write_method))
1d88c843
VB
641 return NULL;
642
643 switch (vp->magic) {
644 case LLDP_SNMP_MED_LOCAL_CLASS:
7a53c5b9 645 long_ret = LOCAL_CHASSIS(scfg)->c_med_type;
4a2acc8e 646 return (u_char *)&long_ret;
8e44f2dc
VB
647 case LLDP_SNMP_MED_POE_DEVICETYPE:
648 case LLDP_SNMP_MED_POE_PSE_POWERSOURCE:
649 case LLDP_SNMP_MED_POE_PD_POWERVAL:
650 case LLDP_SNMP_MED_POE_PD_POWERSOURCE:
651 case LLDP_SNMP_MED_POE_PD_POWERPRIORITY:
652 /* LLDP-MED requires only one device type for all
653 ports. Moreover, a PSE can only have one power source. At
654 least, all PD values are global and not per-port. We try to
655 do our best. For device type, we decide on the number of
656 PD/PSE ports. */
657 pse = 0; power = NULL;
658 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) {
659 if (hardware->h_lport.p_med_power.devicetype ==
660 LLDPMED_POW_TYPE_PSE) {
661 pse++;
662 if (pse == 1) /* Take this port as a reference */
663 power = &hardware->h_lport.p_med_power;
664 } else if (hardware->h_lport.p_med_power.devicetype ==
665 LLDPMED_POW_TYPE_PD) {
666 pse--;
667 if (pse == -1) /* Take this one instead */
668 power = &hardware->h_lport.p_med_power;
669 }
670 }
671 if (!power)
672 break; /* Neither PSE nor PD */
673 long_ret = agent_h_med_power(vp, power);
674 if (long_ret != (unsigned long)-1)
675 return (u_char *)&long_ret;
676 break;
1d88c843
VB
677
678#define LLDP_H_LOCAL_MED(magic, variable) \
679 case magic: \
7a53c5b9 680 if (LOCAL_CHASSIS(scfg)->variable) { \
1d88c843 681 *var_len = strlen( \
7a53c5b9
VB
682 LOCAL_CHASSIS(scfg)->variable); \
683 return (u_char *)LOCAL_CHASSIS(scfg)->variable; \
1d88c843
VB
684 } \
685 break
686
687 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_HW,
688 c_med_hw);
689 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_SW,
690 c_med_sw);
691 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_FW,
692 c_med_fw);
693 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_SN,
694 c_med_sn);
695 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_MANUF,
696 c_med_manuf);
697 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_MODEL,
698 c_med_model);
699 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_ASSET,
700 c_med_asset);
701
702 default:
4a2acc8e 703 return NULL;
1d88c843 704 }
4a2acc8e
VB
705 /* At this point, we seem to have hit an inventory variable that is not
706 * available, try to get the next one */
707 if (name[*length-1] < MAX_SUBID)
708 return agent_h_local_med(vp, name, length,
709 exact, var_len, write_method);
1d88c843
VB
710 return NULL;
711}
712
fd6aa9a3
VB
713static u_char*
714agent_h_local_med_policy(struct variable *vp, oid *name, size_t *length,
715 int exact, size_t *var_len, WriteMethod **write_method)
716{
717 struct lldpd_med_policy *policy;
718 static unsigned long long_ret;
719
1dcd4665
VB
720 if ((policy = (struct lldpd_med_policy *)header_pmedindexed_table(vp, name, length,
721 exact, var_len, write_method, PMED_VARIANT_POLICY)) == NULL)
fd6aa9a3
VB
722 return NULL;
723
724 switch (vp->magic) {
725 case LLDP_SNMP_MED_LOCAL_POLICY_VID:
726 long_ret = policy->vid;
727 break;
728 case LLDP_SNMP_MED_LOCAL_POLICY_PRIO:
729 long_ret = policy->priority;
730 break;
731 case LLDP_SNMP_MED_LOCAL_POLICY_DSCP:
732 long_ret = policy->dscp;
733 break;
734 case LLDP_SNMP_MED_LOCAL_POLICY_UNKNOWN:
735 long_ret = policy->unknown?1:2;
736 break;
737 case LLDP_SNMP_MED_LOCAL_POLICY_TAGGED:
738 long_ret = policy->tagged?1:2;
739 break;
740 default:
741 return NULL;
742 }
743 return (u_char *)&long_ret;
744}
745
1dcd4665
VB
746static u_char*
747agent_h_local_med_location(struct variable *vp, oid *name, size_t *length,
748 int exact, size_t *var_len, WriteMethod **write_method)
749{
750 struct lldpd_med_loc *location;
751
752 if ((location = (struct lldpd_med_loc *)header_pmedindexed_table(vp, name, length,
753 exact, var_len, write_method, PMED_VARIANT_LOCATION)) == NULL)
754 return NULL;
755
756 switch (vp->magic) {
757 case LLDP_SNMP_MED_LOCAL_LOCATION:
758 *var_len = location->data_len;
759 return (u_char *)location->data;
760 }
761 return NULL;
762}
763
8e44f2dc
VB
764static u_char*
765agent_h_local_med_power(struct variable *vp, oid *name, size_t *length,
766 int exact, size_t *var_len, WriteMethod **write_method)
767{
768 static unsigned long long_ret;
769 struct lldpd_hardware *hardware;
770
771 if ((hardware = header_portindexed_table(vp, name, length,
772 exact, var_len, write_method)) == NULL)
773 return NULL;
774 if (!hardware->h_lport.p_med_power.devicetype)
775 goto localpower_failed;
776
777 long_ret = agent_h_med_power(vp, &hardware->h_lport.p_med_power);
778 if (long_ret != (unsigned long)-1)
779 return (u_char *)&long_ret;
780
781localpower_failed:
782 /* No valid data was found, we should try the next one! */
783 if (!exact && (name[*length-1] < MAX_SUBID))
784 return agent_h_local_med_power(vp, name, length,
785 exact, var_len, write_method);
786 return NULL;
787}
788
1d88c843
VB
789static u_char*
790agent_h_remote_med(struct variable *vp, oid *name, size_t *length,
791 int exact, size_t *var_len, WriteMethod **write_method)
792{
7a53c5b9 793 struct lldpd_port *port;
1d88c843
VB
794 static uint8_t bit;
795 static unsigned long long_ret;
796
7a53c5b9 797 if ((port = header_tprindexed_table(vp, name, length,
4a2acc8e 798 exact, var_len, write_method, TPR_VARIANT_NONE)) == NULL)
1d88c843
VB
799 return NULL;
800
7a53c5b9 801 if (!port->p_chassis->c_med_cap_available) {
4a2acc8e
VB
802 if (!exact && (name[*length-2] < MAX_SUBID))
803 name[*length-2]++;
804 goto remotemed_failed;
805 }
1d88c843
VB
806
807 switch (vp->magic) {
808 case LLDP_SNMP_MED_REMOTE_CLASS:
7a53c5b9 809 long_ret = port->p_chassis->c_med_type;
1be9e1b5 810 return (u_char *)&long_ret;
40ecae87 811 case LLDP_SNMP_MED_REMOTE_CAP_AVAILABLE:
1d88c843 812 *var_len = 1;
7a53c5b9 813 bit = swap_bits(port->p_chassis->c_med_cap_available);
40ecae87
VB
814 return (u_char *)&bit;
815 case LLDP_SNMP_MED_REMOTE_CAP_ENABLED:
816 *var_len = 1;
7a53c5b9 817 bit = swap_bits(port->p_med_cap_enabled);
1d88c843 818 return (u_char *)&bit;
8e44f2dc
VB
819
820 case LLDP_SNMP_MED_POE_DEVICETYPE:
821 case LLDP_SNMP_MED_POE_PSE_POWERVAL:
822 case LLDP_SNMP_MED_POE_PD_POWERVAL:
823 case LLDP_SNMP_MED_POE_PSE_POWERSOURCE:
824 case LLDP_SNMP_MED_POE_PD_POWERSOURCE:
825 case LLDP_SNMP_MED_POE_PSE_POWERPRIORITY:
826 case LLDP_SNMP_MED_POE_PD_POWERPRIORITY:
827 long_ret = agent_h_med_power(vp, &port->p_med_power);
828 if (long_ret != (unsigned long)-1)
1be9e1b5 829 return (u_char *)&long_ret;
1be9e1b5
VB
830 break;
831
1d88c843
VB
832#define LLDP_H_REMOTE_MED(magic, variable) \
833 case magic: \
7a53c5b9 834 if (port->p_chassis->variable) { \
1d88c843 835 *var_len = strlen( \
7a53c5b9 836 port->p_chassis->variable); \
1d88c843 837 return (u_char *) \
7a53c5b9 838 port->p_chassis->variable; \
1d88c843
VB
839 } \
840 break
841
842 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_HW,
843 c_med_hw);
844 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_SW,
845 c_med_sw);
846 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_FW,
847 c_med_fw);
848 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_SN,
849 c_med_sn);
850 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_MANUF,
851 c_med_manuf);
852 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_MODEL,
853 c_med_model);
854 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_ASSET,
855 c_med_asset);
856
857 default:
4a2acc8e 858 return NULL;
1d88c843 859 }
4a2acc8e
VB
860remotemed_failed:
861 /* No valid data was found, we should try the next one! */
862 if (!exact && (name[*length-1] < MAX_SUBID))
863 return agent_h_remote_med(vp, name, length,
864 exact, var_len, write_method);
1d88c843
VB
865 return NULL;
866}
4a2acc8e
VB
867
868static u_char*
869agent_h_remote_med_policy(struct variable *vp, oid *name, size_t *length,
870 int exact, size_t *var_len, WriteMethod **write_method)
871{
872 int type;
7a53c5b9 873 struct lldpd_port *port;
4a2acc8e
VB
874 struct lldpd_med_policy *policy;
875 static unsigned long long_ret;
876
7a53c5b9 877 if ((port = header_tprindexed_table(vp, name, length,
4a2acc8e
VB
878 exact, var_len, write_method, TPR_VARIANT_MED_POLICY)) == NULL)
879 return NULL;
880
7a53c5b9 881 if (!port->p_chassis->c_med_cap_available) {
4a2acc8e
VB
882 if (!exact && (name[*length-2] < MAX_SUBID))
883 name[*length-2]++;
884 goto remotemedpolicy_failed;
885 }
886
887 type = name[*length - 1];
888 if ((type < 1) || (type > LLDPMED_APPTYPE_LAST))
889 goto remotemedpolicy_failed;
7a53c5b9 890 policy = &port->p_med_policy[type-1];
4a2acc8e
VB
891 if (policy->type != type)
892 goto remotemedpolicy_failed;
893
894 switch (vp->magic) {
895 case LLDP_SNMP_MED_REMOTE_POLICY_VID:
896 long_ret = policy->vid;
897 return (u_char *)&long_ret;
898 case LLDP_SNMP_MED_REMOTE_POLICY_PRIO:
899 long_ret = policy->priority;
900 return (u_char *)&long_ret;
901 case LLDP_SNMP_MED_REMOTE_POLICY_DSCP:
902 long_ret = policy->dscp;
903 return (u_char *)&long_ret;
904 case LLDP_SNMP_MED_REMOTE_POLICY_UNKNOWN:
905 long_ret = policy->unknown?1:2;
906 return (u_char *)&long_ret;
907 case LLDP_SNMP_MED_REMOTE_POLICY_TAGGED:
908 long_ret = policy->tagged?1:2;
909 return (u_char *)&long_ret;
910 default:
911 return NULL;
912 }
913remotemedpolicy_failed:
914 /* No valid data was found, we should try the next one! */
915 if (!exact && (name[*length-1] < MAX_SUBID))
916 return agent_h_remote_med_policy(vp, name, length,
917 exact, var_len, write_method);
918 return NULL;
919}
920
921static u_char*
922agent_h_remote_med_location(struct variable *vp, oid *name, size_t *length,
923 int exact, size_t *var_len, WriteMethod **write_method)
924{
925 int type;
7a53c5b9 926 struct lldpd_port *port;
4a2acc8e
VB
927 struct lldpd_med_loc *location;
928
7a53c5b9 929 if ((port = header_tprindexed_table(vp, name, length,
4a2acc8e
VB
930 exact, var_len, write_method, TPR_VARIANT_MED_LOCATION)) == NULL)
931 return NULL;
932
7a53c5b9 933 if (!port->p_chassis->c_med_cap_available) {
4a2acc8e
VB
934 if (!exact && (name[*length-2] < MAX_SUBID))
935 name[*length-2]++;
936 goto remotemedlocation_failed;
937 }
938
939 type = name[*length - 1];
940 if ((type < 1) || (type > LLDPMED_APPTYPE_LAST))
941 goto remotemedlocation_failed;
7a53c5b9 942 location = &port->p_med_location[type-1];
4a2acc8e
VB
943 if (location->format != type)
944 goto remotemedlocation_failed;
945
946 switch (vp->magic) {
947 case LLDP_SNMP_MED_REMOTE_LOCATION:
948 *var_len = location->data_len;
949 return (u_char *)location->data;
950 default:
951 return NULL;
952 }
953remotemedlocation_failed:
954 /* No valid data was found, we should try the next one! */
955 if (!exact && (name[*length-1] < MAX_SUBID))
956 return agent_h_remote_med_location(vp, name, length,
957 exact, var_len, write_method);
958 return NULL;
959}
1d88c843
VB
960#endif
961
43c02e7b
VB
962static u_char*
963agent_h_local_chassis(struct variable *vp, oid *name, size_t *length,
964 int exact, size_t *var_len, WriteMethod **write_method)
965{
966 static uint8_t bit;
967 static unsigned long long_ret;
968
969 if (header_generic(vp, name, length, exact, var_len, write_method))
970 return NULL;
971
972 switch (vp->magic) {
973 case LLDP_SNMP_LOCAL_CIDSUBTYPE:
7a53c5b9 974 long_ret = LOCAL_CHASSIS(scfg)->c_id_subtype;
43c02e7b
VB
975 return (u_char *)&long_ret;
976 case LLDP_SNMP_LOCAL_CID:
7a53c5b9
VB
977 *var_len = LOCAL_CHASSIS(scfg)->c_id_len;
978 return (u_char *)LOCAL_CHASSIS(scfg)->c_id;
43c02e7b 979 case LLDP_SNMP_LOCAL_SYSNAME:
7a53c5b9
VB
980 *var_len = strlen(LOCAL_CHASSIS(scfg)->c_name);
981 return (u_char *)LOCAL_CHASSIS(scfg)->c_name;
43c02e7b 982 case LLDP_SNMP_LOCAL_SYSDESCR:
7a53c5b9
VB
983 *var_len = strlen(LOCAL_CHASSIS(scfg)->c_descr);
984 return (u_char *)LOCAL_CHASSIS(scfg)->c_descr;
43c02e7b
VB
985 case LLDP_SNMP_LOCAL_SYSCAP_SUP:
986 *var_len = 1;
7a53c5b9 987 bit = swap_bits(LOCAL_CHASSIS(scfg)->c_cap_available);
43c02e7b
VB
988 return (u_char *)&bit;
989 case LLDP_SNMP_LOCAL_SYSCAP_ENA:
990 *var_len = 1;
7a53c5b9 991 bit = swap_bits(LOCAL_CHASSIS(scfg)->c_cap_enabled);
43c02e7b
VB
992 return (u_char *)&bit;
993 default:
994 break;
995 }
996 return NULL;
997}
998
999static u_char*
1000agent_h_stats(struct variable *vp, oid *name, size_t *length,
1001 int exact, size_t *var_len, WriteMethod **write_method)
1002{
1003 static unsigned long long_ret;
1004 struct lldpd_hardware *hardware;
1005
1006 if ((hardware = header_portindexed_table(vp, name, length,
1007 exact, var_len, write_method)) == NULL)
1008 return NULL;
1009
1010 switch (vp->magic) {
1011 case LLDP_SNMP_STATS_TX:
1012 long_ret = hardware->h_tx_cnt;
1013 return (u_char *)&long_ret;
1014 case LLDP_SNMP_STATS_RX:
1015 long_ret = hardware->h_rx_cnt;
1016 return (u_char *)&long_ret;
1017 case LLDP_SNMP_STATS_RX_DISCARDED:
1018 case LLDP_SNMP_STATS_RX_ERRORS:
37387046
VB
1019 /* We discard only frame with errors. Therefore, the two values
1020 * are equal */
43c02e7b
VB
1021 long_ret = hardware->h_rx_discarded_cnt;
1022 return (u_char *)&long_ret;
1023 case LLDP_SNMP_STATS_RX_TLVDISCARDED:
1024 case LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED:
37387046
VB
1025 /* We discard only unrecognized TLV. Malformed TLV
1026 implies dropping the whole frame */
1027 long_ret = hardware->h_rx_unrecognized_cnt;
43c02e7b
VB
1028 return (u_char *)&long_ret;
1029 case LLDP_SNMP_STATS_RX_AGEOUTS:
1030 long_ret = hardware->h_rx_ageout_cnt;
1031 return (u_char *)&long_ret;
1032 default:
1033 break;
1034 }
1035 return NULL;
1036}
1037
1038static u_char*
1039agent_h_local_port(struct variable *vp, oid *name, size_t *length,
1040 int exact, size_t *var_len, WriteMethod **write_method)
1041{
a1347cd8 1042#ifdef ENABLE_DOT3
43c02e7b 1043 static uint8_t bit;
a1347cd8 1044#endif
43c02e7b
VB
1045 struct lldpd_hardware *hardware;
1046 static unsigned long long_ret;
1047
1048 if ((hardware = header_portindexed_table(vp, name, length,
1049 exact, var_len, write_method)) == NULL)
1050 return NULL;
1051
1052 switch (vp->magic) {
1053 case LLDP_SNMP_LOCAL_PIDSUBTYPE:
1054 long_ret = hardware->h_lport.p_id_subtype;
1055 return (u_char *)&long_ret;
1056 case LLDP_SNMP_LOCAL_PID:
1057 *var_len = hardware->h_lport.p_id_len;
1058 return (u_char *)hardware->h_lport.p_id;
1059 case LLDP_SNMP_LOCAL_PORTDESC:
1060 *var_len = strlen(hardware->h_lport.p_descr);
1061 return (u_char *)hardware->h_lport.p_descr;
a1347cd8 1062#ifdef ENABLE_DOT3
43c02e7b
VB
1063 case LLDP_SNMP_LOCAL_DOT3_AUTONEG_SUPPORT:
1064 long_ret = 2 - hardware->h_lport.p_autoneg_support;
1065 return (u_char *)&long_ret;
1066 case LLDP_SNMP_LOCAL_DOT3_AUTONEG_ENABLED:
1067 long_ret = 2 - hardware->h_lport.p_autoneg_enabled;
1068 return (u_char *)&long_ret;
1069 case LLDP_SNMP_LOCAL_DOT3_AUTONEG_ADVERTISED:
1070 *var_len = 2;
1071 return (u_char *)&hardware->h_lport.p_autoneg_advertised;
1072 case LLDP_SNMP_LOCAL_DOT3_AUTONEG_MAU:
1073 long_ret = hardware->h_lport.p_mau_type;
1074 return (u_char *)&long_ret;
1075 case LLDP_SNMP_LOCAL_DOT3_AGG_STATUS:
1076 bit = swap_bits((hardware->h_lport.p_aggregid > 0) ? 3 : 0);
1077 *var_len = 1;
1078 return (u_char *)&bit;
1079 case LLDP_SNMP_LOCAL_DOT3_AGG_ID:
1080 long_ret = hardware->h_lport.p_aggregid;
1081 return (u_char *)&long_ret;
548109b2
VB
1082 case LLDP_SNMP_LOCAL_DOT3_MFS:
1083 long_ret = hardware->h_lport.p_mfs;
1084 return (u_char *)&long_ret;
75b3469d
VB
1085#endif
1086#ifdef ENABLE_DOT1
1087 case LLDP_SNMP_LOCAL_DOT1_PVID:
1088 long_ret = hardware->h_lport.p_pvid; /* Should always be 0 */
1089 return (u_char *)&long_ret;
a1347cd8 1090#endif
43c02e7b
VB
1091 default:
1092 break;
1093 }
1094 return NULL;
1095}
1096
a1347cd8 1097#ifdef ENABLE_DOT1
43c02e7b
VB
1098static u_char*
1099agent_h_local_vlan(struct variable *vp, oid *name, size_t *length,
1100 int exact, size_t *var_len, WriteMethod **write_method)
1101{
1102 struct lldpd_vlan *vlan;
1103
1104 if ((vlan = header_pvindexed_table(vp, name, length,
1105 exact, var_len, write_method)) == NULL)
1106 return NULL;
1107
1108 switch (vp->magic) {
1109 case LLDP_SNMP_LOCAL_DOT1_VLANNAME:
1110 *var_len = strlen(vlan->v_name);
1111 return (u_char *)vlan->v_name;
1112 default:
1113 break;
1114 }
1115 return NULL;
1116}
1117
1118static u_char*
1119agent_h_remote_vlan(struct variable *vp, oid *name, size_t *length,
1120 int exact, size_t *var_len, WriteMethod **write_method)
1121{
1122 struct lldpd_vlan *vlan;
1123
1124 if ((vlan = header_tprvindexed_table(vp, name, length,
1125 exact, var_len, write_method)) == NULL)
1126 return NULL;
1127
1128 switch (vp->magic) {
1129 case LLDP_SNMP_REMOTE_DOT1_VLANNAME:
1130 *var_len = strlen(vlan->v_name);
1131 return (u_char *)vlan->v_name;
1132 default:
1133 break;
1134 }
1135 return NULL;
1136}
a1347cd8 1137#endif
43c02e7b
VB
1138
1139static u_char*
1140agent_h_remote_port(struct variable *vp, oid *name, size_t *length,
1141 int exact, size_t *var_len, WriteMethod **write_method)
1142{
7a53c5b9 1143 struct lldpd_port *port;
43c02e7b
VB
1144 static uint8_t bit;
1145 static unsigned long long_ret;
1146
7a53c5b9 1147 if ((port = header_tprindexed_table(vp, name, length,
4a2acc8e 1148 exact, var_len, write_method, TPR_VARIANT_NONE)) == NULL)
43c02e7b
VB
1149 return NULL;
1150
1151 switch (vp->magic) {
1152 case LLDP_SNMP_REMOTE_CIDSUBTYPE:
7a53c5b9 1153 long_ret = port->p_chassis->c_id_subtype;
43c02e7b
VB
1154 return (u_char *)&long_ret;
1155 case LLDP_SNMP_REMOTE_CID:
7a53c5b9
VB
1156 *var_len = port->p_chassis->c_id_len;
1157 return (u_char *)port->p_chassis->c_id;
43c02e7b 1158 case LLDP_SNMP_REMOTE_PIDSUBTYPE:
7a53c5b9 1159 long_ret = port->p_id_subtype;
43c02e7b
VB
1160 return (u_char *)&long_ret;
1161 case LLDP_SNMP_REMOTE_PID:
7a53c5b9
VB
1162 *var_len = port->p_id_len;
1163 return (u_char *)port->p_id;
43c02e7b 1164 case LLDP_SNMP_REMOTE_PORTDESC:
7a53c5b9
VB
1165 *var_len = strlen(port->p_descr);
1166 return (u_char *)port->p_descr;
43c02e7b 1167 case LLDP_SNMP_REMOTE_SYSNAME:
7a53c5b9
VB
1168 *var_len = strlen(port->p_chassis->c_name);
1169 return (u_char *)port->p_chassis->c_name;
43c02e7b 1170 case LLDP_SNMP_REMOTE_SYSDESC:
7a53c5b9
VB
1171 *var_len = strlen(port->p_chassis->c_descr);
1172 return (u_char *)port->p_chassis->c_descr;
43c02e7b
VB
1173 case LLDP_SNMP_REMOTE_SYSCAP_SUP:
1174 *var_len = 1;
7a53c5b9 1175 bit = swap_bits(port->p_chassis->c_cap_available);
43c02e7b
VB
1176 return (u_char *)&bit;
1177 case LLDP_SNMP_REMOTE_SYSCAP_ENA:
1178 *var_len = 1;
7a53c5b9 1179 bit = swap_bits(port->p_chassis->c_cap_enabled);
43c02e7b 1180 return (u_char *)&bit;
a1347cd8 1181#ifdef ENABLE_DOT3
43c02e7b 1182 case LLDP_SNMP_REMOTE_DOT3_AUTONEG_SUPPORT:
7a53c5b9 1183 long_ret = 2 - port->p_autoneg_support;
43c02e7b
VB
1184 return (u_char *)&long_ret;
1185 case LLDP_SNMP_REMOTE_DOT3_AUTONEG_ENABLED:
7a53c5b9 1186 long_ret = 2 - port->p_autoneg_enabled;
43c02e7b
VB
1187 return (u_char *)&long_ret;
1188 case LLDP_SNMP_REMOTE_DOT3_AUTONEG_ADVERTISED:
1189 *var_len = 2;
7a53c5b9 1190 return (u_char *)&port->p_autoneg_advertised;
43c02e7b 1191 case LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU:
7a53c5b9 1192 long_ret = port->p_mau_type;
43c02e7b
VB
1193 return (u_char *)&long_ret;
1194 case LLDP_SNMP_REMOTE_DOT3_AGG_STATUS:
7a53c5b9 1195 bit = swap_bits((port->p_aggregid > 0) ? 3 : 0);
43c02e7b
VB
1196 *var_len = 1;
1197 return (u_char *)&bit;
1198 case LLDP_SNMP_REMOTE_DOT3_AGG_ID:
7a53c5b9 1199 long_ret = port->p_aggregid;
43c02e7b 1200 return (u_char *)&long_ret;
548109b2 1201 case LLDP_SNMP_REMOTE_DOT3_MFS:
7a53c5b9 1202 long_ret = port->p_mfs;
548109b2 1203 return (u_char *)&long_ret;
75b3469d
VB
1204#endif
1205#ifdef ENABLE_DOT1
1206 case LLDP_SNMP_REMOTE_DOT1_PVID:
7a53c5b9 1207 long_ret = port->p_pvid;
75b3469d 1208 return (u_char *)&long_ret;
a1347cd8 1209#endif
43c02e7b
VB
1210 default:
1211 break;
1212 }
1213 return NULL;
1214}
1215
1216static u_char*
1217agent_management(struct variable *vp, size_t *var_len, struct lldpd_chassis *chassis)
1218{
1219 static unsigned long int long_ret;
1220 static oid zeroDotZero[2] = {0, 0};
1221
1222 switch (vp->magic) {
1223 case LLDP_SNMP_LOCAL_ADDR_LEN:
1224 long_ret = 5;
1225 return (u_char*)&long_ret;
1226 case LLDP_SNMP_LOCAL_ADDR_IFSUBTYPE:
1227 case LLDP_SNMP_REMOTE_ADDR_IFSUBTYPE:
1228 if (chassis->c_mgmt_if != 0)
1229 long_ret = LLDP_MGMT_IFACE_IFINDEX;
1230 else
1231 long_ret = 1;
1232 return (u_char*)&long_ret;
1233 case LLDP_SNMP_LOCAL_ADDR_IFID:
1234 case LLDP_SNMP_REMOTE_ADDR_IFID:
1235 long_ret = chassis->c_mgmt_if;
1236 return (u_char*)&long_ret;
1237 case LLDP_SNMP_LOCAL_ADDR_OID:
1238 case LLDP_SNMP_REMOTE_ADDR_OID:
1239 *var_len = sizeof(zeroDotZero);
1240 return (u_char*)zeroDotZero;
1241 default:
1242 break;
1243 }
1244 return NULL;
1245}
1246
1247static u_char*
1248agent_h_local_management(struct variable *vp, oid *name, size_t *length,
1249 int exact, size_t *var_len, WriteMethod **write_method)
1250{
1251 oid *target, best[6];
1252 int result, target_len;
1253
7a53c5b9 1254 if (LOCAL_CHASSIS(scfg)->c_mgmt.s_addr == INADDR_ANY)
43c02e7b
VB
1255 return NULL;
1256
1257 if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) {
1258 memcpy(name, vp->name, sizeof(oid) * vp->namelen);
1259 *length = vp->namelen;
1260 }
1261
1262 *write_method = 0;
1263 *var_len = sizeof(long);
1264
1265 target = &name[vp->namelen];
1266 target_len = *length - vp->namelen;
1267
1268 best[0] = 1;
1269 best[1] = 4;
7a53c5b9
VB
1270 best[5] = LOCAL_CHASSIS(scfg)->c_mgmt.s_addr >> 24;
1271 best[4] = (LOCAL_CHASSIS(scfg)->c_mgmt.s_addr & 0xffffff) >> 16;
1272 best[3] = (LOCAL_CHASSIS(scfg)->c_mgmt.s_addr & 0xffff) >> 8;
1273 best[2] = LOCAL_CHASSIS(scfg)->c_mgmt.s_addr & 0xff;
43c02e7b 1274
bff3c98d 1275 if ((result = snmp_oid_compare(target, target_len, best, 6)) < 0) {
43c02e7b
VB
1276 if (exact)
1277 return NULL;
1278 memcpy(target, best, sizeof(oid) * 6);
1279 *length = vp->namelen + 6;
1280 } else if (exact && (result != 0))
1281 return NULL;
1282 else if (!exact && result == 0)
1283 return NULL;
1284
7a53c5b9 1285 return agent_management(vp, var_len, LOCAL_CHASSIS(scfg));
43c02e7b
VB
1286}
1287
1288static u_char*
1289agent_h_remote_management(struct variable *vp, oid *name, size_t *length,
1290 int exact, size_t *var_len, WriteMethod **write_method)
1291{
7a53c5b9 1292 struct lldpd_port *port;
43c02e7b 1293
7a53c5b9 1294 if ((port = header_tprindexed_table(vp, name, length,
4a2acc8e 1295 exact, var_len, write_method, TPR_VARIANT_IP)) == NULL)
43c02e7b
VB
1296 return NULL;
1297
7a53c5b9 1298 return agent_management(vp, var_len, port->p_chassis);
43c02e7b
VB
1299}
1300
1301static struct variable8 lldp_vars[] = {
1302 /* Scalars */
1303 {LLDP_SNMP_TXINTERVAL, ASN_INTEGER, RONLY, agent_h_scalars, 3, {1, 1, 1}},
1304 {LLDP_SNMP_TXMULTIPLIER, ASN_INTEGER, RONLY, agent_h_scalars, 3, {1, 1, 2}},
1305 {LLDP_SNMP_REINITDELAY, ASN_INTEGER, RONLY, agent_h_scalars, 3, {1, 1, 3}},
1306 {LLDP_SNMP_TXDELAY, ASN_INTEGER, RONLY, agent_h_scalars, 3, {1, 1, 4}},
1307 {LLDP_SNMP_NOTIFICATION, ASN_INTEGER, RONLY, agent_h_scalars, 3, {1, 1, 5}},
1308 {LLDP_SNMP_LASTUPDATE, ASN_TIMETICKS, RONLY, agent_h_scalars, 3, {1, 2, 1}},
1309 {LLDP_SNMP_STATS_INSERTS, ASN_GAUGE, RONLY, agent_h_scalars, 3, {1, 2, 2}},
1310 {LLDP_SNMP_STATS_DELETES, ASN_GAUGE, RONLY, agent_h_scalars, 3, {1, 2, 3}},
1311 {LLDP_SNMP_STATS_DROPS, ASN_GAUGE, RONLY, agent_h_scalars, 3, {1, 2, 4}},
1312 {LLDP_SNMP_STATS_AGEOUTS, ASN_GAUGE, RONLY, agent_h_scalars, 3, {1, 2, 5}},
1313 /* Local chassis */
1314 {LLDP_SNMP_LOCAL_CIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_local_chassis, 3, {1, 3, 1}},
1315 {LLDP_SNMP_LOCAL_CID, ASN_OCTET_STR, RONLY, agent_h_local_chassis, 3, {1, 3, 2}},
1316 {LLDP_SNMP_LOCAL_SYSNAME, ASN_OCTET_STR, RONLY, agent_h_local_chassis, 3, {1, 3, 3}},
1317 {LLDP_SNMP_LOCAL_SYSDESCR, ASN_OCTET_STR, RONLY, agent_h_local_chassis, 3, {1, 3, 4}},
1318 {LLDP_SNMP_LOCAL_SYSCAP_SUP, ASN_OCTET_STR, RONLY, agent_h_local_chassis, 3, {1, 3, 5}},
1319 {LLDP_SNMP_LOCAL_SYSCAP_ENA, ASN_OCTET_STR, RONLY, agent_h_local_chassis, 3, {1, 3, 6}},
1320 /* Stats */
1321 {LLDP_SNMP_STATS_TX, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 6, 1, 2}},
1322 {LLDP_SNMP_STATS_RX_DISCARDED, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 2}},
1323 {LLDP_SNMP_STATS_RX_ERRORS, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 3}},
1324 {LLDP_SNMP_STATS_RX, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 4}},
1325 {LLDP_SNMP_STATS_RX_TLVDISCARDED, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 5}},
1326 {LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 6}},
1327 {LLDP_SNMP_STATS_RX_AGEOUTS, ASN_GAUGE, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 7}},
1328 /* Local ports */
1329 {LLDP_SNMP_LOCAL_PIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_local_port, 5, {1, 3, 7, 1, 2}},
1330 {LLDP_SNMP_LOCAL_PID, ASN_OCTET_STR, RONLY, agent_h_local_port, 5, {1, 3, 7, 1, 3}},
1331 {LLDP_SNMP_LOCAL_PORTDESC, ASN_OCTET_STR, RONLY, agent_h_local_port, 5, {1, 3, 7, 1, 4}},
a1347cd8 1332#ifdef ENABLE_DOT3
43c02e7b
VB
1333 {LLDP_SNMP_LOCAL_DOT3_AUTONEG_SUPPORT, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1334 {1, 5, 4623, 1, 2, 1, 1, 1}},
1335 {LLDP_SNMP_LOCAL_DOT3_AUTONEG_ENABLED, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1336 {1, 5, 4623, 1, 2, 1, 1, 2}},
1337 {LLDP_SNMP_LOCAL_DOT3_AUTONEG_ADVERTISED, ASN_OCTET_STR, RONLY, agent_h_local_port, 8,
1338 {1, 5, 4623, 1, 2, 1, 1, 3}},
1339 {LLDP_SNMP_LOCAL_DOT3_AUTONEG_MAU, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1340 {1, 5, 4623, 1, 2, 1, 1, 4}},
1341 {LLDP_SNMP_LOCAL_DOT3_AGG_STATUS, ASN_OCTET_STR, RONLY, agent_h_local_port, 8,
1342 {1, 5, 4623, 1, 2, 3, 1, 1}},
1343 {LLDP_SNMP_LOCAL_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1344 {1, 5, 4623, 1, 2, 3, 1, 2}},
548109b2
VB
1345 {LLDP_SNMP_LOCAL_DOT3_MFS, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1346 {1, 5, 4623, 1, 2, 4, 1, 1}},
75b3469d
VB
1347#endif
1348#ifdef ENABLE_DOT1
1349 {LLDP_SNMP_LOCAL_DOT1_PVID, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1350 {1, 5, 32962, 1, 2, 1, 1, 1}},
a1347cd8 1351#endif
43c02e7b
VB
1352 /* Remote ports */
1353 {LLDP_SNMP_REMOTE_CIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 4}},
1354 {LLDP_SNMP_REMOTE_CID, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 5}},
1355 {LLDP_SNMP_REMOTE_PIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 6}},
1356 {LLDP_SNMP_REMOTE_PID, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 7}},
1357 {LLDP_SNMP_REMOTE_PORTDESC, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 8}},
1358 {LLDP_SNMP_REMOTE_SYSNAME, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 9}},
1359 {LLDP_SNMP_REMOTE_SYSDESC, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 10}},
1360 {LLDP_SNMP_REMOTE_SYSCAP_SUP, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 11}},
1361 {LLDP_SNMP_REMOTE_SYSCAP_ENA, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 12}},
a1347cd8 1362#ifdef ENABLE_DOT3
43c02e7b
VB
1363 {LLDP_SNMP_REMOTE_DOT3_AUTONEG_SUPPORT, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1364 {1, 5, 4623, 1, 3, 1, 1, 1}},
1365 {LLDP_SNMP_REMOTE_DOT3_AUTONEG_ENABLED, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1366 {1, 5, 4623, 1, 3, 1, 1, 2}},
1367 {LLDP_SNMP_REMOTE_DOT3_AUTONEG_ADVERTISED, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8,
1368 {1, 5, 4623, 1, 3, 1, 1, 3}},
1369 {LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1370 {1, 5, 4623, 1, 3, 1, 1, 4}},
1371 {LLDP_SNMP_REMOTE_DOT3_AGG_STATUS, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8,
1372 {1, 5, 4623, 1, 3, 3, 1, 1}},
1373 {LLDP_SNMP_REMOTE_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1374 {1, 5, 4623, 1, 3, 3, 1, 2}},
548109b2
VB
1375 {LLDP_SNMP_REMOTE_DOT3_MFS, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1376 {1, 5, 4623, 1, 3, 4, 1, 1}},
a1347cd8
VB
1377#endif
1378#ifdef ENABLE_DOT1
75b3469d
VB
1379 {LLDP_SNMP_REMOTE_DOT1_PVID, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1380 {1, 5, 32962, 1, 3, 1, 1, 1}},
43c02e7b
VB
1381 /* Local vlans */
1382 {LLDP_SNMP_LOCAL_DOT1_VLANNAME, ASN_OCTET_STR, RONLY, agent_h_local_vlan, 8,
1383 {1, 5, 32962, 1, 2, 3, 1, 2}},
1384 /* Remote vlans */
1385 {LLDP_SNMP_REMOTE_DOT1_VLANNAME, ASN_OCTET_STR, RONLY, agent_h_remote_vlan, 8,
1386 {1, 5, 32962, 1, 3, 3, 1, 2}},
a1347cd8 1387#endif
43c02e7b
VB
1388 /* Management address */
1389 {LLDP_SNMP_LOCAL_ADDR_LEN, ASN_INTEGER, RONLY, agent_h_local_management, 5,
1390 {1, 3, 8, 1, 3}},
1391 {LLDP_SNMP_LOCAL_ADDR_IFSUBTYPE, ASN_INTEGER, RONLY, agent_h_local_management, 5,
1392 {1, 3, 8, 1, 4}},
1393 {LLDP_SNMP_LOCAL_ADDR_IFID, ASN_INTEGER, RONLY, agent_h_local_management, 5,
1394 {1, 3, 8, 1, 5}},
1395 {LLDP_SNMP_LOCAL_ADDR_OID, ASN_OBJECT_ID, RONLY, agent_h_local_management, 5,
1396 {1, 3, 8, 1, 6}},
1397 {LLDP_SNMP_REMOTE_ADDR_IFSUBTYPE, ASN_INTEGER, RONLY, agent_h_remote_management, 5,
1398 {1, 4, 2, 1, 3}},
1399 {LLDP_SNMP_REMOTE_ADDR_IFID, ASN_INTEGER, RONLY, agent_h_remote_management, 5,
1400 {1, 4, 2, 1, 4}},
1401 {LLDP_SNMP_REMOTE_ADDR_OID, ASN_OBJECT_ID, RONLY, agent_h_remote_management, 5,
1402 {1, 4, 2, 1, 5}},
1d88c843
VB
1403#ifdef ENABLE_LLDPMED
1404 /* LLDP-MED local */
1405 {LLDP_SNMP_MED_LOCAL_CLASS, ASN_INTEGER, RONLY, agent_h_local_med, 6,
1406 {1, 5, 4795, 1, 1, 1}},
fd6aa9a3
VB
1407 {LLDP_SNMP_MED_LOCAL_POLICY_VID, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8,
1408 {1, 5, 4795, 1, 2, 1, 1, 2}},
1409 {LLDP_SNMP_MED_LOCAL_POLICY_PRIO, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8,
1410 {1, 5, 4795, 1, 2, 1, 1, 3}},
1411 {LLDP_SNMP_MED_LOCAL_POLICY_DSCP, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8,
1412 {1, 5, 4795, 1, 2, 1, 1, 4}},
1413 {LLDP_SNMP_MED_LOCAL_POLICY_UNKNOWN, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8,
1414 {1, 5, 4795, 1, 2, 1, 1, 5}},
1415 {LLDP_SNMP_MED_LOCAL_POLICY_TAGGED, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8,
1416 {1, 5, 4795, 1, 2, 1, 1, 6}},
1d88c843
VB
1417 {LLDP_SNMP_MED_LOCAL_HW, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1418 {1, 5, 4795, 1, 2, 2}},
1419 {LLDP_SNMP_MED_LOCAL_FW, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1420 {1, 5, 4795, 1, 2, 3}},
1421 {LLDP_SNMP_MED_LOCAL_SW, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1422 {1, 5, 4795, 1, 2, 4}},
1423 {LLDP_SNMP_MED_LOCAL_SN, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1424 {1, 5, 4795, 1, 2, 5}},
1425 {LLDP_SNMP_MED_LOCAL_MANUF, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1426 {1, 5, 4795, 1, 2, 6}},
1427 {LLDP_SNMP_MED_LOCAL_MODEL, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1428 {1, 5, 4795, 1, 2, 7}},
1429 {LLDP_SNMP_MED_LOCAL_ASSET, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1430 {1, 5, 4795, 1, 2, 8}},
1dcd4665
VB
1431 {LLDP_SNMP_MED_LOCAL_LOCATION, ASN_OCTET_STR, RONLY, agent_h_local_med_location, 8,
1432 {1, 5, 4795, 1, 2, 9, 1, 2}},
8e44f2dc
VB
1433 {LLDP_SNMP_MED_POE_DEVICETYPE, ASN_INTEGER, RONLY, agent_h_local_med, 6,
1434 {1, 5, 4795, 1, 2, 10}},
1435 {LLDP_SNMP_MED_POE_PSE_POWERVAL, ASN_GAUGE, RONLY, agent_h_local_med_power, 8,
1436 {1, 5, 4795, 1, 2, 11, 1, 1}},
1437 {LLDP_SNMP_MED_POE_PSE_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_local_med_power, 8,
1438 {1, 5, 4795, 1, 2, 11, 1, 2}},
1439 {LLDP_SNMP_MED_POE_PSE_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_local_med, 6,
1440 {1, 5, 4795, 1, 2, 12}},
1441 {LLDP_SNMP_MED_POE_PD_POWERVAL, ASN_GAUGE, RONLY, agent_h_local_med, 6,
1442 {1, 5, 4795, 1, 2, 13}},
1443 {LLDP_SNMP_MED_POE_PD_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_local_med, 6,
1444 {1, 5, 4795, 1, 2, 14}},
1445 {LLDP_SNMP_MED_POE_PD_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_local_med, 6,
1446 {1, 5, 4795, 1, 2, 15}},
1d88c843 1447 /* LLDP-MED remote */
40ecae87 1448 {LLDP_SNMP_MED_REMOTE_CAP_AVAILABLE, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1d88c843 1449 {1, 5, 4795, 1, 3, 1, 1, 1}},
40ecae87 1450 {LLDP_SNMP_MED_REMOTE_CAP_ENABLED, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1d88c843
VB
1451 {1, 5, 4795, 1, 3, 1, 1, 2}},
1452 {LLDP_SNMP_MED_REMOTE_CLASS, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1453 {1, 5, 4795, 1, 3, 1, 1, 3}},
1454 {LLDP_SNMP_MED_REMOTE_HW, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1455 {1, 5, 4795, 1, 3, 3, 1, 1}},
1456 {LLDP_SNMP_MED_REMOTE_FW, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1457 {1, 5, 4795, 1, 3, 3, 1, 2}},
1458 {LLDP_SNMP_MED_REMOTE_SW, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1459 {1, 5, 4795, 1, 3, 3, 1, 3}},
1460 {LLDP_SNMP_MED_REMOTE_SN, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1461 {1, 5, 4795, 1, 3, 3, 1, 4}},
1462 {LLDP_SNMP_MED_REMOTE_MANUF, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1463 {1, 5, 4795, 1, 3, 3, 1, 5}},
1464 {LLDP_SNMP_MED_REMOTE_MODEL, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1465 {1, 5, 4795, 1, 3, 3, 1, 6}},
1466 {LLDP_SNMP_MED_REMOTE_ASSET, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1467 {1, 5, 4795, 1, 3, 3, 1, 7}},
4a2acc8e
VB
1468 {LLDP_SNMP_MED_REMOTE_POLICY_VID, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8,
1469 {1, 5, 4795, 1, 3, 2, 1, 2}},
1470 {LLDP_SNMP_MED_REMOTE_POLICY_PRIO, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8,
1471 {1, 5, 4795, 1, 3, 2, 1, 3}},
1472 {LLDP_SNMP_MED_REMOTE_POLICY_DSCP, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8,
1473 {1, 5, 4795, 1, 3, 2, 1, 4}},
1474 {LLDP_SNMP_MED_REMOTE_POLICY_UNKNOWN, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8,
1475 {1, 5, 4795, 1, 3, 2, 1, 5}},
1476 {LLDP_SNMP_MED_REMOTE_POLICY_TAGGED, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8,
1477 {1, 5, 4795, 1, 3, 2, 1, 6}},
1478 {LLDP_SNMP_MED_REMOTE_LOCATION, ASN_OCTET_STR, RONLY, agent_h_remote_med_location, 8,
1479 {1, 5, 4795, 1, 3, 4, 1, 2}},
8e44f2dc 1480 {LLDP_SNMP_MED_POE_DEVICETYPE, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1be9e1b5 1481 {1, 5, 4795, 1, 3, 5, 1, 1}},
8e44f2dc 1482 {LLDP_SNMP_MED_POE_PSE_POWERVAL, ASN_GAUGE, RONLY, agent_h_remote_med, 8,
1be9e1b5 1483 {1, 5, 4795, 1, 3, 6, 1, 1}},
8e44f2dc 1484 {LLDP_SNMP_MED_POE_PSE_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1be9e1b5 1485 {1, 5, 4795, 1, 3, 6, 1, 2}},
8e44f2dc 1486 {LLDP_SNMP_MED_POE_PSE_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1be9e1b5 1487 {1, 5, 4795, 1, 3, 6, 1, 3}},
8e44f2dc 1488 {LLDP_SNMP_MED_POE_PD_POWERVAL, ASN_GAUGE, RONLY, agent_h_remote_med, 8,
1be9e1b5 1489 {1, 5, 4795, 1, 3, 7, 1, 1}},
8e44f2dc 1490 {LLDP_SNMP_MED_POE_PD_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1be9e1b5 1491 {1, 5, 4795, 1, 3, 7, 1, 2}},
8e44f2dc 1492 {LLDP_SNMP_MED_POE_PD_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1be9e1b5 1493 {1, 5, 4795, 1, 3, 7, 1, 3}},
1d88c843 1494#endif
43c02e7b
VB
1495};
1496
1497void
bbea66e1 1498agent_init(struct lldpd *cfg, char *agentx, int debug)
43c02e7b
VB
1499{
1500 int rc;
6bb9c4e0 1501#ifdef HAVE___PROGNAME
43c02e7b 1502 extern char *__progname;
6bb9c4e0
VB
1503#else
1504# define __progname "lldpd"
1505#endif
43c02e7b
VB
1506
1507 LLOG_INFO("Enable SNMP subagent");
1508 netsnmp_enable_subagent();
1509 snmp_disable_log();
1510 if (debug)
1511 snmp_enable_stderrlog();
1512 else
1513 snmp_enable_syslog_ident(__progname, LOG_DAEMON);
1514
1515 scfg = cfg;
1516
37954d62
VB
1517 /* We are chrooted, we don't want to handle persistent states */
1518 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
1519 NETSNMP_DS_LIB_DONT_PERSIST_STATE, TRUE);
1520 /* Do not load any MIB */
1521 setenv("MIBS", "", 1);
43c02e7b 1522
d72a05d4
VB
1523 /* We provide our UNIX domain transport */
1524 agent_priv_register_domain();
1525
bbea66e1
V
1526 if (agentx)
1527 netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
1528 NETSNMP_DS_AGENT_X_SOCKET, agentx);
37954d62 1529 init_agent("lldpAgent");
43c02e7b 1530 REGISTER_MIB("lldp", lldp_vars, variable8, lldp_oid);
43c02e7b
VB
1531 init_snmp("lldpAgent");
1532
1533 if ((rc = register_sysORTable(lldp_oid, OID_LENGTH(lldp_oid),
1534 "lldpMIB implementation by lldpd")) != 0)
1535 LLOG_WARNX("Unable to register to sysORTable (%d)", rc);
1536}
1537
1538void
1539agent_shutdown()
1540{
1541 unregister_sysORTable(lldp_oid, OID_LENGTH(lldp_oid));
1542 snmp_shutdown("lldpAgent");
1543}