1 /* -*- mode: c; c-file-style: "openbsd" -*- */
3 * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx>
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 #if HAVE_NET_SNMP_AGENT_UTIL_FUNCS_H
25 # include <net-snmp/agent/util_funcs.h>
27 /* The above header may be buggy. We just need this function. */
28 int header_generic(struct variable
*, oid
*, size_t *, int, size_t *, WriteMethod
**);
32 extern int register_sysORTable(oid
*, size_t, const char *);
33 extern int unregister_sysORTable(oid
*, size_t);
35 /* Global variable because no way to pass it as argument. Should not be used
37 #define scfg agent_scfg
38 struct lldpd
*agent_scfg
;
43 n
= ((n
& 0xF0) >> 4) | ((n
& 0x0F) << 4);
44 n
= ((n
& 0xCC) >> 2) | ((n
& 0x33) << 2);
45 n
= ((n
& 0xAA) >> 1) | ((n
& 0x55) << 1);
50 extern struct timeval starttime
;
52 lastchange(struct lldpd_port
*port
)
54 if (port
->p_lastchange
> starttime
.tv_sec
)
55 return (port
->p_lastchange
- starttime
.tv_sec
) * 100;
60 Helper functions to build header_*indexed_table() functions.
61 Those functions keep an internal state. They are not reentrant!
65 oid
*name
; /* Requested/returned OID */
66 size_t *length
; /* Length of above OID */
68 oid best
[MAX_OID_LEN
]; /* Best OID */
69 size_t best_len
; /* Best OID length */
70 void *entity
; /* Best entity */
72 static struct header_index header_idx
;
75 header_index_init(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
76 size_t *var_len
, WriteMethod
**write_method
)
78 /* If the requested OID name is less than OID prefix we
79 handle, adjust it to our prefix. */
80 if ((snmp_oid_compare(name
, *length
, vp
->name
, vp
->namelen
)) < 0) {
81 memcpy(name
, vp
->name
, sizeof(oid
) * vp
->namelen
);
82 *length
= vp
->namelen
;
84 /* Now, we can only handle OID matching our prefix. Those two
85 tests are not really necessary since NetSNMP won't give us
86 OID "above" our prefix. But this makes unit tests
88 if (*length
< vp
->namelen
) return 0;
89 if (memcmp(name
, vp
->name
, vp
->namelen
* sizeof(oid
))) return 0;
91 if (write_method
!= NULL
) *write_method
= 0;
92 *var_len
= sizeof(long);
94 /* Initialize our header index structure */
96 header_idx
.name
= name
;
97 header_idx
.length
= length
;
98 header_idx
.exact
= exact
;
99 header_idx
.best_len
= 0;
100 header_idx
.entity
= NULL
;
105 header_index_add(oid
*index
, size_t len
, void *entity
)
111 target
= header_idx
.name
+ header_idx
.vp
->namelen
;
112 target_len
= *header_idx
.length
- header_idx
.vp
->namelen
;
113 if ((result
= snmp_oid_compare(index
, len
, target
, target_len
)) < 0)
114 return 0; /* Too small. */
115 if (result
== 0) return header_idx
.exact
;
116 if (header_idx
.best_len
== 0 ||
117 (snmp_oid_compare(index
, len
, header_idx
.best
, header_idx
.best_len
) < 0)) {
118 memcpy(header_idx
.best
, index
, sizeof(oid
) * len
);
119 header_idx
.best_len
= len
;
120 header_idx
.entity
= entity
;
122 return 0; /* No best match yet. */
128 if (header_idx
.entity
== NULL
) return NULL
;
129 if (header_idx
.exact
) return NULL
;
130 memcpy(header_idx
.name
+ header_idx
.vp
->namelen
, header_idx
.best
,
131 sizeof(oid
) * header_idx
.best_len
);
132 *header_idx
.length
= header_idx
.vp
->namelen
+ header_idx
.best_len
;
133 return header_idx
.entity
;
135 /* ----------------------------- */
137 static struct lldpd_hardware
*
138 header_portindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
139 size_t *var_len
, WriteMethod
**write_method
)
141 struct lldpd_hardware
*hardware
;
143 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
145 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
146 oid index
[1] = { hardware
->h_ifindex
};
147 if (header_index_add(index
, 1, hardware
)) return hardware
;
149 return header_index_best();
152 #ifdef ENABLE_LLDPMED
153 static struct lldpd_med_policy
*
154 header_pmedindexed_policy_table(struct variable
*vp
, oid
*name
, size_t *length
,
155 int exact
, size_t *var_len
, WriteMethod
**write_method
)
157 struct lldpd_hardware
*hardware
;
161 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
163 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
164 for (i
= 0; i
< LLDP_MED_APPTYPE_LAST
; i
++) {
165 if (hardware
->h_lport
.p_med_policy
[i
].type
!= i
+ 1) continue;
166 index
[0] = hardware
->h_ifindex
;
168 if (header_index_add(index
, 2,
169 &hardware
->h_lport
.p_med_policy
[i
]))
170 return &hardware
->h_lport
.p_med_policy
[i
];
173 return header_index_best();
176 static struct lldpd_med_loc
*
177 header_pmedindexed_location_table(struct variable
*vp
, oid
*name
, size_t *length
,
178 int exact
, size_t *var_len
, WriteMethod
**write_method
)
180 struct lldpd_hardware
*hardware
;
184 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
186 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
187 for (i
= 0; i
< LLDP_MED_LOCFORMAT_LAST
; i
++) {
188 if (hardware
->h_lport
.p_med_location
[i
].format
!= i
+ 1)
190 index
[0] = hardware
->h_ifindex
;
192 if (header_index_add(index
, 2,
193 &hardware
->h_lport
.p_med_location
[i
]))
194 return &hardware
->h_lport
.p_med_location
[i
];
197 return header_index_best();
201 static struct lldpd_port
*
202 header_tprindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
203 size_t *var_len
, WriteMethod
**write_method
, int withmed
)
205 struct lldpd_hardware
*hardware
;
206 struct lldpd_port
*port
;
209 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
211 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
212 TAILQ_FOREACH (port
, &hardware
->h_rports
, p_entries
) {
213 if (SMART_HIDDEN(port
)) continue;
214 #ifdef ENABLE_LLDPMED
215 if (withmed
&& !port
->p_chassis
->c_med_cap_available
) continue;
217 index
[0] = lastchange(port
);
218 index
[1] = hardware
->h_ifindex
;
219 index
[2] = port
->p_chassis
->c_index
;
220 if (header_index_add(index
, 3, port
)) return port
;
223 return header_index_best();
226 static struct lldpd_mgmt
*
227 header_ipindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
228 size_t *var_len
, WriteMethod
**write_method
)
230 struct lldpd_chassis
*chassis
= LOCAL_CHASSIS(scfg
);
231 struct lldpd_mgmt
*mgmt
;
234 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
236 TAILQ_FOREACH (mgmt
, &chassis
->c_mgmt
, m_entries
) {
238 switch (mgmt
->m_family
) {
248 index
[1] = mgmt
->m_addrsize
;
249 if (index
[1] > sizeof(index
) - 2) continue; /* Odd... */
250 for (i
= 0; i
< index
[1]; i
++)
251 index
[i
+ 2] = mgmt
->m_addr
.octets
[i
];
252 if (header_index_add(index
, 2 + index
[1], mgmt
)) return mgmt
;
255 return header_index_best();
258 static struct lldpd_mgmt
*
259 header_tpripindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
260 size_t *var_len
, WriteMethod
**write_method
)
262 struct lldpd_hardware
*hardware
;
263 struct lldpd_port
*port
;
264 struct lldpd_mgmt
*mgmt
;
267 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
269 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
270 TAILQ_FOREACH (port
, &hardware
->h_rports
, p_entries
) {
271 if (SMART_HIDDEN(port
)) continue;
272 TAILQ_FOREACH (mgmt
, &port
->p_chassis
->c_mgmt
, m_entries
) {
274 index
[0] = lastchange(port
);
275 index
[1] = hardware
->h_ifindex
;
276 index
[2] = port
->p_chassis
->c_index
;
277 switch (mgmt
->m_family
) {
287 index
[4] = mgmt
->m_addrsize
;
288 if (index
[4] > sizeof(index
) - 5) continue; /* Odd... */
289 for (i
= 0; i
< index
[4]; i
++)
290 index
[i
+ 5] = mgmt
->m_addr
.octets
[i
];
291 if (header_index_add(index
, 5 + index
[4], mgmt
))
296 return header_index_best();
300 static struct lldpd_custom
*
301 header_tprcustomindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
302 size_t *var_len
, WriteMethod
**write_method
)
304 struct lldpd_hardware
*hardware
;
305 struct lldpd_port
*port
;
306 struct lldpd_custom
*custom
;
310 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
312 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
313 TAILQ_FOREACH (port
, &hardware
->h_rports
, p_entries
) {
314 if (SMART_HIDDEN(port
)) continue;
316 TAILQ_FOREACH (custom
, &port
->p_custom_list
, next
) {
317 index
[0] = lastchange(port
);
318 index
[1] = hardware
->h_ifindex
;
319 index
[2] = port
->p_chassis
->c_index
;
320 index
[3] = custom
->oui
[0];
321 index
[4] = custom
->oui
[1];
322 index
[5] = custom
->oui
[2];
323 index
[6] = custom
->subtype
;
325 if (header_index_add(index
, 8, custom
)) return custom
;
329 return header_index_best();
333 #ifdef ENABLE_LLDPMED
334 # define TPR_VARIANT_MED_POLICY 2
335 # define TPR_VARIANT_MED_LOCATION 3
337 header_tprmedindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
338 size_t *var_len
, WriteMethod
**write_method
, int variant
)
340 struct lldpd_hardware
*hardware
;
341 struct lldpd_port
*port
;
345 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
347 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
348 TAILQ_FOREACH (port
, &hardware
->h_rports
, p_entries
) {
349 if (SMART_HIDDEN(port
)) continue;
350 if (!port
->p_chassis
->c_med_cap_available
) continue;
352 case TPR_VARIANT_MED_POLICY
:
353 for (j
= 0; j
< LLDP_MED_APPTYPE_LAST
; j
++) {
354 if (port
->p_med_policy
[j
].type
!= j
+ 1)
356 index
[0] = lastchange(port
);
357 index
[1] = hardware
->h_ifindex
;
358 index
[2] = port
->p_chassis
->c_index
;
360 if (header_index_add(index
, 4,
361 &port
->p_med_policy
[j
]))
362 return &port
->p_med_policy
[j
];
365 case TPR_VARIANT_MED_LOCATION
:
366 for (j
= 0; j
< LLDP_MED_LOCFORMAT_LAST
; j
++) {
367 if (port
->p_med_location
[j
].format
!= j
+ 1)
369 index
[0] = lastchange(port
);
370 index
[1] = hardware
->h_ifindex
;
371 index
[2] = port
->p_chassis
->c_index
;
373 if (header_index_add(index
, 4,
374 &port
->p_med_location
[j
]))
375 return &port
->p_med_location
[j
];
381 return header_index_best();
386 static struct lldpd_vlan
*
387 header_pvindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
388 size_t *var_len
, WriteMethod
**write_method
)
390 struct lldpd_hardware
*hardware
;
391 struct lldpd_vlan
*vlan
;
393 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
395 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
396 TAILQ_FOREACH (vlan
, &hardware
->h_lport
.p_vlans
, v_entries
) {
397 oid index
[2] = { hardware
->h_ifindex
, vlan
->v_vid
};
398 if (header_index_add(index
, 2, vlan
)) return vlan
;
401 return header_index_best();
404 static struct lldpd_vlan
*
405 header_tprvindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
406 size_t *var_len
, WriteMethod
**write_method
)
408 struct lldpd_hardware
*hardware
;
409 struct lldpd_port
*port
;
410 struct lldpd_vlan
*vlan
;
412 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
414 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
415 TAILQ_FOREACH (port
, &hardware
->h_rports
, p_entries
) {
416 if (SMART_HIDDEN(port
)) continue;
417 TAILQ_FOREACH (vlan
, &port
->p_vlans
, v_entries
) {
418 oid index
[4] = { lastchange(port
), hardware
->h_ifindex
,
419 port
->p_chassis
->c_index
, vlan
->v_vid
};
420 if (header_index_add(index
, 4, vlan
)) return vlan
;
424 return header_index_best();
427 static struct lldpd_ppvid
*
428 header_pppvidindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
429 size_t *var_len
, WriteMethod
**write_method
)
431 struct lldpd_hardware
*hardware
;
432 struct lldpd_ppvid
*ppvid
;
434 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
436 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
437 TAILQ_FOREACH (ppvid
, &hardware
->h_lport
.p_ppvids
, p_entries
) {
438 oid index
[2] = { hardware
->h_ifindex
, ppvid
->p_ppvid
};
439 if (header_index_add(index
, 2, ppvid
)) return ppvid
;
442 return header_index_best();
445 static struct lldpd_ppvid
*
446 header_tprppvidindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
447 size_t *var_len
, WriteMethod
**write_method
)
449 struct lldpd_hardware
*hardware
;
450 struct lldpd_port
*port
;
451 struct lldpd_ppvid
*ppvid
;
453 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
455 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
456 TAILQ_FOREACH (port
, &hardware
->h_rports
, p_entries
) {
457 if (SMART_HIDDEN(port
)) continue;
458 TAILQ_FOREACH (ppvid
, &port
->p_ppvids
, p_entries
) {
459 oid index
[4] = { lastchange(port
), hardware
->h_ifindex
,
460 port
->p_chassis
->c_index
, ppvid
->p_ppvid
};
461 if (header_index_add(index
, 4, ppvid
)) return ppvid
;
465 return header_index_best();
468 static struct lldpd_pi
*
469 header_ppiindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
470 size_t *var_len
, WriteMethod
**write_method
)
472 struct lldpd_hardware
*hardware
;
475 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
477 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
478 TAILQ_FOREACH (pi
, &hardware
->h_lport
.p_pids
, p_entries
) {
479 oid index
[2] = { hardware
->h_ifindex
,
480 frame_checksum((const u_char
*)pi
->p_pi
, pi
->p_pi_len
,
482 if (header_index_add(index
, 2, pi
)) return pi
;
485 return header_index_best();
488 static struct lldpd_pi
*
489 header_tprpiindexed_table(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
490 size_t *var_len
, WriteMethod
**write_method
)
492 struct lldpd_hardware
*hardware
;
493 struct lldpd_port
*port
;
496 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
))
498 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
499 TAILQ_FOREACH (port
, &hardware
->h_rports
, p_entries
) {
500 if (SMART_HIDDEN(port
)) continue;
501 TAILQ_FOREACH (pi
, &port
->p_pids
, p_entries
) {
502 oid index
[4] = { lastchange(port
), hardware
->h_ifindex
,
503 port
->p_chassis
->c_index
,
504 frame_checksum((const u_char
*)pi
->p_pi
,
506 if (header_index_add(index
, 4, pi
)) return pi
;
510 return header_index_best();
515 #define LLDP_SNMP_TXINTERVAL 1
516 #define LLDP_SNMP_TXMULTIPLIER 2
517 #define LLDP_SNMP_REINITDELAY 3
518 #define LLDP_SNMP_TXDELAY 4
519 #define LLDP_SNMP_NOTIFICATION 5
520 #define LLDP_SNMP_LASTUPDATE 6
521 #define LLDP_SNMP_STATS_INSERTS 7
522 #define LLDP_SNMP_STATS_DELETES 8
523 #define LLDP_SNMP_STATS_DROPS 9
524 #define LLDP_SNMP_STATS_AGEOUTS 10
526 #define LLDP_SNMP_CIDSUBTYPE 1
527 #define LLDP_SNMP_CID 2
528 #define LLDP_SNMP_SYSNAME 3
529 #define LLDP_SNMP_SYSDESCR 4
530 #define LLDP_SNMP_SYSCAP_SUP 5
531 #define LLDP_SNMP_SYSCAP_ENA 6
533 #define LLDP_SNMP_STATS_TX 2
534 #define LLDP_SNMP_STATS_RX_DISCARDED 4
535 #define LLDP_SNMP_STATS_RX_ERRORS 5
536 #define LLDP_SNMP_STATS_RX 6
537 #define LLDP_SNMP_STATS_RX_TLVDISCARDED 7
538 #define LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED 8
539 #define LLDP_SNMP_STATS_RX_AGEOUTS 9
541 #define LLDP_SNMP_PIDSUBTYPE 2
542 #define LLDP_SNMP_PID 3
543 #define LLDP_SNMP_PORTDESC 4
544 #define LLDP_SNMP_DOT3_AUTONEG_SUPPORT 5
545 #define LLDP_SNMP_DOT3_AUTONEG_ENABLED 6
546 #define LLDP_SNMP_DOT3_AUTONEG_ADVERTISED 7
547 #define LLDP_SNMP_DOT3_AUTONEG_MAU 8
548 #define LLDP_SNMP_DOT3_AGG_STATUS 9
549 #define LLDP_SNMP_DOT3_AGG_ID 10
550 #define LLDP_SNMP_DOT3_MFS 11
551 #define LLDP_SNMP_DOT3_POWER_DEVICETYPE 12
552 #define LLDP_SNMP_DOT3_POWER_SUPPORT 13
553 #define LLDP_SNMP_DOT3_POWER_ENABLED 14
554 #define LLDP_SNMP_DOT3_POWER_PAIRCONTROL 15
555 #define LLDP_SNMP_DOT3_POWER_PAIRS 16
556 #define LLDP_SNMP_DOT3_POWER_CLASS 17
557 #define LLDP_SNMP_DOT3_POWER_TYPE 18
558 #define LLDP_SNMP_DOT3_POWER_SOURCE 19
559 #define LLDP_SNMP_DOT3_POWER_PRIORITY 20
560 #define LLDP_SNMP_DOT3_POWER_REQUESTED 21
561 #define LLDP_SNMP_DOT3_POWER_ALLOCATED 22
562 #define LLDP_SNMP_DOT1_PVID 23
564 #define LLDP_SNMP_DOT1_VLANNAME 1
565 /* Protocol VLAN IDs */
566 #define LLDP_SNMP_DOT1_PPVLAN_SUPPORTED 2
567 #define LLDP_SNMP_DOT1_PPVLAN_ENABLED 3
568 /* Protocol Identity */
569 #define LLDP_SNMP_DOT1_PI 1
570 /* Management address */
571 #define LLDP_SNMP_ADDR_LEN 1
572 #define LLDP_SNMP_ADDR_IFSUBTYPE 2
573 #define LLDP_SNMP_ADDR_IFID 3
574 #define LLDP_SNMP_ADDR_OID 4
576 #define LLDP_SNMP_ORG_DEF_INFO 1
578 #define LLDP_SNMP_MED_CAP_AVAILABLE 1
579 #define LLDP_SNMP_MED_CAP_ENABLED 2
580 #define LLDP_SNMP_MED_CLASS 3
581 #define LLDP_SNMP_MED_HW 4
582 #define LLDP_SNMP_MED_FW 5
583 #define LLDP_SNMP_MED_SW 6
584 #define LLDP_SNMP_MED_SN 7
585 #define LLDP_SNMP_MED_MANUF 8
586 #define LLDP_SNMP_MED_MODEL 9
587 #define LLDP_SNMP_MED_ASSET 10
588 #define LLDP_SNMP_MED_POLICY_VID 11
589 #define LLDP_SNMP_MED_POLICY_PRIO 12
590 #define LLDP_SNMP_MED_POLICY_DSCP 13
591 #define LLDP_SNMP_MED_POLICY_UNKNOWN 14
592 #define LLDP_SNMP_MED_POLICY_TAGGED 15
593 #define LLDP_SNMP_MED_LOCATION 16
594 #define LLDP_SNMP_MED_POE_DEVICETYPE 17
595 #define LLDP_SNMP_MED_POE_PSE_POWERVAL 19
596 #define LLDP_SNMP_MED_POE_PSE_POWERSOURCE 20
597 #define LLDP_SNMP_MED_POE_PSE_POWERPRIORITY 21
598 #define LLDP_SNMP_MED_POE_PD_POWERVAL 22
599 #define LLDP_SNMP_MED_POE_PD_POWERSOURCE 23
600 #define LLDP_SNMP_MED_POE_PD_POWERPRIORITY 24
602 /* The following macro should be used anytime where the selected OID
603 is finally not returned (for example, when the associated data is
604 not available). In this case, we retry the function with the next
608 if (!exact && (name[*length - 1] < MAX_SUBID)) \
609 return X(vp, name, length, exact, var_len, write_method); \
614 agent_h_scalars(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
615 size_t *var_len
, WriteMethod
**write_method
)
617 static unsigned long long_ret
;
618 struct lldpd_hardware
*hardware
;
619 struct lldpd_port
*port
;
621 if (header_generic(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
624 case LLDP_SNMP_TXINTERVAL
:
625 long_ret
= (scfg
->g_config
.c_tx_interval
+ 999) / 1000;
626 return (u_char
*)&long_ret
;
627 case LLDP_SNMP_TXMULTIPLIER
:
628 long_ret
= scfg
->g_config
.c_tx_hold
;
629 return (u_char
*)&long_ret
;
630 case LLDP_SNMP_REINITDELAY
:
632 return (u_char
*)&long_ret
;
633 case LLDP_SNMP_TXDELAY
:
634 long_ret
= LLDPD_TX_MSGDELAY
;
635 return (u_char
*)&long_ret
;
636 case LLDP_SNMP_NOTIFICATION
:
638 return (u_char
*)&long_ret
;
639 case LLDP_SNMP_LASTUPDATE
:
641 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
642 /* Check if the last removal of a remote port on this local port
643 * was the last change. */
644 if (hardware
->h_lport
.p_lastremove
> long_ret
)
645 long_ret
= hardware
->h_lport
.p_lastremove
;
646 /* Check if any change on the existing remote ports was the last
648 TAILQ_FOREACH (port
, &hardware
->h_rports
, p_entries
) {
649 if (SMART_HIDDEN(port
)) continue;
650 if (port
->p_lastchange
> long_ret
)
651 long_ret
= port
->p_lastchange
;
654 if (long_ret
) long_ret
= (long_ret
- starttime
.tv_sec
) * 100;
655 return (u_char
*)&long_ret
;
656 case LLDP_SNMP_STATS_INSERTS
:
657 /* We assume this is equal to valid frames received on all ports */
659 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
)
660 long_ret
+= hardware
->h_insert_cnt
;
661 return (u_char
*)&long_ret
;
662 case LLDP_SNMP_STATS_AGEOUTS
:
664 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
)
665 long_ret
+= hardware
->h_ageout_cnt
;
666 return (u_char
*)&long_ret
;
667 case LLDP_SNMP_STATS_DELETES
:
669 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
)
670 long_ret
+= hardware
->h_delete_cnt
;
671 return (u_char
*)&long_ret
;
672 case LLDP_SNMP_STATS_DROPS
:
674 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
)
675 long_ret
+= hardware
->h_drop_cnt
;
676 return (u_char
*)&long_ret
;
683 #ifdef ENABLE_LLDPMED
685 agent_v_med_power(struct variable
*vp
, size_t *var_len
, struct lldpd_med_power
*power
)
687 static unsigned long long_ret
;
690 case LLDP_SNMP_MED_POE_DEVICETYPE
:
691 switch (power
->devicetype
) {
692 case LLDP_MED_POW_TYPE_PSE
:
695 case LLDP_MED_POW_TYPE_PD
:
704 return (u_char
*)&long_ret
;
705 case LLDP_SNMP_MED_POE_PSE_POWERVAL
:
706 case LLDP_SNMP_MED_POE_PD_POWERVAL
:
707 if (((vp
->magic
== LLDP_SNMP_MED_POE_PSE_POWERVAL
) &&
708 (power
->devicetype
== LLDP_MED_POW_TYPE_PSE
)) ||
709 ((vp
->magic
== LLDP_SNMP_MED_POE_PD_POWERVAL
) &&
710 (power
->devicetype
== LLDP_MED_POW_TYPE_PD
))) {
711 long_ret
= power
->val
;
712 return (u_char
*)&long_ret
;
715 case LLDP_SNMP_MED_POE_PSE_POWERSOURCE
:
716 if (power
->devicetype
== LLDP_MED_POW_TYPE_PSE
) {
717 switch (power
->source
) {
718 case LLDP_MED_POW_SOURCE_PRIMARY
:
721 case LLDP_MED_POW_SOURCE_BACKUP
:
727 return (u_char
*)&long_ret
;
730 case LLDP_SNMP_MED_POE_PD_POWERSOURCE
:
731 if (power
->devicetype
== LLDP_MED_POW_TYPE_PD
) {
732 switch (power
->source
) {
733 case LLDP_MED_POW_SOURCE_PSE
:
736 case LLDP_MED_POW_SOURCE_LOCAL
:
739 case LLDP_MED_POW_SOURCE_BOTH
:
745 return (u_char
*)&long_ret
;
748 case LLDP_SNMP_MED_POE_PSE_POWERPRIORITY
:
749 case LLDP_SNMP_MED_POE_PD_POWERPRIORITY
:
750 if (((vp
->magic
== LLDP_SNMP_MED_POE_PSE_POWERPRIORITY
) &&
751 (power
->devicetype
== LLDP_MED_POW_TYPE_PSE
)) ||
752 ((vp
->magic
== LLDP_SNMP_MED_POE_PD_POWERPRIORITY
) &&
753 (power
->devicetype
== LLDP_MED_POW_TYPE_PD
))) {
754 switch (power
->priority
) {
755 case LLDP_MED_POW_PRIO_CRITICAL
:
758 case LLDP_MED_POW_PRIO_HIGH
:
761 case LLDP_MED_POW_PRIO_LOW
:
767 return (u_char
*)&long_ret
;
775 agent_h_local_med_power(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
776 size_t *var_len
, WriteMethod
**write_method
)
778 struct lldpd_med_power
*power
= NULL
;
779 struct lldpd_hardware
*hardware
;
782 if (!LOCAL_CHASSIS(scfg
)->c_med_cap_available
) return NULL
;
783 if (header_generic(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
785 /* LLDP-MED requires only one device type for all
786 ports. Moreover, a PSE can only have one power source. At
787 least, all PD values are global and not per-port. We try to
788 do our best. For device type, we decide on the number of
790 TAILQ_FOREACH (hardware
, &scfg
->g_hardware
, h_entries
) {
791 if (hardware
->h_lport
.p_med_power
.devicetype
== LLDP_MED_POW_TYPE_PSE
) {
793 if (pse
== 1) /* Take this port as a reference */
794 power
= &hardware
->h_lport
.p_med_power
;
795 } else if (hardware
->h_lport
.p_med_power
.devicetype
==
796 LLDP_MED_POW_TYPE_PD
) {
798 if (pse
== -1) /* Take this one instead */
799 power
= &hardware
->h_lport
.p_med_power
;
804 if ((a
= agent_v_med_power(vp
, var_len
, power
)) != NULL
) return a
;
806 TRYNEXT(agent_h_local_med_power
);
809 agent_h_remote_med_power(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
810 size_t *var_len
, WriteMethod
**write_method
)
812 struct lldpd_port
*port
;
815 if ((port
= header_tprindexed_table(vp
, name
, length
, exact
, var_len
,
816 write_method
, 1)) == NULL
)
819 if ((a
= agent_v_med_power(vp
, var_len
, &port
->p_med_power
)) != NULL
) return a
;
820 TRYNEXT(agent_h_remote_med_power
);
824 agent_v_med(struct variable
*vp
, size_t *var_len
, struct lldpd_chassis
*chassis
,
825 struct lldpd_port
*port
)
827 static unsigned long long_ret
;
831 case LLDP_SNMP_MED_CLASS
:
832 long_ret
= chassis
->c_med_type
;
833 return (u_char
*)&long_ret
;
834 case LLDP_SNMP_MED_CAP_AVAILABLE
:
836 bit
= swap_bits(chassis
->c_med_cap_available
);
837 return (u_char
*)&bit
;
838 case LLDP_SNMP_MED_CAP_ENABLED
:
841 bit
= swap_bits(port
->p_med_cap_enabled
);
842 return (u_char
*)&bit
;
844 # define LLDP_H_MED(magic, variable) \
846 if (chassis->variable) { \
847 *var_len = strlen(chassis->variable); \
848 return (u_char *)chassis->variable; \
852 LLDP_H_MED(LLDP_SNMP_MED_HW
, c_med_hw
);
853 LLDP_H_MED(LLDP_SNMP_MED_SW
, c_med_sw
);
854 LLDP_H_MED(LLDP_SNMP_MED_FW
, c_med_fw
);
855 LLDP_H_MED(LLDP_SNMP_MED_SN
, c_med_sn
);
856 LLDP_H_MED(LLDP_SNMP_MED_MANUF
, c_med_manuf
);
857 LLDP_H_MED(LLDP_SNMP_MED_MODEL
, c_med_model
);
858 LLDP_H_MED(LLDP_SNMP_MED_ASSET
, c_med_asset
);
863 agent_h_local_med(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
864 size_t *var_len
, WriteMethod
**write_method
)
868 if (!LOCAL_CHASSIS(scfg
)->c_med_cap_available
) return NULL
;
869 if (header_generic(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
871 if ((a
= agent_v_med(vp
, var_len
, LOCAL_CHASSIS(scfg
), NULL
)) != NULL
) return a
;
872 TRYNEXT(agent_h_local_med
);
876 agent_h_remote_med(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
877 size_t *var_len
, WriteMethod
**write_method
)
879 struct lldpd_port
*port
;
882 if ((port
= header_tprindexed_table(vp
, name
, length
, exact
, var_len
,
883 write_method
, 1)) == NULL
)
886 if ((a
= agent_v_med(vp
, var_len
, port
->p_chassis
, port
)) != NULL
) return a
;
887 TRYNEXT(agent_h_remote_med
);
891 agent_v_med_policy(struct variable
*vp
, size_t *var_len
,
892 struct lldpd_med_policy
*policy
)
894 static unsigned long long_ret
;
897 case LLDP_SNMP_MED_POLICY_VID
:
898 long_ret
= policy
->vid
;
899 return (u_char
*)&long_ret
;
900 case LLDP_SNMP_MED_POLICY_PRIO
:
901 long_ret
= policy
->priority
;
902 return (u_char
*)&long_ret
;
903 case LLDP_SNMP_MED_POLICY_DSCP
:
904 long_ret
= policy
->dscp
;
905 return (u_char
*)&long_ret
;
906 case LLDP_SNMP_MED_POLICY_UNKNOWN
:
907 long_ret
= policy
->unknown
? 1 : 2;
908 return (u_char
*)&long_ret
;
909 case LLDP_SNMP_MED_POLICY_TAGGED
:
910 long_ret
= policy
->tagged
? 1 : 2;
911 return (u_char
*)&long_ret
;
917 agent_h_remote_med_policy(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
918 size_t *var_len
, WriteMethod
**write_method
)
920 struct lldpd_med_policy
*policy
;
922 if ((policy
= (struct lldpd_med_policy
*)header_tprmedindexed_table(vp
, name
,
923 length
, exact
, var_len
, write_method
, TPR_VARIANT_MED_POLICY
)) == NULL
)
926 return agent_v_med_policy(vp
, var_len
, policy
);
929 agent_h_local_med_policy(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
930 size_t *var_len
, WriteMethod
**write_method
)
932 struct lldpd_med_policy
*policy
;
934 if ((policy
= (struct lldpd_med_policy
*)header_pmedindexed_policy_table(vp
,
935 name
, length
, exact
, var_len
, write_method
)) == NULL
)
938 return agent_v_med_policy(vp
, var_len
, policy
);
942 agent_v_med_location(struct variable
*vp
, size_t *var_len
,
943 struct lldpd_med_loc
*location
)
946 case LLDP_SNMP_MED_LOCATION
:
947 *var_len
= location
->data_len
;
948 return (u_char
*)location
->data
;
954 agent_h_remote_med_location(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
955 size_t *var_len
, WriteMethod
**write_method
)
957 struct lldpd_med_loc
*location
;
959 if ((location
= (struct lldpd_med_loc
*)header_tprmedindexed_table(vp
, name
,
960 length
, exact
, var_len
, write_method
, TPR_VARIANT_MED_LOCATION
)) ==
964 return agent_v_med_location(vp
, var_len
, location
);
967 agent_h_local_med_location(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
968 size_t *var_len
, WriteMethod
**write_method
)
970 struct lldpd_med_loc
*location
;
972 if ((location
= (struct lldpd_med_loc
*)header_pmedindexed_location_table(vp
,
973 name
, length
, exact
, var_len
, write_method
)) == NULL
)
976 return agent_v_med_location(vp
, var_len
, location
);
981 agent_v_chassis(struct variable
*vp
, size_t *var_len
, struct lldpd_chassis
*chassis
)
984 static unsigned long long_ret
;
987 case LLDP_SNMP_CIDSUBTYPE
:
988 long_ret
= chassis
->c_id_subtype
;
989 return (u_char
*)&long_ret
;
991 *var_len
= chassis
->c_id_len
;
992 return (u_char
*)chassis
->c_id
;
993 case LLDP_SNMP_SYSNAME
:
994 if (!chassis
->c_name
|| *chassis
->c_name
== '\0') break;
995 *var_len
= strlen(chassis
->c_name
);
996 return (u_char
*)chassis
->c_name
;
997 case LLDP_SNMP_SYSDESCR
:
998 if (!chassis
->c_descr
|| *chassis
->c_descr
== '\0') break;
999 *var_len
= strlen(chassis
->c_descr
);
1000 return (u_char
*)chassis
->c_descr
;
1001 case LLDP_SNMP_SYSCAP_SUP
:
1003 bit
= swap_bits(chassis
->c_cap_available
);
1004 return (u_char
*)&bit
;
1005 case LLDP_SNMP_SYSCAP_ENA
:
1007 bit
= swap_bits(chassis
->c_cap_enabled
);
1008 return (u_char
*)&bit
;
1015 agent_h_local_chassis(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1016 size_t *var_len
, WriteMethod
**write_method
)
1020 if (header_generic(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
1022 if ((a
= agent_v_chassis(vp
, var_len
, LOCAL_CHASSIS(scfg
))) != NULL
) return a
;
1023 TRYNEXT(agent_h_local_chassis
);
1026 agent_h_remote_chassis(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1027 size_t *var_len
, WriteMethod
**write_method
)
1029 struct lldpd_port
*port
;
1032 if ((port
= header_tprindexed_table(vp
, name
, length
, exact
, var_len
,
1033 write_method
, 0)) == NULL
)
1036 if ((a
= agent_v_chassis(vp
, var_len
, port
->p_chassis
)) != NULL
) return a
;
1037 TRYNEXT(agent_h_remote_chassis
);
1041 agent_h_stats(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1042 size_t *var_len
, WriteMethod
**write_method
)
1044 static unsigned long long_ret
;
1045 struct lldpd_hardware
*hardware
;
1047 if ((hardware
= header_portindexed_table(vp
, name
, length
, exact
, var_len
,
1048 write_method
)) == NULL
)
1051 switch (vp
->magic
) {
1052 case LLDP_SNMP_STATS_TX
:
1053 long_ret
= hardware
->h_tx_cnt
;
1054 return (u_char
*)&long_ret
;
1055 case LLDP_SNMP_STATS_RX
:
1056 long_ret
= hardware
->h_rx_cnt
;
1057 return (u_char
*)&long_ret
;
1058 case LLDP_SNMP_STATS_RX_DISCARDED
:
1059 case LLDP_SNMP_STATS_RX_ERRORS
:
1060 /* We discard only frame with errors. Therefore, the two values
1062 long_ret
= hardware
->h_rx_discarded_cnt
;
1063 return (u_char
*)&long_ret
;
1064 case LLDP_SNMP_STATS_RX_TLVDISCARDED
:
1065 case LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED
:
1066 /* We discard only unrecognized TLV. Malformed TLV
1067 implies dropping the whole frame */
1068 long_ret
= hardware
->h_rx_unrecognized_cnt
;
1069 return (u_char
*)&long_ret
;
1070 case LLDP_SNMP_STATS_RX_AGEOUTS
:
1071 long_ret
= hardware
->h_ageout_cnt
;
1072 return (u_char
*)&long_ret
;
1080 agent_v_vlan(struct variable
*vp
, size_t *var_len
, struct lldpd_vlan
*vlan
)
1082 switch (vp
->magic
) {
1083 case LLDP_SNMP_DOT1_VLANNAME
:
1084 *var_len
= strlen(vlan
->v_name
);
1085 return (u_char
*)vlan
->v_name
;
1091 agent_h_local_vlan(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1092 size_t *var_len
, WriteMethod
**write_method
)
1094 struct lldpd_vlan
*vlan
;
1096 if ((vlan
= header_pvindexed_table(vp
, name
, length
, exact
, var_len
,
1097 write_method
)) == NULL
)
1100 return agent_v_vlan(vp
, var_len
, vlan
);
1103 agent_h_remote_vlan(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1104 size_t *var_len
, WriteMethod
**write_method
)
1106 struct lldpd_vlan
*vlan
;
1108 if ((vlan
= header_tprvindexed_table(vp
, name
, length
, exact
, var_len
,
1109 write_method
)) == NULL
)
1112 return agent_v_vlan(vp
, var_len
, vlan
);
1116 agent_v_ppvid(struct variable
*vp
, size_t *var_len
, struct lldpd_ppvid
*ppvid
)
1118 static unsigned long long_ret
;
1120 switch (vp
->magic
) {
1121 case LLDP_SNMP_DOT1_PPVLAN_SUPPORTED
:
1122 long_ret
= (ppvid
->p_cap_status
& LLDP_PPVID_CAP_SUPPORTED
) ? 1 : 2;
1123 return (u_char
*)&long_ret
;
1124 case LLDP_SNMP_DOT1_PPVLAN_ENABLED
:
1125 long_ret
= (ppvid
->p_cap_status
& LLDP_PPVID_CAP_ENABLED
) ? 1 : 2;
1126 return (u_char
*)&long_ret
;
1132 agent_h_local_ppvid(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1133 size_t *var_len
, WriteMethod
**write_method
)
1135 struct lldpd_ppvid
*ppvid
;
1137 if ((ppvid
= header_pppvidindexed_table(vp
, name
, length
, exact
, var_len
,
1138 write_method
)) == NULL
)
1141 return agent_v_ppvid(vp
, var_len
, ppvid
);
1145 agent_h_remote_ppvid(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1146 size_t *var_len
, WriteMethod
**write_method
)
1148 struct lldpd_ppvid
*ppvid
;
1150 if ((ppvid
= header_tprppvidindexed_table(vp
, name
, length
, exact
, var_len
,
1151 write_method
)) == NULL
)
1154 return agent_v_ppvid(vp
, var_len
, ppvid
);
1158 agent_v_pi(struct variable
*vp
, size_t *var_len
, struct lldpd_pi
*pi
)
1160 switch (vp
->magic
) {
1161 case LLDP_SNMP_DOT1_PI
:
1162 *var_len
= pi
->p_pi_len
;
1163 return (u_char
*)pi
->p_pi
;
1169 agent_h_local_pi(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1170 size_t *var_len
, WriteMethod
**write_method
)
1172 struct lldpd_pi
*pi
;
1174 if ((pi
= header_ppiindexed_table(vp
, name
, length
, exact
, var_len
,
1175 write_method
)) == NULL
)
1178 return agent_v_pi(vp
, var_len
, pi
);
1181 agent_h_remote_pi(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1182 size_t *var_len
, WriteMethod
**write_method
)
1184 struct lldpd_pi
*pi
;
1186 if ((pi
= header_tprpiindexed_table(vp
, name
, length
, exact
, var_len
,
1187 write_method
)) == NULL
)
1190 return agent_v_pi(vp
, var_len
, pi
);
1195 agent_v_port(struct variable
*vp
, size_t *var_len
, struct lldpd_port
*port
)
1198 static uint16_t short_ret
;
1201 static unsigned long long_ret
;
1203 switch (vp
->magic
) {
1204 case LLDP_SNMP_PIDSUBTYPE
:
1205 long_ret
= port
->p_id_subtype
;
1206 return (u_char
*)&long_ret
;
1208 *var_len
= port
->p_id_len
;
1209 return (u_char
*)port
->p_id
;
1210 case LLDP_SNMP_PORTDESC
:
1211 if (!port
->p_descr
|| *port
->p_descr
== '\0') break;
1212 *var_len
= strlen(port
->p_descr
);
1213 return (u_char
*)port
->p_descr
;
1215 case LLDP_SNMP_DOT3_AUTONEG_SUPPORT
:
1216 long_ret
= 2 - port
->p_macphy
.autoneg_support
;
1217 return (u_char
*)&long_ret
;
1218 case LLDP_SNMP_DOT3_AUTONEG_ENABLED
:
1219 long_ret
= 2 - port
->p_macphy
.autoneg_enabled
;
1220 return (u_char
*)&long_ret
;
1221 case LLDP_SNMP_DOT3_AUTONEG_ADVERTISED
:
1223 short_ret
= htons(port
->p_macphy
.autoneg_advertised
);
1224 return (u_char
*)&short_ret
;
1225 case LLDP_SNMP_DOT3_AUTONEG_MAU
:
1226 long_ret
= port
->p_macphy
.mau_type
;
1227 return (u_char
*)&long_ret
;
1228 case LLDP_SNMP_DOT3_AGG_STATUS
:
1229 bit
= swap_bits((port
->p_aggregid
> 0) ? 3 : 0);
1231 return (u_char
*)&bit
;
1232 case LLDP_SNMP_DOT3_AGG_ID
:
1233 long_ret
= port
->p_aggregid
;
1234 return (u_char
*)&long_ret
;
1235 case LLDP_SNMP_DOT3_MFS
:
1237 long_ret
= port
->p_mfs
;
1238 return (u_char
*)&long_ret
;
1241 case LLDP_SNMP_DOT3_POWER_DEVICETYPE
:
1242 if (port
->p_power
.devicetype
) {
1244 (port
->p_power
.devicetype
== LLDP_DOT3_POWER_PSE
) ? 1 : 2;
1245 return (u_char
*)&long_ret
;
1248 case LLDP_SNMP_DOT3_POWER_SUPPORT
:
1249 if (port
->p_power
.devicetype
) {
1250 long_ret
= (port
->p_power
.supported
) ? 1 : 2;
1251 return (u_char
*)&long_ret
;
1254 case LLDP_SNMP_DOT3_POWER_ENABLED
:
1255 if (port
->p_power
.devicetype
) {
1256 long_ret
= (port
->p_power
.enabled
) ? 1 : 2;
1257 return (u_char
*)&long_ret
;
1260 case LLDP_SNMP_DOT3_POWER_PAIRCONTROL
:
1261 if (port
->p_power
.devicetype
) {
1262 long_ret
= (port
->p_power
.paircontrol
) ? 1 : 2;
1263 return (u_char
*)&long_ret
;
1266 case LLDP_SNMP_DOT3_POWER_PAIRS
:
1267 if (port
->p_power
.devicetype
) {
1268 long_ret
= port
->p_power
.pairs
;
1269 return (u_char
*)&long_ret
;
1272 case LLDP_SNMP_DOT3_POWER_CLASS
:
1273 if (port
->p_power
.devicetype
&& port
->p_power
.class) {
1274 long_ret
= port
->p_power
.class;
1275 return (u_char
*)&long_ret
;
1278 case LLDP_SNMP_DOT3_POWER_TYPE
:
1279 if (port
->p_power
.devicetype
&&
1280 port
->p_power
.powertype
!= LLDP_DOT3_POWER_8023AT_OFF
) {
1282 bit
= (((port
->p_power
.powertype
==
1283 LLDP_DOT3_POWER_8023AT_TYPE1
) ?
1287 (((port
->p_power
.devicetype
== LLDP_DOT3_POWER_PSE
) ? 0 : 1)
1289 return (u_char
*)&bit
;
1292 case LLDP_SNMP_DOT3_POWER_SOURCE
:
1293 if (port
->p_power
.devicetype
&&
1294 port
->p_power
.powertype
!= LLDP_DOT3_POWER_8023AT_OFF
) {
1296 bit
= swap_bits(port
->p_power
.source
% (1 << 2));
1297 return (u_char
*)&bit
;
1300 case LLDP_SNMP_DOT3_POWER_PRIORITY
:
1301 if (port
->p_power
.devicetype
&&
1302 port
->p_power
.powertype
!= LLDP_DOT3_POWER_8023AT_OFF
) {
1303 /* See 30.12.2.1.16. This seems defined in reverse order... */
1304 long_ret
= 4 - port
->p_power
.priority
;
1305 return (u_char
*)&long_ret
;
1308 case LLDP_SNMP_DOT3_POWER_REQUESTED
:
1309 if (port
->p_power
.devicetype
&&
1310 port
->p_power
.powertype
!= LLDP_DOT3_POWER_8023AT_OFF
) {
1311 long_ret
= port
->p_power
.requested
;
1312 return (u_char
*)&long_ret
;
1315 case LLDP_SNMP_DOT3_POWER_ALLOCATED
:
1316 if (port
->p_power
.devicetype
&&
1317 port
->p_power
.powertype
!= LLDP_DOT3_POWER_8023AT_OFF
) {
1318 long_ret
= port
->p_power
.allocated
;
1319 return (u_char
*)&long_ret
;
1324 case LLDP_SNMP_DOT1_PVID
:
1325 long_ret
= port
->p_pvid
;
1326 return (u_char
*)&long_ret
;
1334 agent_h_remote_port(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1335 size_t *var_len
, WriteMethod
**write_method
)
1337 struct lldpd_port
*port
;
1340 if ((port
= header_tprindexed_table(vp
, name
, length
, exact
, var_len
,
1341 write_method
, 0)) == NULL
)
1344 if ((a
= agent_v_port(vp
, var_len
, port
)) != NULL
) return a
;
1345 TRYNEXT(agent_h_remote_port
);
1348 agent_h_local_port(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1349 size_t *var_len
, WriteMethod
**write_method
)
1351 struct lldpd_hardware
*hardware
;
1354 if ((hardware
= header_portindexed_table(vp
, name
, length
, exact
, var_len
,
1355 write_method
)) == NULL
)
1358 if ((a
= agent_v_port(vp
, var_len
, &hardware
->h_lport
)) != NULL
) return a
;
1359 TRYNEXT(agent_h_local_port
);
1363 agent_v_management(struct variable
*vp
, size_t *var_len
, struct lldpd_mgmt
*mgmt
)
1365 static unsigned long int long_ret
;
1366 static oid zeroDotZero
[2] = { 0, 0 };
1368 switch (vp
->magic
) {
1369 case LLDP_SNMP_ADDR_LEN
:
1370 long_ret
= mgmt
->m_addrsize
+ 1;
1371 return (u_char
*)&long_ret
;
1372 case LLDP_SNMP_ADDR_IFSUBTYPE
:
1373 if (mgmt
->m_iface
!= 0)
1374 long_ret
= LLDP_MGMT_IFACE_IFINDEX
;
1377 return (u_char
*)&long_ret
;
1378 case LLDP_SNMP_ADDR_IFID
:
1379 long_ret
= mgmt
->m_iface
;
1380 return (u_char
*)&long_ret
;
1381 case LLDP_SNMP_ADDR_OID
:
1382 *var_len
= sizeof(zeroDotZero
);
1383 return (u_char
*)zeroDotZero
;
1389 agent_h_local_management(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1390 size_t *var_len
, WriteMethod
**write_method
)
1393 struct lldpd_mgmt
*mgmt
;
1395 if ((mgmt
= header_ipindexed_table(vp
, name
, length
, exact
, var_len
,
1396 write_method
)) == NULL
)
1399 return agent_v_management(vp
, var_len
, mgmt
);
1402 agent_h_remote_management(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1403 size_t *var_len
, WriteMethod
**write_method
)
1405 struct lldpd_mgmt
*mgmt
;
1407 if ((mgmt
= header_tpripindexed_table(vp
, name
, length
, exact
, var_len
,
1408 write_method
)) == NULL
)
1411 return agent_v_management(vp
, var_len
, mgmt
);
1414 #ifdef ENABLE_CUSTOM
1416 agent_v_custom(struct variable
*vp
, size_t *var_len
, struct lldpd_custom
*custom
)
1418 switch (vp
->magic
) {
1419 case LLDP_SNMP_ORG_DEF_INFO
:
1420 *var_len
= custom
->oui_info_len
;
1421 return (u_char
*)custom
->oui_info
;
1427 agent_h_remote_custom(struct variable
*vp
, oid
*name
, size_t *length
, int exact
,
1428 size_t *var_len
, WriteMethod
**write_method
)
1430 struct lldpd_custom
*custom
;
1432 if ((custom
= header_tprcustomindexed_table(vp
, name
, length
, exact
, var_len
,
1433 write_method
)) == NULL
)
1436 return agent_v_custom(vp
, var_len
, custom
);
1441 Here is how it works: a agent_h_*() function will handle incoming
1442 requests. It will use an appropriate header_*indexed_table()
1443 function to grab the appropriate structure that was queried (a port,
1444 a chassis, ...). It will then delegate to a agent_v_*() function the
1445 responsability to extract the appropriate answer.
1447 agent_h_*() functions and header_*indexed_table() are not shared
1448 between remote and not remote version while agent_v_*() functions
1449 are the same for both version.
1452 /* For testing purposes, keep this structure ordered by increasing OID! */
1453 struct variable8 agent_lldp_vars
[] = {
1455 { LLDP_SNMP_TXINTERVAL
, ASN_INTEGER
, RONLY
, agent_h_scalars
, 3, { 1, 1, 1 } },
1456 { LLDP_SNMP_TXMULTIPLIER
, ASN_INTEGER
, RONLY
, agent_h_scalars
, 3, { 1, 1, 2 } },
1457 { LLDP_SNMP_REINITDELAY
, ASN_INTEGER
, RONLY
, agent_h_scalars
, 3, { 1, 1, 3 } },
1458 { LLDP_SNMP_TXDELAY
, ASN_INTEGER
, RONLY
, agent_h_scalars
, 3, { 1, 1, 4 } },
1459 { LLDP_SNMP_NOTIFICATION
, ASN_INTEGER
, RONLY
, agent_h_scalars
, 3, { 1, 1, 5 } },
1460 { LLDP_SNMP_LASTUPDATE
, ASN_TIMETICKS
, RONLY
, agent_h_scalars
, 3, { 1, 2, 1 } },
1461 { LLDP_SNMP_STATS_INSERTS
, ASN_GAUGE
, RONLY
, agent_h_scalars
, 3, { 1, 2, 2 } },
1462 { LLDP_SNMP_STATS_DELETES
, ASN_GAUGE
, RONLY
, agent_h_scalars
, 3, { 1, 2, 3 } },
1463 { LLDP_SNMP_STATS_DROPS
, ASN_GAUGE
, RONLY
, agent_h_scalars
, 3, { 1, 2, 4 } },
1464 { LLDP_SNMP_STATS_AGEOUTS
, ASN_GAUGE
, RONLY
, agent_h_scalars
, 3, { 1, 2, 5 } },
1466 { LLDP_SNMP_STATS_TX
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5, { 1, 2, 6, 1, 2 } },
1467 { LLDP_SNMP_STATS_RX_DISCARDED
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5,
1468 { 1, 2, 7, 1, 2 } },
1469 { LLDP_SNMP_STATS_RX_ERRORS
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5,
1470 { 1, 2, 7, 1, 3 } },
1471 { LLDP_SNMP_STATS_RX
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5, { 1, 2, 7, 1, 4 } },
1472 { LLDP_SNMP_STATS_RX_TLVDISCARDED
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5,
1473 { 1, 2, 7, 1, 5 } },
1474 { LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5,
1475 { 1, 2, 7, 1, 6 } },
1476 { LLDP_SNMP_STATS_RX_AGEOUTS
, ASN_GAUGE
, RONLY
, agent_h_stats
, 5,
1477 { 1, 2, 7, 1, 7 } },
1479 { LLDP_SNMP_CIDSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_local_chassis
, 3,
1481 { LLDP_SNMP_CID
, ASN_OCTET_STR
, RONLY
, agent_h_local_chassis
, 3, { 1, 3, 2 } },
1482 { LLDP_SNMP_SYSNAME
, ASN_OCTET_STR
, RONLY
, agent_h_local_chassis
, 3,
1484 { LLDP_SNMP_SYSDESCR
, ASN_OCTET_STR
, RONLY
, agent_h_local_chassis
, 3,
1486 { LLDP_SNMP_SYSCAP_SUP
, ASN_OCTET_STR
, RONLY
, agent_h_local_chassis
, 3,
1488 { LLDP_SNMP_SYSCAP_ENA
, ASN_OCTET_STR
, RONLY
, agent_h_local_chassis
, 3,
1491 { LLDP_SNMP_PIDSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 5,
1492 { 1, 3, 7, 1, 2 } },
1493 { LLDP_SNMP_PID
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 5,
1494 { 1, 3, 7, 1, 3 } },
1495 { LLDP_SNMP_PORTDESC
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 5,
1496 { 1, 3, 7, 1, 4 } },
1497 /* Local management address */
1498 { LLDP_SNMP_ADDR_LEN
, ASN_INTEGER
, RONLY
, agent_h_local_management
, 5,
1499 { 1, 3, 8, 1, 3 } },
1500 { LLDP_SNMP_ADDR_IFSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_local_management
, 5,
1501 { 1, 3, 8, 1, 4 } },
1502 { LLDP_SNMP_ADDR_IFID
, ASN_INTEGER
, RONLY
, agent_h_local_management
, 5,
1503 { 1, 3, 8, 1, 5 } },
1504 { LLDP_SNMP_ADDR_OID
, ASN_OBJECT_ID
, RONLY
, agent_h_local_management
, 5,
1505 { 1, 3, 8, 1, 6 } },
1507 { LLDP_SNMP_CIDSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_remote_chassis
, 5,
1508 { 1, 4, 1, 1, 4 } },
1509 { LLDP_SNMP_CID
, ASN_OCTET_STR
, RONLY
, agent_h_remote_chassis
, 5,
1510 { 1, 4, 1, 1, 5 } },
1511 { LLDP_SNMP_PIDSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 5,
1512 { 1, 4, 1, 1, 6 } },
1513 { LLDP_SNMP_PID
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 5,
1514 { 1, 4, 1, 1, 7 } },
1515 { LLDP_SNMP_PORTDESC
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 5,
1516 { 1, 4, 1, 1, 8 } },
1517 { LLDP_SNMP_SYSNAME
, ASN_OCTET_STR
, RONLY
, agent_h_remote_chassis
, 5,
1518 { 1, 4, 1, 1, 9 } },
1519 { LLDP_SNMP_SYSDESCR
, ASN_OCTET_STR
, RONLY
, agent_h_remote_chassis
, 5,
1520 { 1, 4, 1, 1, 10 } },
1521 { LLDP_SNMP_SYSCAP_SUP
, ASN_OCTET_STR
, RONLY
, agent_h_remote_chassis
, 5,
1522 { 1, 4, 1, 1, 11 } },
1523 { LLDP_SNMP_SYSCAP_ENA
, ASN_OCTET_STR
, RONLY
, agent_h_remote_chassis
, 5,
1524 { 1, 4, 1, 1, 12 } },
1525 /* Remote management address */
1526 { LLDP_SNMP_ADDR_IFSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_remote_management
, 5,
1527 { 1, 4, 2, 1, 3 } },
1528 { LLDP_SNMP_ADDR_IFID
, ASN_INTEGER
, RONLY
, agent_h_remote_management
, 5,
1529 { 1, 4, 2, 1, 4 } },
1530 { LLDP_SNMP_ADDR_OID
, ASN_OBJECT_ID
, RONLY
, agent_h_remote_management
, 5,
1531 { 1, 4, 2, 1, 5 } },
1532 #ifdef ENABLE_CUSTOM
1534 { LLDP_SNMP_ORG_DEF_INFO
, ASN_OCTET_STR
, RONLY
, agent_h_remote_custom
, 5,
1535 { 1, 4, 4, 1, 4 } },
1538 /* Dot3, local ports */
1539 { LLDP_SNMP_DOT3_AUTONEG_SUPPORT
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1540 { 1, 5, 4623, 1, 2, 1, 1, 1 } },
1541 { LLDP_SNMP_DOT3_AUTONEG_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1542 { 1, 5, 4623, 1, 2, 1, 1, 2 } },
1543 { LLDP_SNMP_DOT3_AUTONEG_ADVERTISED
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
,
1544 8, { 1, 5, 4623, 1, 2, 1, 1, 3 } },
1545 { LLDP_SNMP_DOT3_AUTONEG_MAU
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1546 { 1, 5, 4623, 1, 2, 1, 1, 4 } },
1547 { LLDP_SNMP_DOT3_POWER_DEVICETYPE
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1548 { 1, 5, 4623, 1, 2, 2, 1, 1 } },
1549 { LLDP_SNMP_DOT3_POWER_SUPPORT
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1550 { 1, 5, 4623, 1, 2, 2, 1, 2 } },
1551 { LLDP_SNMP_DOT3_POWER_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1552 { 1, 5, 4623, 1, 2, 2, 1, 3 } },
1553 { LLDP_SNMP_DOT3_POWER_PAIRCONTROL
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1554 { 1, 5, 4623, 1, 2, 2, 1, 4 } },
1555 { LLDP_SNMP_DOT3_POWER_PAIRS
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1556 { 1, 5, 4623, 1, 2, 2, 1, 5 } },
1557 { LLDP_SNMP_DOT3_POWER_CLASS
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1558 { 1, 5, 4623, 1, 2, 2, 1, 6 } },
1559 { LLDP_SNMP_DOT3_POWER_TYPE
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 8,
1560 { 1, 5, 4623, 1, 2, 2, 1, 7 } },
1561 { LLDP_SNMP_DOT3_POWER_SOURCE
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 8,
1562 { 1, 5, 4623, 1, 2, 2, 1, 8 } },
1563 { LLDP_SNMP_DOT3_POWER_PRIORITY
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1564 { 1, 5, 4623, 1, 2, 2, 1, 9 } },
1565 { LLDP_SNMP_DOT3_POWER_REQUESTED
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1566 { 1, 5, 4623, 1, 2, 2, 1, 10 } },
1567 { LLDP_SNMP_DOT3_POWER_ALLOCATED
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1568 { 1, 5, 4623, 1, 2, 2, 1, 11 } },
1569 { LLDP_SNMP_DOT3_AGG_STATUS
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 8,
1570 { 1, 5, 4623, 1, 2, 3, 1, 1 } },
1571 { LLDP_SNMP_DOT3_AGG_ID
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1572 { 1, 5, 4623, 1, 2, 3, 1, 2 } },
1573 { LLDP_SNMP_DOT3_MFS
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1574 { 1, 5, 4623, 1, 2, 4, 1, 1 } },
1576 /* Dot3, remote ports */
1578 { LLDP_SNMP_DOT3_AUTONEG_SUPPORT
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1579 { 1, 5, 4623, 1, 3, 1, 1, 1 } },
1580 { LLDP_SNMP_DOT3_AUTONEG_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1581 { 1, 5, 4623, 1, 3, 1, 1, 2 } },
1582 { LLDP_SNMP_DOT3_AUTONEG_ADVERTISED
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
,
1583 8, { 1, 5, 4623, 1, 3, 1, 1, 3 } },
1584 { LLDP_SNMP_DOT3_AUTONEG_MAU
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1585 { 1, 5, 4623, 1, 3, 1, 1, 4 } },
1586 { LLDP_SNMP_DOT3_POWER_DEVICETYPE
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1587 { 1, 5, 4623, 1, 3, 2, 1, 1 } },
1588 { LLDP_SNMP_DOT3_POWER_SUPPORT
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1589 { 1, 5, 4623, 1, 3, 2, 1, 2 } },
1590 { LLDP_SNMP_DOT3_POWER_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1591 { 1, 5, 4623, 1, 3, 2, 1, 3 } },
1592 { LLDP_SNMP_DOT3_POWER_PAIRCONTROL
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1593 { 1, 5, 4623, 1, 3, 2, 1, 4 } },
1594 { LLDP_SNMP_DOT3_POWER_PAIRS
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1595 { 1, 5, 4623, 1, 3, 2, 1, 5 } },
1596 { LLDP_SNMP_DOT3_POWER_CLASS
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1597 { 1, 5, 4623, 1, 3, 2, 1, 6 } },
1598 { LLDP_SNMP_DOT3_POWER_TYPE
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 8,
1599 { 1, 5, 4623, 1, 3, 2, 1, 7 } },
1600 { LLDP_SNMP_DOT3_POWER_SOURCE
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 8,
1601 { 1, 5, 4623, 1, 3, 2, 1, 8 } },
1602 { LLDP_SNMP_DOT3_POWER_PRIORITY
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1603 { 1, 5, 4623, 1, 3, 2, 1, 9 } },
1604 { LLDP_SNMP_DOT3_POWER_REQUESTED
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1605 { 1, 5, 4623, 1, 3, 2, 1, 10 } },
1606 { LLDP_SNMP_DOT3_POWER_ALLOCATED
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1607 { 1, 5, 4623, 1, 3, 2, 1, 11 } },
1608 { LLDP_SNMP_DOT3_AGG_STATUS
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 8,
1609 { 1, 5, 4623, 1, 3, 3, 1, 1 } },
1610 { LLDP_SNMP_DOT3_AGG_ID
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1611 { 1, 5, 4623, 1, 3, 3, 1, 2 } },
1612 { LLDP_SNMP_DOT3_MFS
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1613 { 1, 5, 4623, 1, 3, 4, 1, 1 } },
1615 #ifdef ENABLE_LLDPMED
1616 /* LLDP-MED local */
1617 { LLDP_SNMP_MED_CLASS
, ASN_INTEGER
, RONLY
, agent_h_local_med
, 6,
1618 { 1, 5, 4795, 1, 1, 1 } },
1619 { LLDP_SNMP_MED_POLICY_VID
, ASN_INTEGER
, RONLY
, agent_h_local_med_policy
, 8,
1620 { 1, 5, 4795, 1, 2, 1, 1, 2 } },
1621 { LLDP_SNMP_MED_POLICY_PRIO
, ASN_INTEGER
, RONLY
, agent_h_local_med_policy
, 8,
1622 { 1, 5, 4795, 1, 2, 1, 1, 3 } },
1623 { LLDP_SNMP_MED_POLICY_DSCP
, ASN_INTEGER
, RONLY
, agent_h_local_med_policy
, 8,
1624 { 1, 5, 4795, 1, 2, 1, 1, 4 } },
1625 { LLDP_SNMP_MED_POLICY_UNKNOWN
, ASN_INTEGER
, RONLY
, agent_h_local_med_policy
, 8,
1626 { 1, 5, 4795, 1, 2, 1, 1, 5 } },
1627 { LLDP_SNMP_MED_POLICY_TAGGED
, ASN_INTEGER
, RONLY
, agent_h_local_med_policy
, 8,
1628 { 1, 5, 4795, 1, 2, 1, 1, 6 } },
1629 { LLDP_SNMP_MED_HW
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1630 { 1, 5, 4795, 1, 2, 2 } },
1631 { LLDP_SNMP_MED_FW
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1632 { 1, 5, 4795, 1, 2, 3 } },
1633 { LLDP_SNMP_MED_SW
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1634 { 1, 5, 4795, 1, 2, 4 } },
1635 { LLDP_SNMP_MED_SN
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1636 { 1, 5, 4795, 1, 2, 5 } },
1637 { LLDP_SNMP_MED_MANUF
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1638 { 1, 5, 4795, 1, 2, 6 } },
1639 { LLDP_SNMP_MED_MODEL
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1640 { 1, 5, 4795, 1, 2, 7 } },
1641 { LLDP_SNMP_MED_ASSET
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1642 { 1, 5, 4795, 1, 2, 8 } },
1643 { LLDP_SNMP_MED_LOCATION
, ASN_OCTET_STR
, RONLY
, agent_h_local_med_location
, 8,
1644 { 1, 5, 4795, 1, 2, 9, 1, 2 } },
1645 { LLDP_SNMP_MED_POE_DEVICETYPE
, ASN_INTEGER
, RONLY
, agent_h_local_med_power
, 6,
1646 { 1, 5, 4795, 1, 2, 10 } },
1647 { LLDP_SNMP_MED_POE_PSE_POWERVAL
, ASN_GAUGE
, RONLY
, agent_h_local_med_power
, 8,
1648 { 1, 5, 4795, 1, 2, 11, 1, 1 } },
1649 { LLDP_SNMP_MED_POE_PSE_POWERPRIORITY
, ASN_INTEGER
, RONLY
,
1650 agent_h_local_med_power
, 8, { 1, 5, 4795, 1, 2, 11, 1, 2 } },
1651 { LLDP_SNMP_MED_POE_PSE_POWERSOURCE
, ASN_INTEGER
, RONLY
,
1652 agent_h_local_med_power
, 6, { 1, 5, 4795, 1, 2, 12 } },
1653 { LLDP_SNMP_MED_POE_PD_POWERVAL
, ASN_GAUGE
, RONLY
, agent_h_local_med_power
, 6,
1654 { 1, 5, 4795, 1, 2, 13 } },
1655 { LLDP_SNMP_MED_POE_PD_POWERSOURCE
, ASN_INTEGER
, RONLY
, agent_h_local_med_power
,
1656 6, { 1, 5, 4795, 1, 2, 14 } },
1657 { LLDP_SNMP_MED_POE_PD_POWERPRIORITY
, ASN_INTEGER
, RONLY
,
1658 agent_h_local_med_power
, 6, { 1, 5, 4795, 1, 2, 15 } },
1659 /* LLDP-MED remote */
1660 { LLDP_SNMP_MED_CAP_AVAILABLE
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1661 { 1, 5, 4795, 1, 3, 1, 1, 1 } },
1662 { LLDP_SNMP_MED_CAP_ENABLED
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1663 { 1, 5, 4795, 1, 3, 1, 1, 2 } },
1664 { LLDP_SNMP_MED_CLASS
, ASN_INTEGER
, RONLY
, agent_h_remote_med
, 8,
1665 { 1, 5, 4795, 1, 3, 1, 1, 3 } },
1666 { LLDP_SNMP_MED_POLICY_VID
, ASN_INTEGER
, RONLY
, agent_h_remote_med_policy
, 8,
1667 { 1, 5, 4795, 1, 3, 2, 1, 2 } },
1668 { LLDP_SNMP_MED_POLICY_PRIO
, ASN_INTEGER
, RONLY
, agent_h_remote_med_policy
, 8,
1669 { 1, 5, 4795, 1, 3, 2, 1, 3 } },
1670 { LLDP_SNMP_MED_POLICY_DSCP
, ASN_INTEGER
, RONLY
, agent_h_remote_med_policy
, 8,
1671 { 1, 5, 4795, 1, 3, 2, 1, 4 } },
1672 { LLDP_SNMP_MED_POLICY_UNKNOWN
, ASN_INTEGER
, RONLY
, agent_h_remote_med_policy
,
1673 8, { 1, 5, 4795, 1, 3, 2, 1, 5 } },
1674 { LLDP_SNMP_MED_POLICY_TAGGED
, ASN_INTEGER
, RONLY
, agent_h_remote_med_policy
, 8,
1675 { 1, 5, 4795, 1, 3, 2, 1, 6 } },
1676 { LLDP_SNMP_MED_HW
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1677 { 1, 5, 4795, 1, 3, 3, 1, 1 } },
1678 { LLDP_SNMP_MED_FW
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1679 { 1, 5, 4795, 1, 3, 3, 1, 2 } },
1680 { LLDP_SNMP_MED_SW
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1681 { 1, 5, 4795, 1, 3, 3, 1, 3 } },
1682 { LLDP_SNMP_MED_SN
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1683 { 1, 5, 4795, 1, 3, 3, 1, 4 } },
1684 { LLDP_SNMP_MED_MANUF
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1685 { 1, 5, 4795, 1, 3, 3, 1, 5 } },
1686 { LLDP_SNMP_MED_MODEL
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1687 { 1, 5, 4795, 1, 3, 3, 1, 6 } },
1688 { LLDP_SNMP_MED_ASSET
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1689 { 1, 5, 4795, 1, 3, 3, 1, 7 } },
1690 { LLDP_SNMP_MED_LOCATION
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med_location
, 8,
1691 { 1, 5, 4795, 1, 3, 4, 1, 2 } },
1692 { LLDP_SNMP_MED_POE_DEVICETYPE
, ASN_INTEGER
, RONLY
, agent_h_remote_med_power
, 8,
1693 { 1, 5, 4795, 1, 3, 5, 1, 1 } },
1694 { LLDP_SNMP_MED_POE_PSE_POWERVAL
, ASN_GAUGE
, RONLY
, agent_h_remote_med_power
, 8,
1695 { 1, 5, 4795, 1, 3, 6, 1, 1 } },
1696 { LLDP_SNMP_MED_POE_PSE_POWERSOURCE
, ASN_INTEGER
, RONLY
,
1697 agent_h_remote_med_power
, 8, { 1, 5, 4795, 1, 3, 6, 1, 2 } },
1698 { LLDP_SNMP_MED_POE_PSE_POWERPRIORITY
, ASN_INTEGER
, RONLY
,
1699 agent_h_remote_med_power
, 8, { 1, 5, 4795, 1, 3, 6, 1, 3 } },
1700 { LLDP_SNMP_MED_POE_PD_POWERVAL
, ASN_GAUGE
, RONLY
, agent_h_remote_med_power
, 8,
1701 { 1, 5, 4795, 1, 3, 7, 1, 1 } },
1702 { LLDP_SNMP_MED_POE_PD_POWERSOURCE
, ASN_INTEGER
, RONLY
,
1703 agent_h_remote_med_power
, 8, { 1, 5, 4795, 1, 3, 7, 1, 2 } },
1704 { LLDP_SNMP_MED_POE_PD_POWERPRIORITY
, ASN_INTEGER
, RONLY
,
1705 agent_h_remote_med_power
, 8, { 1, 5, 4795, 1, 3, 7, 1, 3 } },
1707 /* Dot1, local and remote ports */
1709 { LLDP_SNMP_DOT1_PVID
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1710 { 1, 5, 32962, 1, 2, 1, 1, 1 } },
1711 { LLDP_SNMP_DOT1_PPVLAN_SUPPORTED
, ASN_INTEGER
, RONLY
, agent_h_local_ppvid
, 8,
1712 { 1, 5, 32962, 1, 2, 2, 1, 2 } },
1713 { LLDP_SNMP_DOT1_PPVLAN_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_local_ppvid
, 8,
1714 { 1, 5, 32962, 1, 2, 2, 1, 3 } },
1715 { LLDP_SNMP_DOT1_VLANNAME
, ASN_OCTET_STR
, RONLY
, agent_h_local_vlan
, 8,
1716 { 1, 5, 32962, 1, 2, 3, 1, 2 } },
1717 { LLDP_SNMP_DOT1_PI
, ASN_OCTET_STR
, RONLY
, agent_h_local_pi
, 8,
1718 { 1, 5, 32962, 1, 2, 4, 1, 2 } },
1721 { LLDP_SNMP_DOT1_PVID
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1722 { 1, 5, 32962, 1, 3, 1, 1, 1 } },
1723 { LLDP_SNMP_DOT1_PPVLAN_SUPPORTED
, ASN_INTEGER
, RONLY
, agent_h_remote_ppvid
, 8,
1724 { 1, 5, 32962, 1, 3, 2, 1, 2 } },
1725 { LLDP_SNMP_DOT1_PPVLAN_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_remote_ppvid
, 8,
1726 { 1, 5, 32962, 1, 3, 2, 1, 3 } },
1728 { LLDP_SNMP_DOT1_VLANNAME
, ASN_OCTET_STR
, RONLY
, agent_h_remote_vlan
, 8,
1729 { 1, 5, 32962, 1, 3, 3, 1, 2 } },
1730 /* Protocol identity */
1731 { LLDP_SNMP_DOT1_PI
, ASN_OCTET_STR
, RONLY
, agent_h_remote_pi
, 8,
1732 { 1, 5, 32962, 1, 3, 4, 1, 2 } },
1736 agent_lldp_vars_size(void)
1738 return sizeof(agent_lldp_vars
) / sizeof(struct variable8
);
1742 * Send a notification about a change in one remote neighbor.
1744 * @param hardware Interface on which the change has happened.
1745 * @param type Type of change (add, delete, update)
1746 * @param rport Changed remote port
1749 agent_notify(struct lldpd_hardware
*hardware
, int type
, struct lldpd_port
*rport
)
1751 struct lldpd_hardware
*h
;
1753 /* OID of the notification */
1754 oid notification_oid
[] = { LLDP_OID
, 0, 0, 1 };
1755 size_t notification_oid_len
= OID_LENGTH(notification_oid
);
1756 /* OID for snmpTrapOID.0 */
1757 oid objid_snmptrap
[] = { SNMPTRAP_OID
};
1758 size_t objid_snmptrap_len
= OID_LENGTH(objid_snmptrap
);
1761 oid inserts_oid
[] = { LLDP_OID
, 1, 2, 2 };
1762 size_t inserts_oid_len
= OID_LENGTH(inserts_oid
);
1763 unsigned long inserts
= 0;
1765 oid deletes_oid
[] = { LLDP_OID
, 1, 2, 3 };
1766 size_t deletes_oid_len
= OID_LENGTH(deletes_oid
);
1767 unsigned long deletes
= 0;
1769 oid drops_oid
[] = { LLDP_OID
, 1, 2, 4 };
1770 size_t drops_oid_len
= OID_LENGTH(drops_oid
);
1771 unsigned long drops
= 0;
1773 oid ageouts_oid
[] = { LLDP_OID
, 1, 2, 5 };
1774 size_t ageouts_oid_len
= OID_LENGTH(ageouts_oid
);
1775 unsigned long ageouts
= 0;
1777 /* We also add some extra. Easy ones. */
1778 oid locport_oid
[] = { LLDP_OID
, 1, 3, 7, 1, 4, hardware
->h_ifindex
};
1779 size_t locport_oid_len
= OID_LENGTH(locport_oid
);
1780 oid sysname_oid
[] = { LLDP_OID
, 1, 4, 1, 1, 9, lastchange(rport
),
1781 hardware
->h_ifindex
, rport
->p_chassis
->c_index
};
1782 size_t sysname_oid_len
= OID_LENGTH(sysname_oid
);
1783 oid portdescr_oid
[] = { LLDP_OID
, 1, 4, 1, 1, 8, lastchange(rport
),
1784 hardware
->h_ifindex
, rport
->p_chassis
->c_index
};
1785 size_t portdescr_oid_len
= OID_LENGTH(portdescr_oid
);
1787 netsnmp_variable_list
*notification_vars
= NULL
;
1789 if (!hardware
->h_cfg
->g_snmp
) return;
1792 case NEIGHBOR_CHANGE_DELETED
:
1793 log_debug("snmp", "send notification for neighbor deleted on %s",
1794 hardware
->h_ifname
);
1796 case NEIGHBOR_CHANGE_UPDATED
:
1797 log_debug("snmp", "send notification for neighbor updated on %s",
1798 hardware
->h_ifname
);
1800 case NEIGHBOR_CHANGE_ADDED
:
1801 log_debug("snmp", "send notification for neighbor added on %s",
1802 hardware
->h_ifname
);
1806 TAILQ_FOREACH (h
, &hardware
->h_cfg
->g_hardware
, h_entries
) {
1807 inserts
+= h
->h_insert_cnt
;
1808 deletes
+= h
->h_delete_cnt
;
1809 ageouts
+= h
->h_ageout_cnt
;
1810 drops
+= h
->h_drop_cnt
;
1814 snmp_varlist_add_variable(¬ification_vars
, objid_snmptrap
,
1815 objid_snmptrap_len
, ASN_OBJECT_ID
, (u_char
*)notification_oid
,
1816 notification_oid_len
* sizeof(oid
));
1818 snmp_varlist_add_variable(¬ification_vars
, inserts_oid
, inserts_oid_len
,
1819 ASN_GAUGE
, (u_char
*)&inserts
, sizeof(inserts
));
1820 snmp_varlist_add_variable(¬ification_vars
, deletes_oid
, deletes_oid_len
,
1821 ASN_GAUGE
, (u_char
*)&deletes
, sizeof(inserts
));
1822 snmp_varlist_add_variable(¬ification_vars
, drops_oid
, drops_oid_len
,
1823 ASN_GAUGE
, (u_char
*)&drops
, sizeof(drops
));
1824 snmp_varlist_add_variable(¬ification_vars
, ageouts_oid
, ageouts_oid_len
,
1825 ASN_GAUGE
, (u_char
*)&ageouts
, sizeof(ageouts
));
1827 if (type
!= NEIGHBOR_CHANGE_DELETED
) {
1828 snmp_varlist_add_variable(¬ification_vars
, locport_oid
,
1829 locport_oid_len
, ASN_OCTET_STR
, (u_char
*)hardware
->h_ifname
,
1830 strnlen(hardware
->h_ifname
, IFNAMSIZ
));
1831 if (rport
->p_chassis
->c_name
&& *rport
->p_chassis
->c_name
!= '\0') {
1832 snmp_varlist_add_variable(¬ification_vars
, sysname_oid
,
1833 sysname_oid_len
, ASN_OCTET_STR
,
1834 (u_char
*)rport
->p_chassis
->c_name
,
1835 strlen(rport
->p_chassis
->c_name
));
1837 if (rport
->p_descr
) {
1838 snmp_varlist_add_variable(¬ification_vars
, portdescr_oid
,
1839 portdescr_oid_len
, ASN_OCTET_STR
, (u_char
*)rport
->p_descr
,
1840 strlen(rport
->p_descr
));
1844 log_debug("snmp", "sending SNMP trap (%ld, %ld, %ld)", inserts
, deletes
,
1846 send_v2trap(notification_vars
);
1847 snmp_free_varbind(notification_vars
);
1850 /* Logging NetSNMP messages */
1852 agent_log_callback(int major
, int minor
, void *serverarg
, void *clientarg
)
1854 struct snmp_log_message
*slm
= (struct snmp_log_message
*)serverarg
;
1855 char *msg
= strdup(slm
->msg
);
1860 if (msg
&& msg
[strlen(msg
) - 1] == '\n') msg
[strlen(msg
) - 1] = '\0';
1861 switch (slm
->priority
) {
1863 log_warnx("libsnmp", "%s", msg
? msg
: slm
->msg
);
1866 log_warnx("libsnmp", "%s", msg
? msg
: slm
->msg
);
1869 log_warnx("libsnmp", "%s", msg
? msg
: slm
->msg
);
1872 log_warnx("libsnmp", "%s", msg
? msg
: slm
->msg
);
1875 log_warnx("libsnmp", "%s", msg
? msg
: slm
->msg
);
1878 log_info("libsnmp", "%s", msg
? msg
: slm
->msg
);
1881 log_info("libsnmp", "%s", msg
? msg
: slm
->msg
);
1884 log_debug("libsnmp", "%s", msg
? msg
: slm
->msg
);
1888 return SNMP_ERR_NOERROR
;
1892 agent_init(struct lldpd
*cfg
, const char *agentx
)
1896 log_info("snmp", "enable SNMP subagent");
1897 netsnmp_enable_subagent();
1899 log_debug("snmp", "enable logging");
1901 snmp_enable_calllog();
1902 snmp_register_callback(SNMP_CALLBACK_LIBRARY
, SNMP_CALLBACK_LOGGING
,
1903 agent_log_callback
, NULL
);
1907 /* We are chrooted, we don't want to handle persistent states */
1908 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID
, NETSNMP_DS_LIB_DONT_PERSIST_STATE
,
1910 /* Do not load any MIB */
1911 setenv("MIBS", "", 1);
1912 setenv("MIBDIRS", "/dev/null", 1);
1914 #ifdef ENABLE_PRIVSEP
1915 /* We provide our UNIX domain transport */
1916 log_debug("snmp", "register UNIX domain transport");
1917 agent_priv_register_domain();
1921 netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID
,
1922 NETSNMP_DS_AGENT_X_SOCKET
, agentx
);
1923 init_agent("lldpAgent");
1924 REGISTER_MIB("lldp", agent_lldp_vars
, variable8
, lldp_oid
);
1925 init_snmp("lldpAgent");
1927 log_debug("snmp", "register to sysORTable");
1928 if ((rc
= register_sysORTable(lldp_oid
, OID_LENGTH(lldp_oid
),
1929 "lldpMIB implementation by lldpd")) != 0)
1930 log_warnx("snmp", "unable to register to sysORTable (%d)", rc
);
1936 log_debug("snmp", "agent shutdown");
1937 unregister_sysORTable(lldp_oid
, OID_LENGTH(lldp_oid
));
1938 snmp_shutdown("lldpAgent");