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,
29 size_t *, WriteMethod
**);
33 extern int register_sysORTable(oid
*, size_t, const char *);
34 extern int unregister_sysORTable(oid
*, size_t);
36 /* Global variable because no way to pass it as argument. Should not be used
38 #define scfg agent_scfg
39 struct lldpd
*agent_scfg
;
44 n
= ((n
&0xF0) >>4 ) | ( (n
&0x0F) <<4);
45 n
= ((n
&0xCC) >>2 ) | ( (n
&0x33) <<2);
46 n
= ((n
&0xAA) >>1 ) | ( (n
&0x55) <<1);
51 extern struct timeval starttime
;
53 lastchange(struct lldpd_port
*port
)
55 if (port
->p_lastchange
> starttime
.tv_sec
)
56 return (port
->p_lastchange
- starttime
.tv_sec
)*100;
61 Helper functions to build header_*indexed_table() functions.
62 Those functions keep an internal state. They are not reentrant!
66 oid
*name
; /* Requested/returned OID */
67 size_t *length
; /* Length of above OID */
69 oid best
[MAX_OID_LEN
]; /* Best OID */
70 size_t best_len
; /* Best OID length */
71 void *entity
; /* Best entity */
73 static struct header_index header_idx
;
76 header_index_init(struct variable
*vp
, oid
*name
, size_t *length
,
77 int exact
, size_t *var_len
, WriteMethod
**write_method
)
79 /* If the requested OID name is less than OID prefix we
80 handle, adjust it to our prefix. */
81 if ((snmp_oid_compare(name
, *length
, vp
->name
, vp
->namelen
)) < 0) {
82 memcpy(name
, vp
->name
, sizeof(oid
) * vp
->namelen
);
83 *length
= vp
->namelen
;
85 /* Now, we can only handle OID matching our prefix. Those two
86 tests are not really necessary since NetSNMP won't give us
87 OID "above" our prefix. But this makes unit tests
89 if (*length
< vp
->namelen
) return 0;
90 if (memcmp(name
, vp
->name
, vp
->namelen
* sizeof(oid
))) return 0;
92 if(write_method
!= NULL
) *write_method
= 0;
93 *var_len
= sizeof(long);
95 /* Initialize our header index structure */
97 header_idx
.name
= name
;
98 header_idx
.length
= length
;
99 header_idx
.exact
= exact
;
100 header_idx
.best_len
= 0;
101 header_idx
.entity
= NULL
;
106 header_index_add(oid
*index
, size_t len
, void *entity
)
112 target
= header_idx
.name
+ header_idx
.vp
->namelen
;
113 target_len
= *header_idx
.length
- header_idx
.vp
->namelen
;
114 if ((result
= snmp_oid_compare(index
, len
, target
, target_len
)) < 0)
115 return 0; /* Too small. */
117 return header_idx
.exact
;
118 if (header_idx
.best_len
== 0 ||
119 (snmp_oid_compare(index
, len
,
121 header_idx
.best_len
) < 0)) {
122 memcpy(header_idx
.best
, index
, sizeof(oid
) * len
);
123 header_idx
.best_len
= len
;
124 header_idx
.entity
= entity
;
126 return 0; /* No best match yet. */
132 if (header_idx
.entity
== NULL
)
134 if (header_idx
.exact
)
136 memcpy(header_idx
.name
+ header_idx
.vp
->namelen
,
137 header_idx
.best
, sizeof(oid
) * header_idx
.best_len
);
138 *header_idx
.length
= header_idx
.vp
->namelen
+ header_idx
.best_len
;
139 return header_idx
.entity
;
141 /* ----------------------------- */
143 static struct lldpd_hardware
*
144 header_portindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
145 int exact
, size_t *var_len
, WriteMethod
**write_method
)
147 struct lldpd_hardware
*hardware
;
149 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
150 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
151 oid index
[1] = { hardware
->h_ifindex
};
152 if (header_index_add(index
, 1,
156 return header_index_best();
159 #ifdef ENABLE_LLDPMED
160 static struct lldpd_med_policy
*
161 header_pmedindexed_policy_table(struct variable
*vp
, oid
*name
, size_t *length
,
162 int exact
, size_t *var_len
, WriteMethod
**write_method
)
164 struct lldpd_hardware
*hardware
;
168 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
169 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
170 for (i
= 0; i
< LLDP_MED_APPTYPE_LAST
; i
++) {
171 if (hardware
->h_lport
.p_med_policy
[i
].type
!= i
+1)
173 index
[0] = hardware
->h_ifindex
;
175 if (header_index_add(index
, 2,
176 &hardware
->h_lport
.p_med_policy
[i
]))
177 return &hardware
->h_lport
.p_med_policy
[i
];
180 return header_index_best();
183 static struct lldpd_med_loc
*
184 header_pmedindexed_location_table(struct variable
*vp
, oid
*name
, size_t *length
,
185 int exact
, size_t *var_len
, WriteMethod
**write_method
)
187 struct lldpd_hardware
*hardware
;
191 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
192 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
193 for (i
= 0; i
< LLDP_MED_LOCFORMAT_LAST
; i
++) {
194 if (hardware
->h_lport
.p_med_location
[i
].format
!= i
+1)
196 index
[0] = hardware
->h_ifindex
;
198 if (header_index_add(index
, 2,
199 &hardware
->h_lport
.p_med_location
[i
]))
200 return &hardware
->h_lport
.p_med_location
[i
];
203 return header_index_best();
207 static struct lldpd_port
*
208 header_tprindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
209 int exact
, size_t *var_len
, WriteMethod
**write_method
,
212 struct lldpd_hardware
*hardware
;
213 struct lldpd_port
*port
;
216 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
217 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
218 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
219 if (SMART_HIDDEN(port
)) continue;
220 #ifdef ENABLE_LLDPMED
221 if (withmed
&& !port
->p_chassis
->c_med_cap_available
) continue;
223 index
[0] = lastchange(port
);
224 index
[1] = hardware
->h_ifindex
;
225 index
[2] = port
->p_chassis
->c_index
;
226 if (header_index_add(index
, 3,
231 return header_index_best();
234 static struct lldpd_mgmt
*
235 header_ipindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
236 int exact
, size_t *var_len
, WriteMethod
**write_method
)
238 struct lldpd_chassis
*chassis
= LOCAL_CHASSIS(scfg
);
239 struct lldpd_mgmt
*mgmt
;
242 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
243 TAILQ_FOREACH(mgmt
, &chassis
->c_mgmt
, m_entries
) {
245 switch (mgmt
->m_family
) {
246 case LLDPD_AF_IPV4
: index
[0] = 1; break;
247 case LLDPD_AF_IPV6
: index
[0] = 2; break;
250 index
[1] = mgmt
->m_addrsize
;
251 if (index
[1] > sizeof(index
) - 2)
252 continue; /* Odd... */
253 for (i
= 0; i
< index
[1]; i
++)
254 index
[i
+ 2] = mgmt
->m_addr
.octets
[i
];
255 if (header_index_add(index
, 2 + index
[1], mgmt
))
259 return header_index_best();
262 static struct lldpd_mgmt
*
263 header_tpripindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
264 int exact
, size_t *var_len
, WriteMethod
**write_method
)
266 struct lldpd_hardware
*hardware
;
267 struct lldpd_port
*port
;
268 struct lldpd_mgmt
*mgmt
;
271 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
272 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
273 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
274 if (SMART_HIDDEN(port
)) continue;
275 TAILQ_FOREACH(mgmt
, &port
->p_chassis
->c_mgmt
, m_entries
) {
277 index
[0] = lastchange(port
);
278 index
[1] = hardware
->h_ifindex
;
279 index
[2] = port
->p_chassis
->c_index
;
280 switch (mgmt
->m_family
) {
281 case LLDPD_AF_IPV4
: index
[3] = 1; break;
282 case LLDPD_AF_IPV6
: index
[3] = 2; break;
285 index
[4] = mgmt
->m_addrsize
;
286 if (index
[4] > sizeof(index
) - 5)
287 continue; /* Odd... */
288 for (i
= 0; i
< index
[4]; i
++)
289 index
[i
+ 5] = mgmt
->m_addr
.octets
[i
];
290 if (header_index_add(index
, 5 + index
[4], mgmt
))
295 return header_index_best();
298 #ifdef ENABLE_LLDPMED
299 #define TPR_VARIANT_MED_POLICY 2
300 #define TPR_VARIANT_MED_LOCATION 3
302 header_tprmedindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
303 int exact
, size_t *var_len
, WriteMethod
**write_method
, int variant
)
305 struct lldpd_hardware
*hardware
;
306 struct lldpd_port
*port
;
310 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
311 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
312 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
313 if (SMART_HIDDEN(port
)) continue;
314 if (!port
->p_chassis
->c_med_cap_available
) continue;
316 case TPR_VARIANT_MED_POLICY
:
318 j
< LLDP_MED_APPTYPE_LAST
;
320 if (port
->p_med_policy
[j
].type
!= j
+1)
322 index
[0] = lastchange(port
);
323 index
[1] = hardware
->h_ifindex
;
324 index
[2] = port
->p_chassis
->c_index
;
326 if (header_index_add(index
, 4,
327 &port
->p_med_policy
[j
]))
328 return &port
->p_med_policy
[j
];
331 case TPR_VARIANT_MED_LOCATION
:
333 j
< LLDP_MED_LOCFORMAT_LAST
;
335 if (port
->p_med_location
[j
].format
!= j
+1)
337 index
[0] = lastchange(port
);
338 index
[1] = hardware
->h_ifindex
;
339 index
[2] = port
->p_chassis
->c_index
;
341 if (header_index_add(index
, 4,
342 &port
->p_med_location
[j
]))
343 return &port
->p_med_location
[j
];
349 return header_index_best();
354 static struct lldpd_vlan
*
355 header_pvindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
356 int exact
, size_t *var_len
, WriteMethod
**write_method
)
358 struct lldpd_hardware
*hardware
;
359 struct lldpd_vlan
*vlan
;
361 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
362 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
363 TAILQ_FOREACH(vlan
, &hardware
->h_lport
.p_vlans
, v_entries
) {
364 oid index
[2] = { hardware
->h_ifindex
,
366 if (header_index_add(index
, 2, vlan
))
370 return header_index_best();
373 static struct lldpd_vlan
*
374 header_tprvindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
375 int exact
, size_t *var_len
, WriteMethod
**write_method
)
377 struct lldpd_hardware
*hardware
;
378 struct lldpd_port
*port
;
379 struct lldpd_vlan
*vlan
;
381 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
382 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
383 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
384 if (SMART_HIDDEN(port
)) continue;
385 TAILQ_FOREACH(vlan
, &port
->p_vlans
, v_entries
) {
386 oid index
[4] = { lastchange(port
),
388 port
->p_chassis
->c_index
,
390 if (header_index_add(index
, 4,
396 return header_index_best();
399 static struct lldpd_ppvid
*
400 header_pppvidindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
401 int exact
, size_t *var_len
, WriteMethod
**write_method
)
403 struct lldpd_hardware
*hardware
;
404 struct lldpd_ppvid
*ppvid
;
406 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
407 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
408 TAILQ_FOREACH(ppvid
, &hardware
->h_lport
.p_ppvids
, p_entries
) {
409 oid index
[2] = { hardware
->h_ifindex
,
411 if (header_index_add(index
, 2,
416 return header_index_best();
419 static struct lldpd_ppvid
*
420 header_tprppvidindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
421 int exact
, size_t *var_len
, WriteMethod
**write_method
)
423 struct lldpd_hardware
*hardware
;
424 struct lldpd_port
*port
;
425 struct lldpd_ppvid
*ppvid
;
427 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
428 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
429 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
430 if (SMART_HIDDEN(port
)) continue;
431 TAILQ_FOREACH(ppvid
, &port
->p_ppvids
, p_entries
) {
432 oid index
[4] = { lastchange(port
),
434 port
->p_chassis
->c_index
,
436 if (header_index_add(index
, 4,
442 return header_index_best();
445 static struct lldpd_pi
*
446 header_ppiindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
447 int exact
, size_t *var_len
, WriteMethod
**write_method
)
449 struct lldpd_hardware
*hardware
;
452 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
453 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
454 TAILQ_FOREACH(pi
, &hardware
->h_lport
.p_pids
, p_entries
) {
455 oid index
[2] = { hardware
->h_ifindex
,
456 frame_checksum((const u_char
*)pi
->p_pi
,
458 if (header_index_add(index
, 2,
463 return header_index_best();
466 static struct lldpd_pi
*
467 header_tprpiindexed_table(struct variable
*vp
, oid
*name
, size_t *length
,
468 int exact
, size_t *var_len
, WriteMethod
**write_method
)
470 struct lldpd_hardware
*hardware
;
471 struct lldpd_port
*port
;
474 if (!header_index_init(vp
, name
, length
, exact
, var_len
, write_method
)) return NULL
;
475 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
476 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
477 if (SMART_HIDDEN(port
)) continue;
478 TAILQ_FOREACH(pi
, &port
->p_pids
, p_entries
) {
479 oid index
[4] = { lastchange(port
),
481 port
->p_chassis
->c_index
,
482 frame_checksum((const u_char
*)pi
->p_pi
,
484 if (header_index_add(index
, 4,
490 return header_index_best();
495 #define LLDP_SNMP_TXINTERVAL 1
496 #define LLDP_SNMP_TXMULTIPLIER 2
497 #define LLDP_SNMP_REINITDELAY 3
498 #define LLDP_SNMP_TXDELAY 4
499 #define LLDP_SNMP_NOTIFICATION 5
500 #define LLDP_SNMP_LASTUPDATE 6
501 #define LLDP_SNMP_STATS_INSERTS 7
502 #define LLDP_SNMP_STATS_DELETES 8
503 #define LLDP_SNMP_STATS_DROPS 9
504 #define LLDP_SNMP_STATS_AGEOUTS 10
506 #define LLDP_SNMP_CIDSUBTYPE 1
507 #define LLDP_SNMP_CID 2
508 #define LLDP_SNMP_SYSNAME 3
509 #define LLDP_SNMP_SYSDESCR 4
510 #define LLDP_SNMP_SYSCAP_SUP 5
511 #define LLDP_SNMP_SYSCAP_ENA 6
513 #define LLDP_SNMP_STATS_TX 2
514 #define LLDP_SNMP_STATS_RX_DISCARDED 4
515 #define LLDP_SNMP_STATS_RX_ERRORS 5
516 #define LLDP_SNMP_STATS_RX 6
517 #define LLDP_SNMP_STATS_RX_TLVDISCARDED 7
518 #define LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED 8
519 #define LLDP_SNMP_STATS_RX_AGEOUTS 9
521 #define LLDP_SNMP_PIDSUBTYPE 2
522 #define LLDP_SNMP_PID 3
523 #define LLDP_SNMP_PORTDESC 4
524 #define LLDP_SNMP_DOT3_AUTONEG_SUPPORT 5
525 #define LLDP_SNMP_DOT3_AUTONEG_ENABLED 6
526 #define LLDP_SNMP_DOT3_AUTONEG_ADVERTISED 7
527 #define LLDP_SNMP_DOT3_AUTONEG_MAU 8
528 #define LLDP_SNMP_DOT3_AGG_STATUS 9
529 #define LLDP_SNMP_DOT3_AGG_ID 10
530 #define LLDP_SNMP_DOT3_MFS 11
531 #define LLDP_SNMP_DOT3_POWER_DEVICETYPE 12
532 #define LLDP_SNMP_DOT3_POWER_SUPPORT 13
533 #define LLDP_SNMP_DOT3_POWER_ENABLED 14
534 #define LLDP_SNMP_DOT3_POWER_PAIRCONTROL 15
535 #define LLDP_SNMP_DOT3_POWER_PAIRS 16
536 #define LLDP_SNMP_DOT3_POWER_CLASS 17
537 #define LLDP_SNMP_DOT3_POWER_TYPE 18
538 #define LLDP_SNMP_DOT3_POWER_SOURCE 19
539 #define LLDP_SNMP_DOT3_POWER_PRIORITY 20
540 #define LLDP_SNMP_DOT3_POWER_REQUESTED 21
541 #define LLDP_SNMP_DOT3_POWER_ALLOCATED 22
542 #define LLDP_SNMP_DOT1_PVID 23
544 #define LLDP_SNMP_DOT1_VLANNAME 1
545 /* Protocol VLAN IDs */
546 #define LLDP_SNMP_DOT1_PPVLAN_SUPPORTED 2
547 #define LLDP_SNMP_DOT1_PPVLAN_ENABLED 3
548 /* Protocol Identity */
549 #define LLDP_SNMP_DOT1_PI 1
550 /* Management address */
551 #define LLDP_SNMP_ADDR_LEN 1
552 #define LLDP_SNMP_ADDR_IFSUBTYPE 2
553 #define LLDP_SNMP_ADDR_IFID 3
554 #define LLDP_SNMP_ADDR_OID 4
556 #define LLDP_SNMP_MED_CAP_AVAILABLE 1
557 #define LLDP_SNMP_MED_CAP_ENABLED 2
558 #define LLDP_SNMP_MED_CLASS 3
559 #define LLDP_SNMP_MED_HW 4
560 #define LLDP_SNMP_MED_FW 5
561 #define LLDP_SNMP_MED_SW 6
562 #define LLDP_SNMP_MED_SN 7
563 #define LLDP_SNMP_MED_MANUF 8
564 #define LLDP_SNMP_MED_MODEL 9
565 #define LLDP_SNMP_MED_ASSET 10
566 #define LLDP_SNMP_MED_POLICY_VID 11
567 #define LLDP_SNMP_MED_POLICY_PRIO 12
568 #define LLDP_SNMP_MED_POLICY_DSCP 13
569 #define LLDP_SNMP_MED_POLICY_UNKNOWN 14
570 #define LLDP_SNMP_MED_POLICY_TAGGED 15
571 #define LLDP_SNMP_MED_LOCATION 16
572 #define LLDP_SNMP_MED_POE_DEVICETYPE 17
573 #define LLDP_SNMP_MED_POE_PSE_POWERVAL 19
574 #define LLDP_SNMP_MED_POE_PSE_POWERSOURCE 20
575 #define LLDP_SNMP_MED_POE_PSE_POWERPRIORITY 21
576 #define LLDP_SNMP_MED_POE_PD_POWERVAL 22
577 #define LLDP_SNMP_MED_POE_PD_POWERSOURCE 23
578 #define LLDP_SNMP_MED_POE_PD_POWERPRIORITY 24
580 /* The following macro should be used anytime where the selected OID
581 is finally not returned (for example, when the associated data is
582 not available). In this case, we retry the function with the next
586 if (!exact && (name[*length-1] < MAX_SUBID)) \
587 return X(vp, name, length, \
588 exact, var_len, write_method); \
594 agent_h_scalars(struct variable
*vp
, oid
*name
, size_t *length
,
595 int exact
, size_t *var_len
, WriteMethod
**write_method
)
597 static unsigned long long_ret
;
598 struct lldpd_hardware
*hardware
;
599 struct lldpd_port
*port
;
601 if (header_generic(vp
, name
, length
, exact
, var_len
, write_method
))
605 case LLDP_SNMP_TXINTERVAL
:
606 long_ret
= scfg
->g_config
.c_tx_interval
;
607 return (u_char
*)&long_ret
;
608 case LLDP_SNMP_TXMULTIPLIER
:
609 long_ret
= scfg
->g_config
.c_ttl
/ scfg
->g_config
.c_tx_interval
;
610 return (u_char
*)&long_ret
;
611 case LLDP_SNMP_REINITDELAY
:
613 return (u_char
*)&long_ret
;
614 case LLDP_SNMP_TXDELAY
:
615 long_ret
= LLDPD_TX_MSGDELAY
;
616 return (u_char
*)&long_ret
;
617 case LLDP_SNMP_NOTIFICATION
:
619 return (u_char
*)&long_ret
;
620 case LLDP_SNMP_LASTUPDATE
:
622 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
623 /* Check if the last removal of a remote port on this local port was the last change. */
624 if (hardware
->h_lport
.p_lastremove
> long_ret
)
625 long_ret
= hardware
->h_lport
.p_lastremove
;
626 /* Check if any change on the existing remote ports was the last change. */
627 TAILQ_FOREACH(port
, &hardware
->h_rports
, p_entries
) {
628 if (SMART_HIDDEN(port
)) continue;
629 if (port
->p_lastchange
> long_ret
)
630 long_ret
= port
->p_lastchange
;
634 long_ret
= (long_ret
- starttime
.tv_sec
) * 100;
635 return (u_char
*)&long_ret
;
636 case LLDP_SNMP_STATS_INSERTS
:
637 /* We assume this is equal to valid frames received on all ports */
639 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
)
640 long_ret
+= hardware
->h_insert_cnt
;
641 return (u_char
*)&long_ret
;
642 case LLDP_SNMP_STATS_AGEOUTS
:
644 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
)
645 long_ret
+= hardware
->h_ageout_cnt
;
646 return (u_char
*)&long_ret
;
647 case LLDP_SNMP_STATS_DELETES
:
649 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
)
650 long_ret
+= hardware
->h_delete_cnt
;
651 return (u_char
*)&long_ret
;
652 case LLDP_SNMP_STATS_DROPS
:
654 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
)
655 long_ret
+= hardware
->h_drop_cnt
;
656 return (u_char
*)&long_ret
;
663 #ifdef ENABLE_LLDPMED
665 agent_v_med_power(struct variable
*vp
, size_t *var_len
, struct lldpd_med_power
*power
)
667 static unsigned long long_ret
;
670 case LLDP_SNMP_MED_POE_DEVICETYPE
:
671 switch (power
->devicetype
) {
672 case LLDP_MED_POW_TYPE_PSE
:
674 case LLDP_MED_POW_TYPE_PD
:
681 return (u_char
*)&long_ret
;
682 case LLDP_SNMP_MED_POE_PSE_POWERVAL
:
683 case LLDP_SNMP_MED_POE_PD_POWERVAL
:
684 if (((vp
->magic
== LLDP_SNMP_MED_POE_PSE_POWERVAL
) &&
685 (power
->devicetype
==
686 LLDP_MED_POW_TYPE_PSE
)) ||
687 ((vp
->magic
== LLDP_SNMP_MED_POE_PD_POWERVAL
) &&
688 (power
->devicetype
==
689 LLDP_MED_POW_TYPE_PD
))) {
690 long_ret
= power
->val
;
691 return (u_char
*)&long_ret
;
694 case LLDP_SNMP_MED_POE_PSE_POWERSOURCE
:
695 if (power
->devicetype
==
696 LLDP_MED_POW_TYPE_PSE
) {
697 switch (power
->source
) {
698 case LLDP_MED_POW_SOURCE_PRIMARY
:
700 case LLDP_MED_POW_SOURCE_BACKUP
:
705 return (u_char
*)&long_ret
;
708 case LLDP_SNMP_MED_POE_PD_POWERSOURCE
:
709 if (power
->devicetype
==
710 LLDP_MED_POW_TYPE_PD
) {
711 switch (power
->source
) {
712 case LLDP_MED_POW_SOURCE_PSE
:
714 case LLDP_MED_POW_SOURCE_LOCAL
:
716 case LLDP_MED_POW_SOURCE_BOTH
:
721 return (u_char
*)&long_ret
;
724 case LLDP_SNMP_MED_POE_PSE_POWERPRIORITY
:
725 case LLDP_SNMP_MED_POE_PD_POWERPRIORITY
:
726 if (((vp
->magic
== LLDP_SNMP_MED_POE_PSE_POWERPRIORITY
) &&
727 (power
->devicetype
==
728 LLDP_MED_POW_TYPE_PSE
)) ||
729 ((vp
->magic
== LLDP_SNMP_MED_POE_PD_POWERPRIORITY
) &&
730 (power
->devicetype
==
731 LLDP_MED_POW_TYPE_PD
))) {
732 switch (power
->priority
) {
733 case LLDP_MED_POW_PRIO_CRITICAL
:
735 case LLDP_MED_POW_PRIO_HIGH
:
737 case LLDP_MED_POW_PRIO_LOW
:
742 return (u_char
*)&long_ret
;
750 agent_h_local_med_power(struct variable
*vp
, oid
*name
, size_t *length
,
751 int exact
, size_t *var_len
, WriteMethod
**write_method
)
753 struct lldpd_med_power
*power
= NULL
;
754 struct lldpd_hardware
*hardware
;
757 if (!LOCAL_CHASSIS(scfg
)->c_med_cap_available
)
759 if (header_generic(vp
, name
, length
, exact
, var_len
, write_method
))
762 /* LLDP-MED requires only one device type for all
763 ports. Moreover, a PSE can only have one power source. At
764 least, all PD values are global and not per-port. We try to
765 do our best. For device type, we decide on the number of
767 TAILQ_FOREACH(hardware
, &scfg
->g_hardware
, h_entries
) {
768 if (hardware
->h_lport
.p_med_power
.devicetype
==
769 LLDP_MED_POW_TYPE_PSE
) {
771 if (pse
== 1) /* Take this port as a reference */
772 power
= &hardware
->h_lport
.p_med_power
;
773 } else if (hardware
->h_lport
.p_med_power
.devicetype
==
774 LLDP_MED_POW_TYPE_PD
) {
776 if (pse
== -1) /* Take this one instead */
777 power
= &hardware
->h_lport
.p_med_power
;
782 if ((a
= agent_v_med_power(vp
, var_len
, power
)) != NULL
)
785 TRYNEXT(agent_h_local_med_power
);
788 agent_h_remote_med_power(struct variable
*vp
, oid
*name
, size_t *length
,
789 int exact
, size_t *var_len
, WriteMethod
**write_method
)
791 struct lldpd_port
*port
;
794 if ((port
= header_tprindexed_table(vp
, name
, length
,
795 exact
, var_len
, write_method
, 1)) == NULL
)
798 if ((a
= agent_v_med_power(vp
, var_len
, &port
->p_med_power
)) != NULL
)
800 TRYNEXT(agent_h_remote_med_power
);
804 agent_v_med(struct variable
*vp
, size_t *var_len
,
805 struct lldpd_chassis
*chassis
,
806 struct lldpd_port
*port
)
808 static unsigned long long_ret
;
812 case LLDP_SNMP_MED_CLASS
:
813 long_ret
= chassis
->c_med_type
;
814 return (u_char
*)&long_ret
;
815 case LLDP_SNMP_MED_CAP_AVAILABLE
:
817 bit
= swap_bits(chassis
->c_med_cap_available
);
818 return (u_char
*)&bit
;
819 case LLDP_SNMP_MED_CAP_ENABLED
:
822 bit
= swap_bits(port
->p_med_cap_enabled
);
823 return (u_char
*)&bit
;
825 #define LLDP_H_MED(magic, variable) \
827 if (chassis->variable) { \
829 chassis->variable); \
835 LLDP_H_MED(LLDP_SNMP_MED_HW
,
837 LLDP_H_MED(LLDP_SNMP_MED_SW
,
839 LLDP_H_MED(LLDP_SNMP_MED_FW
,
841 LLDP_H_MED(LLDP_SNMP_MED_SN
,
843 LLDP_H_MED(LLDP_SNMP_MED_MANUF
,
845 LLDP_H_MED(LLDP_SNMP_MED_MODEL
,
847 LLDP_H_MED(LLDP_SNMP_MED_ASSET
,
854 agent_h_local_med(struct variable
*vp
, oid
*name
, size_t *length
,
855 int exact
, size_t *var_len
, WriteMethod
**write_method
)
859 if (!LOCAL_CHASSIS(scfg
)->c_med_cap_available
)
861 if (header_generic(vp
, name
, length
, exact
, var_len
, write_method
))
864 if ((a
= agent_v_med(vp
, var_len
,
865 LOCAL_CHASSIS(scfg
), NULL
)) != NULL
)
867 TRYNEXT(agent_h_local_med
);
871 agent_h_remote_med(struct variable
*vp
, oid
*name
, size_t *length
,
872 int exact
, size_t *var_len
, WriteMethod
**write_method
)
874 struct lldpd_port
*port
;
877 if ((port
= header_tprindexed_table(vp
, name
, length
,
878 exact
, var_len
, write_method
, 1)) == NULL
)
881 if ((a
= agent_v_med(vp
, var_len
,
882 port
->p_chassis
, port
)) != NULL
)
884 TRYNEXT(agent_h_remote_med
);
888 agent_v_med_policy(struct variable
*vp
, size_t *var_len
,
889 struct lldpd_med_policy
*policy
)
891 static unsigned long long_ret
;
894 case LLDP_SNMP_MED_POLICY_VID
:
895 long_ret
= policy
->vid
;
896 return (u_char
*)&long_ret
;
897 case LLDP_SNMP_MED_POLICY_PRIO
:
898 long_ret
= policy
->priority
;
899 return (u_char
*)&long_ret
;
900 case LLDP_SNMP_MED_POLICY_DSCP
:
901 long_ret
= policy
->dscp
;
902 return (u_char
*)&long_ret
;
903 case LLDP_SNMP_MED_POLICY_UNKNOWN
:
904 long_ret
= policy
->unknown
?1:2;
905 return (u_char
*)&long_ret
;
906 case LLDP_SNMP_MED_POLICY_TAGGED
:
907 long_ret
= policy
->tagged
?1:2;
908 return (u_char
*)&long_ret
;
914 agent_h_remote_med_policy(struct variable
*vp
, oid
*name
, size_t *length
,
915 int exact
, size_t *var_len
, WriteMethod
**write_method
)
917 struct lldpd_med_policy
*policy
;
919 if ((policy
= (struct lldpd_med_policy
*)header_tprmedindexed_table(vp
, name
, length
,
920 exact
, var_len
, write_method
, TPR_VARIANT_MED_POLICY
)) == NULL
)
923 return agent_v_med_policy(vp
, var_len
, policy
);
926 agent_h_local_med_policy(struct variable
*vp
, oid
*name
, size_t *length
,
927 int exact
, size_t *var_len
, WriteMethod
**write_method
)
929 struct lldpd_med_policy
*policy
;
931 if ((policy
= (struct lldpd_med_policy
*)header_pmedindexed_policy_table(vp
, name
, length
,
932 exact
, var_len
, write_method
)) == NULL
)
935 return agent_v_med_policy(vp
, var_len
, policy
);
939 agent_v_med_location(struct variable
*vp
, size_t *var_len
,
940 struct lldpd_med_loc
*location
)
943 case LLDP_SNMP_MED_LOCATION
:
944 *var_len
= location
->data_len
;
945 return (u_char
*)location
->data
;
951 agent_h_remote_med_location(struct variable
*vp
, oid
*name
, size_t *length
,
952 int exact
, size_t *var_len
, WriteMethod
**write_method
)
954 struct lldpd_med_loc
*location
;
956 if ((location
= (struct lldpd_med_loc
*)header_tprmedindexed_table(vp
, name
, length
,
957 exact
, var_len
, write_method
, TPR_VARIANT_MED_LOCATION
)) == NULL
)
960 return agent_v_med_location(vp
, var_len
, location
);
963 agent_h_local_med_location(struct variable
*vp
, oid
*name
, size_t *length
,
964 int exact
, size_t *var_len
, WriteMethod
**write_method
)
966 struct lldpd_med_loc
*location
;
968 if ((location
= (struct lldpd_med_loc
*)header_pmedindexed_location_table(vp
, name
, length
,
969 exact
, var_len
, write_method
)) == NULL
)
972 return agent_v_med_location(vp
, var_len
, location
);
977 agent_v_chassis(struct variable
*vp
, size_t *var_len
,
978 struct lldpd_chassis
*chassis
)
981 static unsigned long long_ret
;
984 case LLDP_SNMP_CIDSUBTYPE
:
985 long_ret
= chassis
->c_id_subtype
;
986 return (u_char
*)&long_ret
;
988 *var_len
= chassis
->c_id_len
;
989 return (u_char
*)chassis
->c_id
;
990 case LLDP_SNMP_SYSNAME
:
991 if (!chassis
->c_name
|| *chassis
->c_name
== '\0') break;
992 *var_len
= strlen(chassis
->c_name
);
993 return (u_char
*)chassis
->c_name
;
994 case LLDP_SNMP_SYSDESCR
:
995 if (!chassis
->c_descr
|| *chassis
->c_descr
== '\0') break;
996 *var_len
= strlen(chassis
->c_descr
);
997 return (u_char
*)chassis
->c_descr
;
998 case LLDP_SNMP_SYSCAP_SUP
:
1000 bit
= swap_bits(chassis
->c_cap_available
);
1001 return (u_char
*)&bit
;
1002 case LLDP_SNMP_SYSCAP_ENA
:
1004 bit
= swap_bits(chassis
->c_cap_enabled
);
1005 return (u_char
*)&bit
;
1012 agent_h_local_chassis(struct variable
*vp
, oid
*name
, size_t *length
,
1013 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1015 if (header_generic(vp
, name
, length
, exact
, var_len
, write_method
))
1018 return agent_v_chassis(vp
, var_len
, LOCAL_CHASSIS(scfg
));
1021 agent_h_remote_chassis(struct variable
*vp
, oid
*name
, size_t *length
,
1022 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1024 struct lldpd_port
*port
;
1026 if ((port
= header_tprindexed_table(vp
, name
, length
,
1027 exact
, var_len
, write_method
, 0)) == NULL
)
1030 return agent_v_chassis(vp
, var_len
, port
->p_chassis
);
1034 agent_h_stats(struct variable
*vp
, oid
*name
, size_t *length
,
1035 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1037 static unsigned long long_ret
;
1038 struct lldpd_hardware
*hardware
;
1040 if ((hardware
= header_portindexed_table(vp
, name
, length
,
1041 exact
, var_len
, write_method
)) == NULL
)
1044 switch (vp
->magic
) {
1045 case LLDP_SNMP_STATS_TX
:
1046 long_ret
= hardware
->h_tx_cnt
;
1047 return (u_char
*)&long_ret
;
1048 case LLDP_SNMP_STATS_RX
:
1049 long_ret
= hardware
->h_rx_cnt
;
1050 return (u_char
*)&long_ret
;
1051 case LLDP_SNMP_STATS_RX_DISCARDED
:
1052 case LLDP_SNMP_STATS_RX_ERRORS
:
1053 /* We discard only frame with errors. Therefore, the two values
1055 long_ret
= hardware
->h_rx_discarded_cnt
;
1056 return (u_char
*)&long_ret
;
1057 case LLDP_SNMP_STATS_RX_TLVDISCARDED
:
1058 case LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED
:
1059 /* We discard only unrecognized TLV. Malformed TLV
1060 implies dropping the whole frame */
1061 long_ret
= hardware
->h_rx_unrecognized_cnt
;
1062 return (u_char
*)&long_ret
;
1063 case LLDP_SNMP_STATS_RX_AGEOUTS
:
1064 long_ret
= hardware
->h_ageout_cnt
;
1065 return (u_char
*)&long_ret
;
1074 agent_v_vlan(struct variable
*vp
, size_t *var_len
, struct lldpd_vlan
*vlan
)
1076 switch (vp
->magic
) {
1077 case LLDP_SNMP_DOT1_VLANNAME
:
1078 *var_len
= strlen(vlan
->v_name
);
1079 return (u_char
*)vlan
->v_name
;
1086 agent_h_local_vlan(struct variable
*vp
, oid
*name
, size_t *length
,
1087 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1089 struct lldpd_vlan
*vlan
;
1091 if ((vlan
= header_pvindexed_table(vp
, name
, length
,
1092 exact
, var_len
, write_method
)) == NULL
)
1095 return agent_v_vlan(vp
, var_len
, vlan
);
1098 agent_h_remote_vlan(struct variable
*vp
, oid
*name
, size_t *length
,
1099 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1101 struct lldpd_vlan
*vlan
;
1103 if ((vlan
= header_tprvindexed_table(vp
, name
, length
,
1104 exact
, var_len
, write_method
)) == NULL
)
1107 return agent_v_vlan(vp
, var_len
, vlan
);
1111 agent_v_ppvid(struct variable
*vp
, size_t *var_len
, struct lldpd_ppvid
*ppvid
)
1113 static unsigned long long_ret
;
1115 switch (vp
->magic
) {
1116 case LLDP_SNMP_DOT1_PPVLAN_SUPPORTED
:
1117 long_ret
= (ppvid
->p_cap_status
& LLDP_PPVID_CAP_SUPPORTED
)?1:2;
1118 return (u_char
*)&long_ret
;
1119 case LLDP_SNMP_DOT1_PPVLAN_ENABLED
:
1120 long_ret
= (ppvid
->p_cap_status
& LLDP_PPVID_CAP_ENABLED
)?1:2;
1121 return (u_char
*)&long_ret
;
1128 agent_h_local_ppvid(struct variable
*vp
, oid
*name
, size_t *length
,
1129 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1131 struct lldpd_ppvid
*ppvid
;
1133 if ((ppvid
= header_pppvidindexed_table(vp
, name
, length
,
1134 exact
, var_len
, write_method
)) == NULL
)
1137 return agent_v_ppvid(vp
, var_len
, ppvid
);
1141 agent_h_remote_ppvid(struct variable
*vp
, oid
*name
, size_t *length
,
1142 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1144 struct lldpd_ppvid
*ppvid
;
1146 if ((ppvid
= header_tprppvidindexed_table(vp
, name
, length
,
1147 exact
, var_len
, write_method
)) == NULL
)
1150 return agent_v_ppvid(vp
, var_len
, ppvid
);
1154 agent_v_pi(struct variable
*vp
, size_t *var_len
, struct lldpd_pi
*pi
)
1156 switch (vp
->magic
) {
1157 case LLDP_SNMP_DOT1_PI
:
1158 *var_len
= pi
->p_pi_len
;
1159 return (u_char
*)pi
->p_pi
;
1166 agent_h_local_pi(struct variable
*vp
, oid
*name
, size_t *length
,
1167 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1169 struct lldpd_pi
*pi
;
1171 if ((pi
= header_ppiindexed_table(vp
, name
, length
,
1172 exact
, var_len
, write_method
)) == NULL
)
1175 return agent_v_pi(vp
, var_len
, pi
);
1178 agent_h_remote_pi(struct variable
*vp
, oid
*name
, size_t *length
,
1179 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1181 struct lldpd_pi
*pi
;
1183 if ((pi
= header_tprpiindexed_table(vp
, name
, length
,
1184 exact
, var_len
, write_method
)) == NULL
)
1187 return agent_v_pi(vp
, var_len
, pi
);
1192 agent_v_port(struct variable
*vp
, size_t *var_len
, struct lldpd_port
*port
)
1195 static uint16_t short_ret
;
1198 static unsigned long long_ret
;
1200 switch (vp
->magic
) {
1201 case LLDP_SNMP_PIDSUBTYPE
:
1202 long_ret
= port
->p_id_subtype
;
1203 return (u_char
*)&long_ret
;
1205 *var_len
= port
->p_id_len
;
1206 return (u_char
*)port
->p_id
;
1207 case LLDP_SNMP_PORTDESC
:
1208 if (!port
->p_descr
|| *port
->p_descr
== '\0') break;
1209 *var_len
= strlen(port
->p_descr
);
1210 return (u_char
*)port
->p_descr
;
1212 case LLDP_SNMP_DOT3_AUTONEG_SUPPORT
:
1213 long_ret
= 2 - port
->p_macphy
.autoneg_support
;
1214 return (u_char
*)&long_ret
;
1215 case LLDP_SNMP_DOT3_AUTONEG_ENABLED
:
1216 long_ret
= 2 - port
->p_macphy
.autoneg_enabled
;
1217 return (u_char
*)&long_ret
;
1218 case LLDP_SNMP_DOT3_AUTONEG_ADVERTISED
:
1220 short_ret
= htons(port
->p_macphy
.autoneg_advertised
);
1221 return (u_char
*)&short_ret
;
1222 case LLDP_SNMP_DOT3_AUTONEG_MAU
:
1223 long_ret
= port
->p_macphy
.mau_type
;
1224 return (u_char
*)&long_ret
;
1225 case LLDP_SNMP_DOT3_AGG_STATUS
:
1226 bit
= swap_bits((port
->p_aggregid
> 0) ? 3 : 0);
1228 return (u_char
*)&bit
;
1229 case LLDP_SNMP_DOT3_AGG_ID
:
1230 long_ret
= port
->p_aggregid
;
1231 return (u_char
*)&long_ret
;
1232 case LLDP_SNMP_DOT3_MFS
:
1234 long_ret
= port
->p_mfs
;
1235 return (u_char
*)&long_ret
;
1238 case LLDP_SNMP_DOT3_POWER_DEVICETYPE
:
1239 if (port
->p_power
.devicetype
) {
1240 long_ret
= (port
->p_power
.devicetype
== LLDP_DOT3_POWER_PSE
)?1:2;
1241 return (u_char
*)&long_ret
;
1244 case LLDP_SNMP_DOT3_POWER_SUPPORT
:
1245 if (port
->p_power
.devicetype
) {
1246 long_ret
= (port
->p_power
.supported
)?1:2;
1247 return (u_char
*)&long_ret
;
1250 case LLDP_SNMP_DOT3_POWER_ENABLED
:
1251 if (port
->p_power
.devicetype
) {
1252 long_ret
= (port
->p_power
.enabled
)?1:2;
1253 return (u_char
*)&long_ret
;
1256 case LLDP_SNMP_DOT3_POWER_PAIRCONTROL
:
1257 if (port
->p_power
.devicetype
) {
1258 long_ret
= (port
->p_power
.paircontrol
)?1:2;
1259 return (u_char
*)&long_ret
;
1262 case LLDP_SNMP_DOT3_POWER_PAIRS
:
1263 if (port
->p_power
.devicetype
) {
1264 long_ret
= port
->p_power
.pairs
;
1265 return (u_char
*)&long_ret
;
1268 case LLDP_SNMP_DOT3_POWER_CLASS
:
1269 if (port
->p_power
.devicetype
&& port
->p_power
.class) {
1270 long_ret
= port
->p_power
.class;
1271 return (u_char
*)&long_ret
;
1274 case LLDP_SNMP_DOT3_POWER_TYPE
:
1275 if (port
->p_power
.devicetype
&&
1276 port
->p_power
.powertype
!= LLDP_DOT3_POWER_8023AT_OFF
) {
1278 bit
= (((port
->p_power
.powertype
==
1279 LLDP_DOT3_POWER_8023AT_TYPE1
)?0:1) << 7) |
1280 (((port
->p_power
.devicetype
==
1281 LLDP_DOT3_POWER_PSE
)?0:1) << 6);
1282 return (u_char
*)&bit
;
1285 case LLDP_SNMP_DOT3_POWER_SOURCE
:
1286 if (port
->p_power
.devicetype
&&
1287 port
->p_power
.powertype
!= LLDP_DOT3_POWER_8023AT_OFF
) {
1289 bit
= swap_bits(port
->p_power
.source
%(1<<2));
1290 return (u_char
*)&bit
;
1293 case LLDP_SNMP_DOT3_POWER_PRIORITY
:
1294 if (port
->p_power
.devicetype
&&
1295 port
->p_power
.powertype
!= LLDP_DOT3_POWER_8023AT_OFF
) {
1296 /* See 30.12.2.1.16. This seems defined in reverse order... */
1297 long_ret
= 4 - port
->p_power
.priority
;
1298 return (u_char
*)&long_ret
;
1301 case LLDP_SNMP_DOT3_POWER_REQUESTED
:
1302 if (port
->p_power
.devicetype
&&
1303 port
->p_power
.powertype
!= LLDP_DOT3_POWER_8023AT_OFF
) {
1304 long_ret
= port
->p_power
.requested
;
1305 return (u_char
*)&long_ret
;
1308 case LLDP_SNMP_DOT3_POWER_ALLOCATED
:
1309 if (port
->p_power
.devicetype
&&
1310 port
->p_power
.powertype
!= LLDP_DOT3_POWER_8023AT_OFF
) {
1311 long_ret
= port
->p_power
.allocated
;
1312 return (u_char
*)&long_ret
;
1317 case LLDP_SNMP_DOT1_PVID
:
1318 long_ret
= port
->p_pvid
;
1319 return (u_char
*)&long_ret
;
1327 agent_h_remote_port(struct variable
*vp
, oid
*name
, size_t *length
,
1328 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1330 struct lldpd_port
*port
;
1333 if ((port
= header_tprindexed_table(vp
, name
, length
,
1334 exact
, var_len
, write_method
, 0)) == NULL
)
1337 if ((a
= agent_v_port(vp
, var_len
, port
)) != NULL
)
1339 TRYNEXT(agent_h_remote_port
);
1342 agent_h_local_port(struct variable
*vp
, oid
*name
, size_t *length
,
1343 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1345 struct lldpd_hardware
*hardware
;
1348 if ((hardware
= header_portindexed_table(vp
, name
, length
,
1349 exact
, var_len
, write_method
)) == NULL
)
1352 if ((a
= agent_v_port(vp
, var_len
, &hardware
->h_lport
)) != NULL
)
1354 TRYNEXT(agent_h_local_port
);
1358 agent_v_management(struct variable
*vp
, size_t *var_len
, struct lldpd_mgmt
*mgmt
)
1360 static unsigned long int long_ret
;
1361 static oid zeroDotZero
[2] = {0, 0};
1363 switch (vp
->magic
) {
1364 case LLDP_SNMP_ADDR_LEN
:
1365 long_ret
= mgmt
->m_addrsize
+ 1;
1366 return (u_char
*)&long_ret
;
1367 case LLDP_SNMP_ADDR_IFSUBTYPE
:
1368 if (mgmt
->m_iface
!= 0)
1369 long_ret
= LLDP_MGMT_IFACE_IFINDEX
;
1372 return (u_char
*)&long_ret
;
1373 case LLDP_SNMP_ADDR_IFID
:
1374 long_ret
= mgmt
->m_iface
;
1375 return (u_char
*)&long_ret
;
1376 case LLDP_SNMP_ADDR_OID
:
1377 *var_len
= sizeof(zeroDotZero
);
1378 return (u_char
*)zeroDotZero
;
1385 agent_h_local_management(struct variable
*vp
, oid
*name
, size_t *length
,
1386 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1389 struct lldpd_mgmt
*mgmt
;
1391 if ((mgmt
= header_ipindexed_table(vp
, name
, length
,
1392 exact
, var_len
, write_method
)) == NULL
)
1395 return agent_v_management(vp
, var_len
, mgmt
);
1398 agent_h_remote_management(struct variable
*vp
, oid
*name
, size_t *length
,
1399 int exact
, size_t *var_len
, WriteMethod
**write_method
)
1401 struct lldpd_mgmt
*mgmt
;
1403 if ((mgmt
= header_tpripindexed_table(vp
, name
, length
,
1404 exact
, var_len
, write_method
)) == NULL
)
1407 return agent_v_management(vp
, var_len
, mgmt
);
1411 Here is how it works: a agent_h_*() function will handle incoming
1412 requests. It will use an appropriate header_*indexed_table()
1413 function to grab the appropriate structure that was queried (a port,
1414 a chassis, ...). It will then delegate to a agent_v_*() function the
1415 responsability to extract the appropriate answer.
1417 agent_h_*() functions and header_*indexed_table() are not shared
1418 between remote and not remote version while agent_v_*() functions
1419 are the same for both version.
1422 /* For testing purposes, keep this structure ordered by increasing OID! */
1423 struct variable8 agent_lldp_vars
[] = {
1425 {LLDP_SNMP_TXINTERVAL
, ASN_INTEGER
, RONLY
, agent_h_scalars
, 3, {1, 1, 1}},
1426 {LLDP_SNMP_TXMULTIPLIER
, ASN_INTEGER
, RONLY
, agent_h_scalars
, 3, {1, 1, 2}},
1427 {LLDP_SNMP_REINITDELAY
, ASN_INTEGER
, RONLY
, agent_h_scalars
, 3, {1, 1, 3}},
1428 {LLDP_SNMP_TXDELAY
, ASN_INTEGER
, RONLY
, agent_h_scalars
, 3, {1, 1, 4}},
1429 {LLDP_SNMP_NOTIFICATION
, ASN_INTEGER
, RONLY
, agent_h_scalars
, 3, {1, 1, 5}},
1430 {LLDP_SNMP_LASTUPDATE
, ASN_TIMETICKS
, RONLY
, agent_h_scalars
, 3, {1, 2, 1}},
1431 {LLDP_SNMP_STATS_INSERTS
, ASN_GAUGE
, RONLY
, agent_h_scalars
, 3, {1, 2, 2}},
1432 {LLDP_SNMP_STATS_DELETES
, ASN_GAUGE
, RONLY
, agent_h_scalars
, 3, {1, 2, 3}},
1433 {LLDP_SNMP_STATS_DROPS
, ASN_GAUGE
, RONLY
, agent_h_scalars
, 3, {1, 2, 4}},
1434 {LLDP_SNMP_STATS_AGEOUTS
, ASN_GAUGE
, RONLY
, agent_h_scalars
, 3, {1, 2, 5}},
1436 {LLDP_SNMP_STATS_TX
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5, {1, 2, 6, 1, 2}},
1437 {LLDP_SNMP_STATS_RX_DISCARDED
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5, {1, 2, 7, 1, 2}},
1438 {LLDP_SNMP_STATS_RX_ERRORS
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5, {1, 2, 7, 1, 3}},
1439 {LLDP_SNMP_STATS_RX
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5, {1, 2, 7, 1, 4}},
1440 {LLDP_SNMP_STATS_RX_TLVDISCARDED
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5, {1, 2, 7, 1, 5}},
1441 {LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED
, ASN_COUNTER
, RONLY
, agent_h_stats
, 5, {1, 2, 7, 1, 6}},
1442 {LLDP_SNMP_STATS_RX_AGEOUTS
, ASN_GAUGE
, RONLY
, agent_h_stats
, 5, {1, 2, 7, 1, 7}},
1444 {LLDP_SNMP_CIDSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_local_chassis
, 3, {1, 3, 1}},
1445 {LLDP_SNMP_CID
, ASN_OCTET_STR
, RONLY
, agent_h_local_chassis
, 3, {1, 3, 2}},
1446 {LLDP_SNMP_SYSNAME
, ASN_OCTET_STR
, RONLY
, agent_h_local_chassis
, 3, {1, 3, 3}},
1447 {LLDP_SNMP_SYSDESCR
, ASN_OCTET_STR
, RONLY
, agent_h_local_chassis
, 3, {1, 3, 4}},
1448 {LLDP_SNMP_SYSCAP_SUP
, ASN_OCTET_STR
, RONLY
, agent_h_local_chassis
, 3, {1, 3, 5}},
1449 {LLDP_SNMP_SYSCAP_ENA
, ASN_OCTET_STR
, RONLY
, agent_h_local_chassis
, 3, {1, 3, 6}},
1451 {LLDP_SNMP_PIDSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 5, {1, 3, 7, 1, 2}},
1452 {LLDP_SNMP_PID
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 5, {1, 3, 7, 1, 3}},
1453 {LLDP_SNMP_PORTDESC
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 5, {1, 3, 7, 1, 4}},
1454 /* Local management address */
1455 {LLDP_SNMP_ADDR_LEN
, ASN_INTEGER
, RONLY
, agent_h_local_management
, 5,
1457 {LLDP_SNMP_ADDR_IFSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_local_management
, 5,
1459 {LLDP_SNMP_ADDR_IFID
, ASN_INTEGER
, RONLY
, agent_h_local_management
, 5,
1461 {LLDP_SNMP_ADDR_OID
, ASN_OBJECT_ID
, RONLY
, agent_h_local_management
, 5,
1464 {LLDP_SNMP_CIDSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_remote_chassis
, 5, {1, 4, 1, 1, 4}},
1465 {LLDP_SNMP_CID
, ASN_OCTET_STR
, RONLY
, agent_h_remote_chassis
, 5, {1, 4, 1, 1, 5}},
1466 {LLDP_SNMP_PIDSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 5, {1, 4, 1, 1, 6}},
1467 {LLDP_SNMP_PID
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 5, {1, 4, 1, 1, 7}},
1468 {LLDP_SNMP_PORTDESC
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 5, {1, 4, 1, 1, 8}},
1469 {LLDP_SNMP_SYSNAME
, ASN_OCTET_STR
, RONLY
, agent_h_remote_chassis
, 5, {1, 4, 1, 1, 9}},
1470 {LLDP_SNMP_SYSDESCR
, ASN_OCTET_STR
, RONLY
, agent_h_remote_chassis
, 5, {1, 4, 1, 1, 10}},
1471 {LLDP_SNMP_SYSCAP_SUP
, ASN_OCTET_STR
, RONLY
, agent_h_remote_chassis
, 5, {1, 4, 1, 1, 11}},
1472 {LLDP_SNMP_SYSCAP_ENA
, ASN_OCTET_STR
, RONLY
, agent_h_remote_chassis
, 5, {1, 4, 1, 1, 12}},
1473 /* Remote management address */
1474 {LLDP_SNMP_ADDR_IFSUBTYPE
, ASN_INTEGER
, RONLY
, agent_h_remote_management
, 5,
1476 {LLDP_SNMP_ADDR_IFID
, ASN_INTEGER
, RONLY
, agent_h_remote_management
, 5,
1478 {LLDP_SNMP_ADDR_OID
, ASN_OBJECT_ID
, RONLY
, agent_h_remote_management
, 5,
1480 /* Dot3, local ports */
1482 {LLDP_SNMP_DOT3_AUTONEG_SUPPORT
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1483 {1, 5, 4623, 1, 2, 1, 1, 1}},
1484 {LLDP_SNMP_DOT3_AUTONEG_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1485 {1, 5, 4623, 1, 2, 1, 1, 2}},
1486 {LLDP_SNMP_DOT3_AUTONEG_ADVERTISED
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 8,
1487 {1, 5, 4623, 1, 2, 1, 1, 3}},
1488 {LLDP_SNMP_DOT3_AUTONEG_MAU
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1489 {1, 5, 4623, 1, 2, 1, 1, 4}},
1490 {LLDP_SNMP_DOT3_POWER_DEVICETYPE
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1491 {1, 5, 4623, 1, 2, 2, 1, 1}},
1492 {LLDP_SNMP_DOT3_POWER_SUPPORT
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1493 {1, 5, 4623, 1, 2, 2, 1, 2}},
1494 {LLDP_SNMP_DOT3_POWER_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1495 {1, 5, 4623, 1, 2, 2, 1, 3}},
1496 {LLDP_SNMP_DOT3_POWER_PAIRCONTROL
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1497 {1, 5, 4623, 1, 2, 2, 1, 4}},
1498 {LLDP_SNMP_DOT3_POWER_PAIRS
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1499 {1, 5, 4623, 1, 2, 2, 1, 5}},
1500 {LLDP_SNMP_DOT3_POWER_CLASS
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1501 {1, 5, 4623, 1, 2, 2, 1, 6}},
1502 {LLDP_SNMP_DOT3_POWER_TYPE
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 8,
1503 {1, 5, 4623, 1, 2, 2, 1, 7}},
1504 {LLDP_SNMP_DOT3_POWER_SOURCE
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 8,
1505 {1, 5, 4623, 1, 2, 2, 1, 8}},
1506 {LLDP_SNMP_DOT3_POWER_PRIORITY
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1507 {1, 5, 4623, 1, 2, 2, 1, 9}},
1508 {LLDP_SNMP_DOT3_POWER_REQUESTED
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1509 {1, 5, 4623, 1, 2, 2, 1, 10}},
1510 {LLDP_SNMP_DOT3_POWER_ALLOCATED
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1511 {1, 5, 4623, 1, 2, 2, 1, 11}},
1512 {LLDP_SNMP_DOT3_AGG_STATUS
, ASN_OCTET_STR
, RONLY
, agent_h_local_port
, 8,
1513 {1, 5, 4623, 1, 2, 3, 1, 1}},
1514 {LLDP_SNMP_DOT3_AGG_ID
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1515 {1, 5, 4623, 1, 2, 3, 1, 2}},
1516 {LLDP_SNMP_DOT3_MFS
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1517 {1, 5, 4623, 1, 2, 4, 1, 1}},
1519 /* Dot3, remote ports */
1521 {LLDP_SNMP_DOT3_AUTONEG_SUPPORT
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1522 {1, 5, 4623, 1, 3, 1, 1, 1}},
1523 {LLDP_SNMP_DOT3_AUTONEG_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1524 {1, 5, 4623, 1, 3, 1, 1, 2}},
1525 {LLDP_SNMP_DOT3_AUTONEG_ADVERTISED
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 8,
1526 {1, 5, 4623, 1, 3, 1, 1, 3}},
1527 {LLDP_SNMP_DOT3_AUTONEG_MAU
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1528 {1, 5, 4623, 1, 3, 1, 1, 4}},
1529 {LLDP_SNMP_DOT3_POWER_DEVICETYPE
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1530 {1, 5, 4623, 1, 3, 2, 1, 1}},
1531 {LLDP_SNMP_DOT3_POWER_SUPPORT
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1532 {1, 5, 4623, 1, 3, 2, 1, 2}},
1533 {LLDP_SNMP_DOT3_POWER_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1534 {1, 5, 4623, 1, 3, 2, 1, 3}},
1535 {LLDP_SNMP_DOT3_POWER_PAIRCONTROL
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1536 {1, 5, 4623, 1, 3, 2, 1, 4}},
1537 {LLDP_SNMP_DOT3_POWER_PAIRS
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1538 {1, 5, 4623, 1, 3, 2, 1, 5}},
1539 {LLDP_SNMP_DOT3_POWER_CLASS
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1540 {1, 5, 4623, 1, 3, 2, 1, 6}},
1541 {LLDP_SNMP_DOT3_POWER_TYPE
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 8,
1542 {1, 5, 4623, 1, 3, 2, 1, 7}},
1543 {LLDP_SNMP_DOT3_POWER_SOURCE
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 8,
1544 {1, 5, 4623, 1, 3, 2, 1, 8}},
1545 {LLDP_SNMP_DOT3_POWER_PRIORITY
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1546 {1, 5, 4623, 1, 3, 2, 1, 9}},
1547 {LLDP_SNMP_DOT3_POWER_REQUESTED
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1548 {1, 5, 4623, 1, 3, 2, 1, 10}},
1549 {LLDP_SNMP_DOT3_POWER_ALLOCATED
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1550 {1, 5, 4623, 1, 3, 2, 1, 11}},
1551 {LLDP_SNMP_DOT3_AGG_STATUS
, ASN_OCTET_STR
, RONLY
, agent_h_remote_port
, 8,
1552 {1, 5, 4623, 1, 3, 3, 1, 1}},
1553 {LLDP_SNMP_DOT3_AGG_ID
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1554 {1, 5, 4623, 1, 3, 3, 1, 2}},
1555 {LLDP_SNMP_DOT3_MFS
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1556 {1, 5, 4623, 1, 3, 4, 1, 1}},
1558 #ifdef ENABLE_LLDPMED
1559 /* LLDP-MED local */
1560 {LLDP_SNMP_MED_CLASS
, ASN_INTEGER
, RONLY
, agent_h_local_med
, 6,
1561 {1, 5, 4795, 1, 1, 1}},
1562 {LLDP_SNMP_MED_POLICY_VID
, ASN_INTEGER
, RONLY
, agent_h_local_med_policy
, 8,
1563 {1, 5, 4795, 1, 2, 1, 1, 2}},
1564 {LLDP_SNMP_MED_POLICY_PRIO
, ASN_INTEGER
, RONLY
, agent_h_local_med_policy
, 8,
1565 {1, 5, 4795, 1, 2, 1, 1, 3}},
1566 {LLDP_SNMP_MED_POLICY_DSCP
, ASN_INTEGER
, RONLY
, agent_h_local_med_policy
, 8,
1567 {1, 5, 4795, 1, 2, 1, 1, 4}},
1568 {LLDP_SNMP_MED_POLICY_UNKNOWN
, ASN_INTEGER
, RONLY
, agent_h_local_med_policy
, 8,
1569 {1, 5, 4795, 1, 2, 1, 1, 5}},
1570 {LLDP_SNMP_MED_POLICY_TAGGED
, ASN_INTEGER
, RONLY
, agent_h_local_med_policy
, 8,
1571 {1, 5, 4795, 1, 2, 1, 1, 6}},
1572 {LLDP_SNMP_MED_HW
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1573 {1, 5, 4795, 1, 2, 2}},
1574 {LLDP_SNMP_MED_FW
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1575 {1, 5, 4795, 1, 2, 3}},
1576 {LLDP_SNMP_MED_SW
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1577 {1, 5, 4795, 1, 2, 4}},
1578 {LLDP_SNMP_MED_SN
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1579 {1, 5, 4795, 1, 2, 5}},
1580 {LLDP_SNMP_MED_MANUF
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1581 {1, 5, 4795, 1, 2, 6}},
1582 {LLDP_SNMP_MED_MODEL
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1583 {1, 5, 4795, 1, 2, 7}},
1584 {LLDP_SNMP_MED_ASSET
, ASN_OCTET_STR
, RONLY
, agent_h_local_med
, 6,
1585 {1, 5, 4795, 1, 2, 8}},
1586 {LLDP_SNMP_MED_LOCATION
, ASN_OCTET_STR
, RONLY
, agent_h_local_med_location
, 8,
1587 {1, 5, 4795, 1, 2, 9, 1, 2}},
1588 {LLDP_SNMP_MED_POE_DEVICETYPE
, ASN_INTEGER
, RONLY
, agent_h_local_med_power
, 6,
1589 {1, 5, 4795, 1, 2, 10}},
1590 {LLDP_SNMP_MED_POE_PSE_POWERVAL
, ASN_GAUGE
, RONLY
, agent_h_local_med_power
, 8,
1591 {1, 5, 4795, 1, 2, 11, 1, 1}},
1592 {LLDP_SNMP_MED_POE_PSE_POWERPRIORITY
, ASN_INTEGER
, RONLY
, agent_h_local_med_power
, 8,
1593 {1, 5, 4795, 1, 2, 11, 1, 2}},
1594 {LLDP_SNMP_MED_POE_PSE_POWERSOURCE
, ASN_INTEGER
, RONLY
, agent_h_local_med_power
, 6,
1595 {1, 5, 4795, 1, 2, 12}},
1596 {LLDP_SNMP_MED_POE_PD_POWERVAL
, ASN_GAUGE
, RONLY
, agent_h_local_med_power
, 6,
1597 {1, 5, 4795, 1, 2, 13}},
1598 {LLDP_SNMP_MED_POE_PD_POWERSOURCE
, ASN_INTEGER
, RONLY
, agent_h_local_med_power
, 6,
1599 {1, 5, 4795, 1, 2, 14}},
1600 {LLDP_SNMP_MED_POE_PD_POWERPRIORITY
, ASN_INTEGER
, RONLY
, agent_h_local_med_power
, 6,
1601 {1, 5, 4795, 1, 2, 15}},
1602 /* LLDP-MED remote */
1603 {LLDP_SNMP_MED_CAP_AVAILABLE
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1604 {1, 5, 4795, 1, 3, 1, 1, 1}},
1605 {LLDP_SNMP_MED_CAP_ENABLED
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1606 {1, 5, 4795, 1, 3, 1, 1, 2}},
1607 {LLDP_SNMP_MED_CLASS
, ASN_INTEGER
, RONLY
, agent_h_remote_med
, 8,
1608 {1, 5, 4795, 1, 3, 1, 1, 3}},
1609 {LLDP_SNMP_MED_POLICY_VID
, ASN_INTEGER
, RONLY
, agent_h_remote_med_policy
, 8,
1610 {1, 5, 4795, 1, 3, 2, 1, 2}},
1611 {LLDP_SNMP_MED_POLICY_PRIO
, ASN_INTEGER
, RONLY
, agent_h_remote_med_policy
, 8,
1612 {1, 5, 4795, 1, 3, 2, 1, 3}},
1613 {LLDP_SNMP_MED_POLICY_DSCP
, ASN_INTEGER
, RONLY
, agent_h_remote_med_policy
, 8,
1614 {1, 5, 4795, 1, 3, 2, 1, 4}},
1615 {LLDP_SNMP_MED_POLICY_UNKNOWN
, ASN_INTEGER
, RONLY
, agent_h_remote_med_policy
, 8,
1616 {1, 5, 4795, 1, 3, 2, 1, 5}},
1617 {LLDP_SNMP_MED_POLICY_TAGGED
, ASN_INTEGER
, RONLY
, agent_h_remote_med_policy
, 8,
1618 {1, 5, 4795, 1, 3, 2, 1, 6}},
1619 {LLDP_SNMP_MED_HW
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1620 {1, 5, 4795, 1, 3, 3, 1, 1}},
1621 {LLDP_SNMP_MED_FW
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1622 {1, 5, 4795, 1, 3, 3, 1, 2}},
1623 {LLDP_SNMP_MED_SW
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1624 {1, 5, 4795, 1, 3, 3, 1, 3}},
1625 {LLDP_SNMP_MED_SN
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1626 {1, 5, 4795, 1, 3, 3, 1, 4}},
1627 {LLDP_SNMP_MED_MANUF
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1628 {1, 5, 4795, 1, 3, 3, 1, 5}},
1629 {LLDP_SNMP_MED_MODEL
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1630 {1, 5, 4795, 1, 3, 3, 1, 6}},
1631 {LLDP_SNMP_MED_ASSET
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med
, 8,
1632 {1, 5, 4795, 1, 3, 3, 1, 7}},
1633 {LLDP_SNMP_MED_LOCATION
, ASN_OCTET_STR
, RONLY
, agent_h_remote_med_location
, 8,
1634 {1, 5, 4795, 1, 3, 4, 1, 2}},
1635 {LLDP_SNMP_MED_POE_DEVICETYPE
, ASN_INTEGER
, RONLY
, agent_h_remote_med_power
, 8,
1636 {1, 5, 4795, 1, 3, 5, 1, 1}},
1637 {LLDP_SNMP_MED_POE_PSE_POWERVAL
, ASN_GAUGE
, RONLY
, agent_h_remote_med_power
, 8,
1638 {1, 5, 4795, 1, 3, 6, 1, 1}},
1639 {LLDP_SNMP_MED_POE_PSE_POWERSOURCE
, ASN_INTEGER
, RONLY
, agent_h_remote_med_power
, 8,
1640 {1, 5, 4795, 1, 3, 6, 1, 2}},
1641 {LLDP_SNMP_MED_POE_PSE_POWERPRIORITY
, ASN_INTEGER
, RONLY
, agent_h_remote_med_power
, 8,
1642 {1, 5, 4795, 1, 3, 6, 1, 3}},
1643 {LLDP_SNMP_MED_POE_PD_POWERVAL
, ASN_GAUGE
, RONLY
, agent_h_remote_med_power
, 8,
1644 {1, 5, 4795, 1, 3, 7, 1, 1}},
1645 {LLDP_SNMP_MED_POE_PD_POWERSOURCE
, ASN_INTEGER
, RONLY
, agent_h_remote_med_power
, 8,
1646 {1, 5, 4795, 1, 3, 7, 1, 2}},
1647 {LLDP_SNMP_MED_POE_PD_POWERPRIORITY
, ASN_INTEGER
, RONLY
, agent_h_remote_med_power
, 8,
1648 {1, 5, 4795, 1, 3, 7, 1, 3}},
1650 /* Dot1, local and remote ports */
1652 {LLDP_SNMP_DOT1_PVID
, ASN_INTEGER
, RONLY
, agent_h_local_port
, 8,
1653 {1, 5, 32962, 1, 2, 1, 1, 1}},
1654 {LLDP_SNMP_DOT1_PPVLAN_SUPPORTED
, ASN_INTEGER
, RONLY
, agent_h_local_ppvid
, 8,
1655 {1, 5, 32962, 1, 2, 2, 1, 2}},
1656 {LLDP_SNMP_DOT1_PPVLAN_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_local_ppvid
, 8,
1657 {1, 5, 32962, 1, 2, 2, 1, 3}},
1658 {LLDP_SNMP_DOT1_VLANNAME
, ASN_OCTET_STR
, RONLY
, agent_h_local_vlan
, 8,
1659 {1, 5, 32962, 1, 2, 3, 1, 2}},
1660 {LLDP_SNMP_DOT1_PI
, ASN_OCTET_STR
, RONLY
, agent_h_local_pi
, 8,
1661 {1, 5, 32962, 1, 2, 4, 1, 2}},
1664 {LLDP_SNMP_DOT1_PVID
, ASN_INTEGER
, RONLY
, agent_h_remote_port
, 8,
1665 {1, 5, 32962, 1, 3, 1, 1, 1}},
1666 {LLDP_SNMP_DOT1_PPVLAN_SUPPORTED
, ASN_INTEGER
, RONLY
, agent_h_remote_ppvid
, 8,
1667 {1, 5, 32962, 1, 3, 2, 1, 2}},
1668 {LLDP_SNMP_DOT1_PPVLAN_ENABLED
, ASN_INTEGER
, RONLY
, agent_h_remote_ppvid
, 8,
1669 {1, 5, 32962, 1, 3, 2, 1, 3}},
1671 {LLDP_SNMP_DOT1_VLANNAME
, ASN_OCTET_STR
, RONLY
, agent_h_remote_vlan
, 8,
1672 {1, 5, 32962, 1, 3, 3, 1, 2}},
1673 /* Protocol identity */
1674 {LLDP_SNMP_DOT1_PI
, ASN_OCTET_STR
, RONLY
, agent_h_remote_pi
, 8,
1675 {1, 5, 32962, 1, 3, 4, 1, 2}},
1678 size_t agent_lldp_vars_size(void) {
1679 return sizeof(agent_lldp_vars
)/sizeof(struct variable8
);
1683 * Send a notification about a change in one remote neighbor.
1685 * @param hardware Interface on which the change has happened.
1686 * @param type Type of change (add, delete, update)
1687 * @param rport Changed remote port
1690 agent_notify(struct lldpd_hardware
*hardware
, int type
,
1691 struct lldpd_port
*rport
)
1693 struct lldpd_hardware
*h
;
1695 /* OID of the notification */
1696 oid notification_oid
[] = { LLDP_OID
, 0, 0, 1 };
1697 size_t notification_oid_len
= OID_LENGTH(notification_oid
);
1698 /* OID for snmpTrapOID.0 */
1699 oid objid_snmptrap
[] = { SNMPTRAP_OID
};
1700 size_t objid_snmptrap_len
= OID_LENGTH(objid_snmptrap
);
1703 oid inserts_oid
[] = { LLDP_OID
, 1, 2, 2 };
1704 size_t inserts_oid_len
= OID_LENGTH(inserts_oid
);
1705 unsigned long inserts
= 0;
1707 oid deletes_oid
[] = { LLDP_OID
, 1, 2, 3 };
1708 size_t deletes_oid_len
= OID_LENGTH(deletes_oid
);
1709 unsigned long deletes
= 0;
1711 oid drops_oid
[] = { LLDP_OID
, 1, 2, 4 };
1712 size_t drops_oid_len
= OID_LENGTH(drops_oid
);
1713 unsigned long drops
= 0;
1715 oid ageouts_oid
[] = { LLDP_OID
, 1, 2, 5 };
1716 size_t ageouts_oid_len
= OID_LENGTH(ageouts_oid
);
1717 unsigned long ageouts
= 0;
1719 /* We also add some extra. Easy ones. */
1720 oid locport_oid
[] = { LLDP_OID
, 1, 3, 7, 1, 4,
1721 hardware
->h_ifindex
};
1722 size_t locport_oid_len
= OID_LENGTH(locport_oid
);
1723 oid sysname_oid
[] = { LLDP_OID
, 1, 4, 1, 1, 9,
1724 lastchange(rport
), hardware
->h_ifindex
,
1725 rport
->p_chassis
->c_index
};
1726 size_t sysname_oid_len
= OID_LENGTH(sysname_oid
);
1727 oid portdescr_oid
[] = { LLDP_OID
, 1, 4, 1, 1, 8,
1728 lastchange(rport
), hardware
->h_ifindex
,
1729 rport
->p_chassis
->c_index
};
1730 size_t portdescr_oid_len
= OID_LENGTH(portdescr_oid
);
1732 netsnmp_variable_list
*notification_vars
= NULL
;
1734 if (!hardware
->h_cfg
->g_snmp
) return;
1737 case NEIGHBOR_CHANGE_DELETED
:
1738 log_debug("snmp", "send notification for neighbor deleted on %s",
1739 hardware
->h_ifname
);
1741 case NEIGHBOR_CHANGE_UPDATED
:
1742 log_debug("snmp", "send notification for neighbor updated on %s",
1743 hardware
->h_ifname
);
1745 case NEIGHBOR_CHANGE_ADDED
:
1746 log_debug("snmp", "send notification for neighbor added on %s",
1747 hardware
->h_ifname
);
1751 TAILQ_FOREACH(h
, &hardware
->h_cfg
->g_hardware
, h_entries
) {
1752 inserts
+= h
->h_insert_cnt
;
1753 deletes
+= h
->h_delete_cnt
;
1754 ageouts
+= h
->h_ageout_cnt
;
1755 drops
+= h
->h_drop_cnt
;
1759 snmp_varlist_add_variable(¬ification_vars
,
1760 objid_snmptrap
, objid_snmptrap_len
,
1762 (u_char
*) notification_oid
,
1763 notification_oid_len
* sizeof(oid
));
1765 snmp_varlist_add_variable(¬ification_vars
,
1766 inserts_oid
, inserts_oid_len
,
1770 snmp_varlist_add_variable(¬ification_vars
,
1771 deletes_oid
, deletes_oid_len
,
1775 snmp_varlist_add_variable(¬ification_vars
,
1776 drops_oid
, drops_oid_len
,
1780 snmp_varlist_add_variable(¬ification_vars
,
1781 ageouts_oid
, ageouts_oid_len
,
1786 if (type
!= NEIGHBOR_CHANGE_DELETED
) {
1787 snmp_varlist_add_variable(¬ification_vars
,
1788 locport_oid
, locport_oid_len
,
1790 (u_char
*)hardware
->h_ifname
,
1791 strnlen(hardware
->h_ifname
, IFNAMSIZ
));
1792 if (rport
->p_chassis
->c_name
&& *rport
->p_chassis
->c_name
!= '\0') {
1793 snmp_varlist_add_variable(¬ification_vars
,
1794 sysname_oid
, sysname_oid_len
,
1796 (u_char
*)rport
->p_chassis
->c_name
,
1797 strlen(rport
->p_chassis
->c_name
));
1799 if (rport
->p_descr
) {
1800 snmp_varlist_add_variable(¬ification_vars
,
1801 portdescr_oid
, portdescr_oid_len
,
1803 (u_char
*)rport
->p_descr
,
1804 strlen(rport
->p_descr
));
1808 log_debug("snmp", "sending SNMP trap (%ld, %ld, %ld)",
1809 inserts
, deletes
, ageouts
);
1810 send_v2trap(notification_vars
);
1811 snmp_free_varbind(notification_vars
);
1815 /* Logging NetSNMP messages */
1817 agent_log_callback(int major
, int minor
,
1818 void *serverarg
, void *clientarg
) {
1819 struct snmp_log_message
*slm
= (struct snmp_log_message
*)serverarg
;
1820 char *msg
= strdup(slm
->msg
);
1821 (void)major
; (void)minor
; (void)clientarg
;
1823 if (msg
&& msg
[strlen(msg
)-1] == '\n') msg
[strlen(msg
)-1] = '\0';
1824 switch (slm
->priority
) {
1825 case LOG_EMERG
: log_warnx("libsnmp", "%s", msg
?msg
:slm
->msg
); break;
1826 case LOG_ALERT
: log_warnx("libsnmp", "%s", msg
?msg
:slm
->msg
); break;
1827 case LOG_CRIT
: log_warnx("libsnmp", "%s", msg
?msg
:slm
->msg
); break;
1828 case LOG_ERR
: log_warnx("libsnmp", "%s", msg
?msg
:slm
->msg
); break;
1829 case LOG_WARNING
: log_warnx("libsnmp", "%s", msg
?msg
:slm
->msg
); break;
1830 case LOG_NOTICE
: log_info ("libsnmp", "%s", msg
?msg
:slm
->msg
); break;
1831 case LOG_INFO
: log_info ("libsnmp", "%s", msg
?msg
:slm
->msg
); break;
1832 case LOG_DEBUG
: log_debug("libsnmp", "%s", msg
?msg
:slm
->msg
); break;
1835 return SNMP_ERR_NOERROR
;
1839 agent_init(struct lldpd
*cfg
, const char *agentx
)
1843 log_info("snmp", "enable SNMP subagent");
1844 netsnmp_enable_subagent();
1846 log_debug("snmp", "enable logging");
1848 snmp_enable_calllog();
1849 snmp_register_callback(SNMP_CALLBACK_LIBRARY
,
1850 SNMP_CALLBACK_LOGGING
,
1856 /* We are chrooted, we don't want to handle persistent states */
1857 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID
,
1858 NETSNMP_DS_LIB_DONT_PERSIST_STATE
, TRUE
);
1859 /* Do not load any MIB */
1860 setenv("MIBS", "", 1);
1861 setenv("MIBDIRS", "/dev/null", 1);
1863 #ifdef ENABLE_PRIVSEP
1864 /* We provide our UNIX domain transport */
1865 log_debug("snmp", "register UNIX domain transport");
1866 agent_priv_register_domain();
1870 netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID
,
1871 NETSNMP_DS_AGENT_X_SOCKET
, agentx
);
1872 init_agent("lldpAgent");
1873 REGISTER_MIB("lldp", agent_lldp_vars
, variable8
, lldp_oid
);
1874 init_snmp("lldpAgent");
1876 log_debug("snmp", "register to sysORTable");
1877 if ((rc
= register_sysORTable(lldp_oid
, OID_LENGTH(lldp_oid
),
1878 "lldpMIB implementation by lldpd")) != 0)
1879 log_warnx("snmp", "unable to register to sysORTable (%d)", rc
);
1885 log_debug("snmp", "agent shutdown");
1886 unregister_sysORTable(lldp_oid
, OID_LENGTH(lldp_oid
));
1887 snmp_shutdown("lldpAgent");