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