]> git.ipfire.org Git - thirdparty/lldpd.git/blob - src/agent.c
47eeac85b291960dfdb4c54a2debb081c0450c7e
[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_DOT3_POWER_DEVICETYPE 12
405 #define LLDP_SNMP_LOCAL_DOT3_POWER_SUPPORT 13
406 #define LLDP_SNMP_LOCAL_DOT3_POWER_ENABLED 14
407 #define LLDP_SNMP_LOCAL_DOT3_POWER_PAIRCONTROL 15
408 #define LLDP_SNMP_LOCAL_DOT3_POWER_PAIRS 16
409 #define LLDP_SNMP_LOCAL_DOT3_POWER_CLASS 17
410 #define LLDP_SNMP_LOCAL_DOT3_POWER_TYPE 18
411 #define LLDP_SNMP_LOCAL_DOT3_POWER_SOURCE 19
412 #define LLDP_SNMP_LOCAL_DOT3_POWER_PRIORITY 20
413 #define LLDP_SNMP_LOCAL_DOT3_POWER_REQUESTED 21
414 #define LLDP_SNMP_LOCAL_DOT3_POWER_ALLOCATED 22
415 #define LLDP_SNMP_LOCAL_DOT1_PVID 23
416 /* Remote ports */
417 #define LLDP_SNMP_REMOTE_CIDSUBTYPE 1
418 #define LLDP_SNMP_REMOTE_CID 2
419 #define LLDP_SNMP_REMOTE_PIDSUBTYPE 3
420 #define LLDP_SNMP_REMOTE_PID 4
421 #define LLDP_SNMP_REMOTE_PORTDESC 5
422 #define LLDP_SNMP_REMOTE_SYSNAME 6
423 #define LLDP_SNMP_REMOTE_SYSDESC 7
424 #define LLDP_SNMP_REMOTE_SYSCAP_SUP 8
425 #define LLDP_SNMP_REMOTE_SYSCAP_ENA 9
426 #define LLDP_SNMP_REMOTE_DOT3_AUTONEG_SUPPORT 10
427 #define LLDP_SNMP_REMOTE_DOT3_AUTONEG_ENABLED 11
428 #define LLDP_SNMP_REMOTE_DOT3_AUTONEG_ADVERTISED 12
429 #define LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU 13
430 #define LLDP_SNMP_REMOTE_DOT3_AGG_STATUS 14
431 #define LLDP_SNMP_REMOTE_DOT3_AGG_ID 15
432 #define LLDP_SNMP_REMOTE_DOT3_MFS 16
433 #define LLDP_SNMP_REMOTE_DOT3_POWER_DEVICETYPE 17
434 #define LLDP_SNMP_REMOTE_DOT3_POWER_SUPPORT 18
435 #define LLDP_SNMP_REMOTE_DOT3_POWER_ENABLED 19
436 #define LLDP_SNMP_REMOTE_DOT3_POWER_PAIRCONTROL 20
437 #define LLDP_SNMP_REMOTE_DOT3_POWER_PAIRS 21
438 #define LLDP_SNMP_REMOTE_DOT3_POWER_CLASS 22
439 #define LLDP_SNMP_REMOTE_DOT3_POWER_TYPE 23
440 #define LLDP_SNMP_REMOTE_DOT3_POWER_SOURCE 24
441 #define LLDP_SNMP_REMOTE_DOT3_POWER_PRIORITY 25
442 #define LLDP_SNMP_REMOTE_DOT3_POWER_REQUESTED 26
443 #define LLDP_SNMP_REMOTE_DOT3_POWER_ALLOCATED 27
444 #define LLDP_SNMP_REMOTE_DOT1_PVID 28
445 /* Local vlans */
446 #define LLDP_SNMP_LOCAL_DOT1_VLANNAME 1
447 /* Remote vlans */
448 #define LLDP_SNMP_REMOTE_DOT1_VLANNAME 1
449 /* Management address */
450 #define LLDP_SNMP_LOCAL_ADDR_LEN 1
451 #define LLDP_SNMP_LOCAL_ADDR_IFSUBTYPE 2
452 #define LLDP_SNMP_LOCAL_ADDR_IFID 3
453 #define LLDP_SNMP_LOCAL_ADDR_OID 4
454 #define LLDP_SNMP_REMOTE_ADDR_IFSUBTYPE 5
455 #define LLDP_SNMP_REMOTE_ADDR_IFID 6
456 #define LLDP_SNMP_REMOTE_ADDR_OID 7
457 /* LLDP-MED local */
458 #define LLDP_SNMP_MED_LOCAL_CLASS 1
459 #define LLDP_SNMP_MED_LOCAL_HW 2
460 #define LLDP_SNMP_MED_LOCAL_FW 3
461 #define LLDP_SNMP_MED_LOCAL_SW 4
462 #define LLDP_SNMP_MED_LOCAL_SN 5
463 #define LLDP_SNMP_MED_LOCAL_MANUF 6
464 #define LLDP_SNMP_MED_LOCAL_MODEL 7
465 #define LLDP_SNMP_MED_LOCAL_ASSET 8
466 #define LLDP_SNMP_MED_LOCAL_POLICY_VID 9
467 #define LLDP_SNMP_MED_LOCAL_POLICY_PRIO 10
468 #define LLDP_SNMP_MED_LOCAL_POLICY_DSCP 11
469 #define LLDP_SNMP_MED_LOCAL_POLICY_UNKNOWN 12
470 #define LLDP_SNMP_MED_LOCAL_POLICY_TAGGED 13
471 #define LLDP_SNMP_MED_LOCAL_LOCATION 14
472 /* No more than 17 since we reuse LLDP_SNMP_MED_POE_DEVICETYPE and above */
473 /* LLDP-MED remote */
474 #define LLDP_SNMP_MED_REMOTE_CAP_AVAILABLE 1
475 #define LLDP_SNMP_MED_REMOTE_CAP_ENABLED 2
476 #define LLDP_SNMP_MED_REMOTE_CLASS 3
477 #define LLDP_SNMP_MED_REMOTE_HW 4
478 #define LLDP_SNMP_MED_REMOTE_FW 5
479 #define LLDP_SNMP_MED_REMOTE_SW 6
480 #define LLDP_SNMP_MED_REMOTE_SN 7
481 #define LLDP_SNMP_MED_REMOTE_MANUF 8
482 #define LLDP_SNMP_MED_REMOTE_MODEL 9
483 #define LLDP_SNMP_MED_REMOTE_ASSET 10
484 #define LLDP_SNMP_MED_REMOTE_POLICY_VID 11
485 #define LLDP_SNMP_MED_REMOTE_POLICY_PRIO 12
486 #define LLDP_SNMP_MED_REMOTE_POLICY_DSCP 13
487 #define LLDP_SNMP_MED_REMOTE_POLICY_UNKNOWN 14
488 #define LLDP_SNMP_MED_REMOTE_POLICY_TAGGED 15
489 #define LLDP_SNMP_MED_REMOTE_LOCATION 16
490 #define LLDP_SNMP_MED_POE_DEVICETYPE 17
491 #define LLDP_SNMP_MED_POE_PSE_POWERVAL 19
492 #define LLDP_SNMP_MED_POE_PSE_POWERSOURCE 20
493 #define LLDP_SNMP_MED_POE_PSE_POWERPRIORITY 21
494 #define LLDP_SNMP_MED_POE_PD_POWERVAL 22
495 #define LLDP_SNMP_MED_POE_PD_POWERSOURCE 23
496 #define LLDP_SNMP_MED_POE_PD_POWERPRIORITY 24
497
498 static u_char*
499 agent_h_scalars(struct variable *vp, oid *name, size_t *length,
500 int exact, size_t *var_len, WriteMethod **write_method)
501 {
502 static unsigned long long_ret;
503 struct lldpd_hardware *hardware;
504 struct lldpd_port *port;
505
506 if (header_generic(vp, name, length, exact, var_len, write_method))
507 return NULL;
508
509 switch (vp->magic) {
510 case LLDP_SNMP_TXINTERVAL:
511 long_ret = scfg->g_delay;
512 return (u_char *)&long_ret;
513 case LLDP_SNMP_TXMULTIPLIER:
514 long_ret = LOCAL_CHASSIS(scfg)->c_ttl / scfg->g_delay;
515 return (u_char *)&long_ret;
516 case LLDP_SNMP_REINITDELAY:
517 long_ret = 1;
518 return (u_char *)&long_ret;
519 case LLDP_SNMP_TXDELAY:
520 long_ret = LLDPD_TX_MSGDELAY;
521 return (u_char *)&long_ret;
522 case LLDP_SNMP_NOTIFICATION:
523 long_ret = 5;
524 return (u_char *)&long_ret;
525 case LLDP_SNMP_LASTUPDATE:
526 long_ret = 0;
527 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries)
528 TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
529 if (SMART_HIDDEN(scfg, port)) continue;
530 if (port->p_lastchange > long_ret)
531 long_ret = port->p_lastchange;
532 }
533 if (long_ret)
534 long_ret = (long_ret - starttime.tv_sec) * 100;
535 return (u_char *)&long_ret;
536 case LLDP_SNMP_STATS_INSERTS:
537 /* We assume this is equal to valid frames received on all ports */
538 long_ret = 0;
539 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries)
540 long_ret += hardware->h_rx_cnt;
541 return (u_char *)&long_ret;
542 case LLDP_SNMP_STATS_AGEOUTS:
543 long_ret = 0;
544 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries)
545 long_ret += hardware->h_rx_ageout_cnt;
546 return (u_char *)&long_ret;
547 case LLDP_SNMP_STATS_DELETES:
548 long_ret = 0;
549 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries)
550 long_ret += hardware->h_rx_ageout_cnt +
551 hardware->h_rx_cnt?(hardware->h_rx_cnt - 1):0;
552 return (u_char *)&long_ret;
553 case LLDP_SNMP_STATS_DROPS:
554 /* We assume that we never have insufficient resources */
555 long_ret = 0;
556 return (u_char *)&long_ret;
557 default:
558 break;
559 }
560 return NULL;
561 }
562
563 #ifdef ENABLE_LLDPMED
564 static unsigned long
565 agent_h_med_power(struct variable *vp, struct lldpd_med_power *power)
566 {
567 unsigned long long_ret;
568
569 switch (vp->magic) {
570 case LLDP_SNMP_MED_POE_DEVICETYPE:
571 switch (power->devicetype) {
572 case LLDPMED_POW_TYPE_PSE:
573 long_ret = 2; break;
574 case LLDPMED_POW_TYPE_PD:
575 long_ret = 3; break;
576 case 0:
577 long_ret = 4; break;
578 default:
579 long_ret = 1;
580 }
581 return long_ret;
582 case LLDP_SNMP_MED_POE_PSE_POWERVAL:
583 case LLDP_SNMP_MED_POE_PD_POWERVAL:
584 if (((vp->magic == LLDP_SNMP_MED_POE_PSE_POWERVAL) &&
585 (power->devicetype ==
586 LLDPMED_POW_TYPE_PSE)) ||
587 ((vp->magic == LLDP_SNMP_MED_POE_PD_POWERVAL) &&
588 (power->devicetype ==
589 LLDPMED_POW_TYPE_PD))) {
590 long_ret = power->val;
591 return long_ret;
592 }
593 break;
594 case LLDP_SNMP_MED_POE_PSE_POWERSOURCE:
595 if (power->devicetype ==
596 LLDPMED_POW_TYPE_PSE) {
597 switch (power->source) {
598 case LLDPMED_POW_SOURCE_PRIMARY:
599 long_ret = 2; break;
600 case LLDPMED_POW_SOURCE_BACKUP:
601 long_ret = 3; break;
602 default:
603 long_ret = 1;
604 }
605 return long_ret;
606 }
607 break;
608 case LLDP_SNMP_MED_POE_PD_POWERSOURCE:
609 if (power->devicetype ==
610 LLDPMED_POW_TYPE_PD) {
611 switch (power->source) {
612 case LLDPMED_POW_SOURCE_PSE:
613 long_ret = 2; break;
614 case LLDPMED_POW_SOURCE_LOCAL:
615 long_ret = 3; break;
616 case LLDPMED_POW_SOURCE_BOTH:
617 long_ret = 4; break;
618 default:
619 long_ret = 1;
620 }
621 return long_ret;
622 }
623 break;
624 case LLDP_SNMP_MED_POE_PSE_POWERPRIORITY:
625 case LLDP_SNMP_MED_POE_PD_POWERPRIORITY:
626 if (((vp->magic == LLDP_SNMP_MED_POE_PSE_POWERPRIORITY) &&
627 (power->devicetype ==
628 LLDPMED_POW_TYPE_PSE)) ||
629 ((vp->magic == LLDP_SNMP_MED_POE_PD_POWERPRIORITY) &&
630 (power->devicetype ==
631 LLDPMED_POW_TYPE_PD))) {
632 switch (power->priority) {
633 case LLDPMED_POW_PRIO_CRITICAL:
634 long_ret = 2; break;
635 case LLDPMED_POW_PRIO_HIGH:
636 long_ret = 3; break;
637 case LLDPMED_POW_PRIO_LOW:
638 long_ret = 4; break;
639 default:
640 long_ret = 1;
641 }
642 return long_ret;
643 }
644 break;
645 }
646
647 return (unsigned long)-1;
648 }
649
650 static u_char*
651 agent_h_local_med(struct variable *vp, oid *name, size_t *length,
652 int exact, size_t *var_len, WriteMethod **write_method)
653 {
654 static unsigned long long_ret;
655 struct lldpd_hardware *hardware;
656 struct lldpd_med_power *power;
657 int pse;
658
659 if (!LOCAL_CHASSIS(scfg)->c_med_cap_available)
660 return NULL;
661
662 if (header_generic(vp, name, length, exact, var_len, write_method))
663 return NULL;
664
665 switch (vp->magic) {
666 case LLDP_SNMP_MED_LOCAL_CLASS:
667 long_ret = LOCAL_CHASSIS(scfg)->c_med_type;
668 return (u_char *)&long_ret;
669 case LLDP_SNMP_MED_POE_DEVICETYPE:
670 case LLDP_SNMP_MED_POE_PSE_POWERSOURCE:
671 case LLDP_SNMP_MED_POE_PD_POWERVAL:
672 case LLDP_SNMP_MED_POE_PD_POWERSOURCE:
673 case LLDP_SNMP_MED_POE_PD_POWERPRIORITY:
674 /* LLDP-MED requires only one device type for all
675 ports. Moreover, a PSE can only have one power source. At
676 least, all PD values are global and not per-port. We try to
677 do our best. For device type, we decide on the number of
678 PD/PSE ports. */
679 pse = 0; power = NULL;
680 TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) {
681 if (hardware->h_lport.p_med_power.devicetype ==
682 LLDPMED_POW_TYPE_PSE) {
683 pse++;
684 if (pse == 1) /* Take this port as a reference */
685 power = &hardware->h_lport.p_med_power;
686 } else if (hardware->h_lport.p_med_power.devicetype ==
687 LLDPMED_POW_TYPE_PD) {
688 pse--;
689 if (pse == -1) /* Take this one instead */
690 power = &hardware->h_lport.p_med_power;
691 }
692 }
693 if (!power)
694 break; /* Neither PSE nor PD */
695 long_ret = agent_h_med_power(vp, power);
696 if (long_ret != (unsigned long)-1)
697 return (u_char *)&long_ret;
698 break;
699
700 #define LLDP_H_LOCAL_MED(magic, variable) \
701 case magic: \
702 if (LOCAL_CHASSIS(scfg)->variable) { \
703 *var_len = strlen( \
704 LOCAL_CHASSIS(scfg)->variable); \
705 return (u_char *)LOCAL_CHASSIS(scfg)->variable; \
706 } \
707 break
708
709 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_HW,
710 c_med_hw);
711 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_SW,
712 c_med_sw);
713 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_FW,
714 c_med_fw);
715 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_SN,
716 c_med_sn);
717 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_MANUF,
718 c_med_manuf);
719 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_MODEL,
720 c_med_model);
721 LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_ASSET,
722 c_med_asset);
723
724 default:
725 return NULL;
726 }
727 /* At this point, we seem to have hit an inventory variable that is not
728 * available, try to get the next one */
729 if (name[*length-1] < MAX_SUBID)
730 return agent_h_local_med(vp, name, length,
731 exact, var_len, write_method);
732 return NULL;
733 }
734
735 static u_char*
736 agent_h_local_med_policy(struct variable *vp, oid *name, size_t *length,
737 int exact, size_t *var_len, WriteMethod **write_method)
738 {
739 struct lldpd_med_policy *policy;
740 static unsigned long long_ret;
741
742 if ((policy = (struct lldpd_med_policy *)header_pmedindexed_table(vp, name, length,
743 exact, var_len, write_method, PMED_VARIANT_POLICY)) == NULL)
744 return NULL;
745
746 switch (vp->magic) {
747 case LLDP_SNMP_MED_LOCAL_POLICY_VID:
748 long_ret = policy->vid;
749 break;
750 case LLDP_SNMP_MED_LOCAL_POLICY_PRIO:
751 long_ret = policy->priority;
752 break;
753 case LLDP_SNMP_MED_LOCAL_POLICY_DSCP:
754 long_ret = policy->dscp;
755 break;
756 case LLDP_SNMP_MED_LOCAL_POLICY_UNKNOWN:
757 long_ret = policy->unknown?1:2;
758 break;
759 case LLDP_SNMP_MED_LOCAL_POLICY_TAGGED:
760 long_ret = policy->tagged?1:2;
761 break;
762 default:
763 return NULL;
764 }
765 return (u_char *)&long_ret;
766 }
767
768 static u_char*
769 agent_h_local_med_location(struct variable *vp, oid *name, size_t *length,
770 int exact, size_t *var_len, WriteMethod **write_method)
771 {
772 struct lldpd_med_loc *location;
773
774 if ((location = (struct lldpd_med_loc *)header_pmedindexed_table(vp, name, length,
775 exact, var_len, write_method, PMED_VARIANT_LOCATION)) == NULL)
776 return NULL;
777
778 switch (vp->magic) {
779 case LLDP_SNMP_MED_LOCAL_LOCATION:
780 *var_len = location->data_len;
781 return (u_char *)location->data;
782 }
783 return NULL;
784 }
785
786 static u_char*
787 agent_h_local_med_power(struct variable *vp, oid *name, size_t *length,
788 int exact, size_t *var_len, WriteMethod **write_method)
789 {
790 static unsigned long long_ret;
791 struct lldpd_hardware *hardware;
792
793 if ((hardware = header_portindexed_table(vp, name, length,
794 exact, var_len, write_method)) == NULL)
795 return NULL;
796 if (!hardware->h_lport.p_med_power.devicetype)
797 goto localpower_failed;
798
799 long_ret = agent_h_med_power(vp, &hardware->h_lport.p_med_power);
800 if (long_ret != (unsigned long)-1)
801 return (u_char *)&long_ret;
802
803 localpower_failed:
804 /* No valid data was found, we should try the next one! */
805 if (!exact && (name[*length-1] < MAX_SUBID))
806 return agent_h_local_med_power(vp, name, length,
807 exact, var_len, write_method);
808 return NULL;
809 }
810
811 static u_char*
812 agent_h_remote_med(struct variable *vp, oid *name, size_t *length,
813 int exact, size_t *var_len, WriteMethod **write_method)
814 {
815 struct lldpd_port *port;
816 static uint8_t bit;
817 static unsigned long long_ret;
818
819 if ((port = header_tprindexed_table(vp, name, length,
820 exact, var_len, write_method, TPR_VARIANT_NONE)) == NULL)
821 return NULL;
822
823 if (!port->p_chassis->c_med_cap_available) {
824 if (!exact && (name[*length-2] < MAX_SUBID))
825 name[*length-2]++;
826 goto remotemed_failed;
827 }
828
829 switch (vp->magic) {
830 case LLDP_SNMP_MED_REMOTE_CLASS:
831 long_ret = port->p_chassis->c_med_type;
832 return (u_char *)&long_ret;
833 case LLDP_SNMP_MED_REMOTE_CAP_AVAILABLE:
834 *var_len = 1;
835 bit = swap_bits(port->p_chassis->c_med_cap_available);
836 return (u_char *)&bit;
837 case LLDP_SNMP_MED_REMOTE_CAP_ENABLED:
838 *var_len = 1;
839 bit = swap_bits(port->p_med_cap_enabled);
840 return (u_char *)&bit;
841
842 case LLDP_SNMP_MED_POE_DEVICETYPE:
843 case LLDP_SNMP_MED_POE_PSE_POWERVAL:
844 case LLDP_SNMP_MED_POE_PD_POWERVAL:
845 case LLDP_SNMP_MED_POE_PSE_POWERSOURCE:
846 case LLDP_SNMP_MED_POE_PD_POWERSOURCE:
847 case LLDP_SNMP_MED_POE_PSE_POWERPRIORITY:
848 case LLDP_SNMP_MED_POE_PD_POWERPRIORITY:
849 long_ret = agent_h_med_power(vp, &port->p_med_power);
850 if (long_ret != (unsigned long)-1)
851 return (u_char *)&long_ret;
852 break;
853
854 #define LLDP_H_REMOTE_MED(magic, variable) \
855 case magic: \
856 if (port->p_chassis->variable) { \
857 *var_len = strlen( \
858 port->p_chassis->variable); \
859 return (u_char *) \
860 port->p_chassis->variable; \
861 } \
862 break
863
864 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_HW,
865 c_med_hw);
866 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_SW,
867 c_med_sw);
868 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_FW,
869 c_med_fw);
870 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_SN,
871 c_med_sn);
872 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_MANUF,
873 c_med_manuf);
874 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_MODEL,
875 c_med_model);
876 LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_ASSET,
877 c_med_asset);
878
879 default:
880 return NULL;
881 }
882 remotemed_failed:
883 /* No valid data was found, we should try the next one! */
884 if (!exact && (name[*length-1] < MAX_SUBID))
885 return agent_h_remote_med(vp, name, length,
886 exact, var_len, write_method);
887 return NULL;
888 }
889
890 static u_char*
891 agent_h_remote_med_policy(struct variable *vp, oid *name, size_t *length,
892 int exact, size_t *var_len, WriteMethod **write_method)
893 {
894 int type;
895 struct lldpd_port *port;
896 struct lldpd_med_policy *policy;
897 static unsigned long long_ret;
898
899 if ((port = header_tprindexed_table(vp, name, length,
900 exact, var_len, write_method, TPR_VARIANT_MED_POLICY)) == NULL)
901 return NULL;
902
903 if (!port->p_chassis->c_med_cap_available) {
904 if (!exact && (name[*length-2] < MAX_SUBID))
905 name[*length-2]++;
906 goto remotemedpolicy_failed;
907 }
908
909 type = name[*length - 1];
910 if ((type < 1) || (type > LLDPMED_APPTYPE_LAST))
911 goto remotemedpolicy_failed;
912 policy = &port->p_med_policy[type-1];
913 if (policy->type != type)
914 goto remotemedpolicy_failed;
915
916 switch (vp->magic) {
917 case LLDP_SNMP_MED_REMOTE_POLICY_VID:
918 long_ret = policy->vid;
919 return (u_char *)&long_ret;
920 case LLDP_SNMP_MED_REMOTE_POLICY_PRIO:
921 long_ret = policy->priority;
922 return (u_char *)&long_ret;
923 case LLDP_SNMP_MED_REMOTE_POLICY_DSCP:
924 long_ret = policy->dscp;
925 return (u_char *)&long_ret;
926 case LLDP_SNMP_MED_REMOTE_POLICY_UNKNOWN:
927 long_ret = policy->unknown?1:2;
928 return (u_char *)&long_ret;
929 case LLDP_SNMP_MED_REMOTE_POLICY_TAGGED:
930 long_ret = policy->tagged?1:2;
931 return (u_char *)&long_ret;
932 default:
933 return NULL;
934 }
935 remotemedpolicy_failed:
936 /* No valid data was found, we should try the next one! */
937 if (!exact && (name[*length-1] < MAX_SUBID))
938 return agent_h_remote_med_policy(vp, name, length,
939 exact, var_len, write_method);
940 return NULL;
941 }
942
943 static u_char*
944 agent_h_remote_med_location(struct variable *vp, oid *name, size_t *length,
945 int exact, size_t *var_len, WriteMethod **write_method)
946 {
947 int type;
948 struct lldpd_port *port;
949 struct lldpd_med_loc *location;
950
951 if ((port = header_tprindexed_table(vp, name, length,
952 exact, var_len, write_method, TPR_VARIANT_MED_LOCATION)) == NULL)
953 return NULL;
954
955 if (!port->p_chassis->c_med_cap_available) {
956 if (!exact && (name[*length-2] < MAX_SUBID))
957 name[*length-2]++;
958 goto remotemedlocation_failed;
959 }
960
961 type = name[*length - 1];
962 if ((type < 1) || (type > LLDPMED_APPTYPE_LAST))
963 goto remotemedlocation_failed;
964 location = &port->p_med_location[type-1];
965 if (location->format != type)
966 goto remotemedlocation_failed;
967
968 switch (vp->magic) {
969 case LLDP_SNMP_MED_REMOTE_LOCATION:
970 *var_len = location->data_len;
971 return (u_char *)location->data;
972 default:
973 return NULL;
974 }
975 remotemedlocation_failed:
976 /* No valid data was found, we should try the next one! */
977 if (!exact && (name[*length-1] < MAX_SUBID))
978 return agent_h_remote_med_location(vp, name, length,
979 exact, var_len, write_method);
980 return NULL;
981 }
982 #endif
983
984 static u_char*
985 agent_h_local_chassis(struct variable *vp, oid *name, size_t *length,
986 int exact, size_t *var_len, WriteMethod **write_method)
987 {
988 static uint8_t bit;
989 static unsigned long long_ret;
990
991 if (header_generic(vp, name, length, exact, var_len, write_method))
992 return NULL;
993
994 switch (vp->magic) {
995 case LLDP_SNMP_LOCAL_CIDSUBTYPE:
996 long_ret = LOCAL_CHASSIS(scfg)->c_id_subtype;
997 return (u_char *)&long_ret;
998 case LLDP_SNMP_LOCAL_CID:
999 *var_len = LOCAL_CHASSIS(scfg)->c_id_len;
1000 return (u_char *)LOCAL_CHASSIS(scfg)->c_id;
1001 case LLDP_SNMP_LOCAL_SYSNAME:
1002 *var_len = strlen(LOCAL_CHASSIS(scfg)->c_name);
1003 return (u_char *)LOCAL_CHASSIS(scfg)->c_name;
1004 case LLDP_SNMP_LOCAL_SYSDESCR:
1005 *var_len = strlen(LOCAL_CHASSIS(scfg)->c_descr);
1006 return (u_char *)LOCAL_CHASSIS(scfg)->c_descr;
1007 case LLDP_SNMP_LOCAL_SYSCAP_SUP:
1008 *var_len = 1;
1009 bit = swap_bits(LOCAL_CHASSIS(scfg)->c_cap_available);
1010 return (u_char *)&bit;
1011 case LLDP_SNMP_LOCAL_SYSCAP_ENA:
1012 *var_len = 1;
1013 bit = swap_bits(LOCAL_CHASSIS(scfg)->c_cap_enabled);
1014 return (u_char *)&bit;
1015 default:
1016 break;
1017 }
1018 return NULL;
1019 }
1020
1021 static u_char*
1022 agent_h_stats(struct variable *vp, oid *name, size_t *length,
1023 int exact, size_t *var_len, WriteMethod **write_method)
1024 {
1025 static unsigned long long_ret;
1026 struct lldpd_hardware *hardware;
1027
1028 if ((hardware = header_portindexed_table(vp, name, length,
1029 exact, var_len, write_method)) == NULL)
1030 return NULL;
1031
1032 switch (vp->magic) {
1033 case LLDP_SNMP_STATS_TX:
1034 long_ret = hardware->h_tx_cnt;
1035 return (u_char *)&long_ret;
1036 case LLDP_SNMP_STATS_RX:
1037 long_ret = hardware->h_rx_cnt;
1038 return (u_char *)&long_ret;
1039 case LLDP_SNMP_STATS_RX_DISCARDED:
1040 case LLDP_SNMP_STATS_RX_ERRORS:
1041 /* We discard only frame with errors. Therefore, the two values
1042 * are equal */
1043 long_ret = hardware->h_rx_discarded_cnt;
1044 return (u_char *)&long_ret;
1045 case LLDP_SNMP_STATS_RX_TLVDISCARDED:
1046 case LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED:
1047 /* We discard only unrecognized TLV. Malformed TLV
1048 implies dropping the whole frame */
1049 long_ret = hardware->h_rx_unrecognized_cnt;
1050 return (u_char *)&long_ret;
1051 case LLDP_SNMP_STATS_RX_AGEOUTS:
1052 long_ret = hardware->h_rx_ageout_cnt;
1053 return (u_char *)&long_ret;
1054 default:
1055 break;
1056 }
1057 return NULL;
1058 }
1059
1060 static u_char*
1061 agent_h_local_port(struct variable *vp, oid *name, size_t *length,
1062 int exact, size_t *var_len, WriteMethod **write_method)
1063 {
1064 #ifdef ENABLE_DOT3
1065 static uint8_t bit;
1066 #endif
1067 struct lldpd_hardware *hardware;
1068 static unsigned long long_ret;
1069
1070 if ((hardware = header_portindexed_table(vp, name, length,
1071 exact, var_len, write_method)) == NULL)
1072 return NULL;
1073
1074 switch (vp->magic) {
1075 case LLDP_SNMP_LOCAL_PIDSUBTYPE:
1076 long_ret = hardware->h_lport.p_id_subtype;
1077 return (u_char *)&long_ret;
1078 case LLDP_SNMP_LOCAL_PID:
1079 *var_len = hardware->h_lport.p_id_len;
1080 return (u_char *)hardware->h_lport.p_id;
1081 case LLDP_SNMP_LOCAL_PORTDESC:
1082 *var_len = strlen(hardware->h_lport.p_descr);
1083 return (u_char *)hardware->h_lport.p_descr;
1084 #ifdef ENABLE_DOT3
1085 case LLDP_SNMP_LOCAL_DOT3_AUTONEG_SUPPORT:
1086 long_ret = 2 - hardware->h_lport.p_macphy.autoneg_support;
1087 return (u_char *)&long_ret;
1088 case LLDP_SNMP_LOCAL_DOT3_AUTONEG_ENABLED:
1089 long_ret = 2 - hardware->h_lport.p_macphy.autoneg_enabled;
1090 return (u_char *)&long_ret;
1091 case LLDP_SNMP_LOCAL_DOT3_AUTONEG_ADVERTISED:
1092 *var_len = 2;
1093 return (u_char *)&hardware->h_lport.p_macphy.autoneg_advertised;
1094 case LLDP_SNMP_LOCAL_DOT3_AUTONEG_MAU:
1095 long_ret = hardware->h_lport.p_macphy.mau_type;
1096 return (u_char *)&long_ret;
1097 case LLDP_SNMP_LOCAL_DOT3_AGG_STATUS:
1098 bit = swap_bits((hardware->h_lport.p_aggregid > 0) ? 3 : 0);
1099 *var_len = 1;
1100 return (u_char *)&bit;
1101 case LLDP_SNMP_LOCAL_DOT3_AGG_ID:
1102 long_ret = hardware->h_lport.p_aggregid;
1103 return (u_char *)&long_ret;
1104 case LLDP_SNMP_LOCAL_DOT3_MFS:
1105 long_ret = hardware->h_lport.p_mfs;
1106 return (u_char *)&long_ret;
1107 case LLDP_SNMP_LOCAL_DOT3_POWER_DEVICETYPE:
1108 if (hardware->h_lport.p_power.devicetype) {
1109 long_ret = (hardware->h_lport.p_power.devicetype ==
1110 LLDP_DOT3_POWER_PSE)?1:2;
1111 return (u_char *)&long_ret;
1112 }
1113 break;
1114 case LLDP_SNMP_LOCAL_DOT3_POWER_SUPPORT:
1115 if (hardware->h_lport.p_power.devicetype) {
1116 long_ret = (hardware->h_lport.p_power.supported)?1:2;
1117 return (u_char *)&long_ret;
1118 }
1119 break;
1120 case LLDP_SNMP_LOCAL_DOT3_POWER_ENABLED:
1121 if (hardware->h_lport.p_power.devicetype) {
1122 long_ret = (hardware->h_lport.p_power.enabled)?1:2;
1123 return (u_char *)&long_ret;
1124 }
1125 break;
1126 case LLDP_SNMP_LOCAL_DOT3_POWER_PAIRCONTROL:
1127 if (hardware->h_lport.p_power.devicetype) {
1128 long_ret = (hardware->h_lport.p_power.paircontrol)?1:2;
1129 return (u_char *)&long_ret;
1130 }
1131 break;
1132 case LLDP_SNMP_LOCAL_DOT3_POWER_PAIRS:
1133 if (hardware->h_lport.p_power.devicetype) {
1134 long_ret = hardware->h_lport.p_power.pairs;
1135 return (u_char *)&long_ret;
1136 }
1137 break;
1138 case LLDP_SNMP_LOCAL_DOT3_POWER_CLASS:
1139 if (hardware->h_lport.p_power.devicetype && hardware->h_lport.p_power.class) {
1140 long_ret = hardware->h_lport.p_power.class;
1141 return (u_char *)&long_ret;
1142 }
1143 break;
1144 case LLDP_SNMP_LOCAL_DOT3_POWER_TYPE:
1145 if (hardware->h_lport.p_power.devicetype &&
1146 hardware->h_lport.p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) {
1147 *var_len = 1;
1148 bit = (((hardware->h_lport.p_power.powertype ==
1149 LLDP_DOT3_POWER_8023AT_TYPE1)?1:0) << 7) |
1150 (((hardware->h_lport.p_power.devicetype ==
1151 LLDP_DOT3_POWER_PSE)?0:1) << 6);
1152 return (u_char *)&bit;
1153 }
1154 break;
1155 case LLDP_SNMP_LOCAL_DOT3_POWER_SOURCE:
1156 if (hardware->h_lport.p_power.devicetype &&
1157 hardware->h_lport.p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) {
1158 *var_len = 1;
1159 bit = swap_bits(hardware->h_lport.p_power.source%(1<<2));
1160 return (u_char *)&bit;
1161 }
1162 break;
1163 case LLDP_SNMP_LOCAL_DOT3_POWER_PRIORITY:
1164 if (hardware->h_lport.p_power.devicetype &&
1165 hardware->h_lport.p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) {
1166 long_ret = hardware->h_lport.p_power.priority;
1167 return (u_char *)&long_ret;
1168 }
1169 break;
1170 case LLDP_SNMP_LOCAL_DOT3_POWER_REQUESTED:
1171 if (hardware->h_lport.p_power.devicetype &&
1172 hardware->h_lport.p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) {
1173 long_ret = hardware->h_lport.p_power.requested;
1174 return (u_char *)&long_ret;
1175 }
1176 break;
1177 case LLDP_SNMP_LOCAL_DOT3_POWER_ALLOCATED:
1178 if (hardware->h_lport.p_power.devicetype &&
1179 hardware->h_lport.p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) {
1180 long_ret = hardware->h_lport.p_power.allocated;
1181 return (u_char *)&long_ret;
1182 }
1183 break;
1184 #endif
1185 #ifdef ENABLE_DOT1
1186 case LLDP_SNMP_LOCAL_DOT1_PVID:
1187 long_ret = hardware->h_lport.p_pvid; /* Should always be 0 */
1188 return (u_char *)&long_ret;
1189 #endif
1190 default:
1191 break;
1192 }
1193 if (!exact && (name[*length-1] < MAX_SUBID))
1194 return agent_h_local_port(vp, name, length,
1195 exact, var_len, write_method);
1196 return NULL;
1197 }
1198
1199 #ifdef ENABLE_DOT1
1200 static u_char*
1201 agent_h_local_vlan(struct variable *vp, oid *name, size_t *length,
1202 int exact, size_t *var_len, WriteMethod **write_method)
1203 {
1204 struct lldpd_vlan *vlan;
1205
1206 if ((vlan = header_pvindexed_table(vp, name, length,
1207 exact, var_len, write_method)) == NULL)
1208 return NULL;
1209
1210 switch (vp->magic) {
1211 case LLDP_SNMP_LOCAL_DOT1_VLANNAME:
1212 *var_len = strlen(vlan->v_name);
1213 return (u_char *)vlan->v_name;
1214 default:
1215 break;
1216 }
1217 return NULL;
1218 }
1219
1220 static u_char*
1221 agent_h_remote_vlan(struct variable *vp, oid *name, size_t *length,
1222 int exact, size_t *var_len, WriteMethod **write_method)
1223 {
1224 struct lldpd_vlan *vlan;
1225
1226 if ((vlan = header_tprvindexed_table(vp, name, length,
1227 exact, var_len, write_method)) == NULL)
1228 return NULL;
1229
1230 switch (vp->magic) {
1231 case LLDP_SNMP_REMOTE_DOT1_VLANNAME:
1232 *var_len = strlen(vlan->v_name);
1233 return (u_char *)vlan->v_name;
1234 default:
1235 break;
1236 }
1237 return NULL;
1238 }
1239 #endif
1240
1241 static u_char*
1242 agent_h_remote_port(struct variable *vp, oid *name, size_t *length,
1243 int exact, size_t *var_len, WriteMethod **write_method)
1244 {
1245 struct lldpd_port *port;
1246 static uint8_t bit;
1247 static unsigned long long_ret;
1248
1249 if ((port = header_tprindexed_table(vp, name, length,
1250 exact, var_len, write_method, TPR_VARIANT_NONE)) == NULL)
1251 return NULL;
1252
1253 switch (vp->magic) {
1254 case LLDP_SNMP_REMOTE_CIDSUBTYPE:
1255 long_ret = port->p_chassis->c_id_subtype;
1256 return (u_char *)&long_ret;
1257 case LLDP_SNMP_REMOTE_CID:
1258 *var_len = port->p_chassis->c_id_len;
1259 return (u_char *)port->p_chassis->c_id;
1260 case LLDP_SNMP_REMOTE_PIDSUBTYPE:
1261 long_ret = port->p_id_subtype;
1262 return (u_char *)&long_ret;
1263 case LLDP_SNMP_REMOTE_PID:
1264 *var_len = port->p_id_len;
1265 return (u_char *)port->p_id;
1266 case LLDP_SNMP_REMOTE_PORTDESC:
1267 *var_len = strlen(port->p_descr);
1268 return (u_char *)port->p_descr;
1269 case LLDP_SNMP_REMOTE_SYSNAME:
1270 *var_len = strlen(port->p_chassis->c_name);
1271 return (u_char *)port->p_chassis->c_name;
1272 case LLDP_SNMP_REMOTE_SYSDESC:
1273 *var_len = strlen(port->p_chassis->c_descr);
1274 return (u_char *)port->p_chassis->c_descr;
1275 case LLDP_SNMP_REMOTE_SYSCAP_SUP:
1276 *var_len = 1;
1277 bit = swap_bits(port->p_chassis->c_cap_available);
1278 return (u_char *)&bit;
1279 case LLDP_SNMP_REMOTE_SYSCAP_ENA:
1280 *var_len = 1;
1281 bit = swap_bits(port->p_chassis->c_cap_enabled);
1282 return (u_char *)&bit;
1283 #ifdef ENABLE_DOT3
1284 case LLDP_SNMP_REMOTE_DOT3_AUTONEG_SUPPORT:
1285 long_ret = 2 - port->p_macphy.autoneg_support;
1286 return (u_char *)&long_ret;
1287 case LLDP_SNMP_REMOTE_DOT3_AUTONEG_ENABLED:
1288 long_ret = 2 - port->p_macphy.autoneg_enabled;
1289 return (u_char *)&long_ret;
1290 case LLDP_SNMP_REMOTE_DOT3_AUTONEG_ADVERTISED:
1291 *var_len = 2;
1292 return (u_char *)&port->p_macphy.autoneg_advertised;
1293 case LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU:
1294 long_ret = port->p_macphy.mau_type;
1295 return (u_char *)&long_ret;
1296 case LLDP_SNMP_REMOTE_DOT3_AGG_STATUS:
1297 bit = swap_bits((port->p_aggregid > 0) ? 3 : 0);
1298 *var_len = 1;
1299 return (u_char *)&bit;
1300 case LLDP_SNMP_REMOTE_DOT3_AGG_ID:
1301 long_ret = port->p_aggregid;
1302 return (u_char *)&long_ret;
1303 case LLDP_SNMP_REMOTE_DOT3_MFS:
1304 long_ret = port->p_mfs;
1305 return (u_char *)&long_ret;
1306 case LLDP_SNMP_REMOTE_DOT3_POWER_DEVICETYPE:
1307 if (port->p_power.devicetype) {
1308 long_ret = (port->p_power.devicetype == LLDP_DOT3_POWER_PSE)?1:2;
1309 return (u_char *)&long_ret;
1310 }
1311 break;
1312 case LLDP_SNMP_REMOTE_DOT3_POWER_SUPPORT:
1313 if (port->p_power.devicetype) {
1314 long_ret = (port->p_power.supported)?1:2;
1315 return (u_char *)&long_ret;
1316 }
1317 break;
1318 case LLDP_SNMP_REMOTE_DOT3_POWER_ENABLED:
1319 if (port->p_power.devicetype) {
1320 long_ret = (port->p_power.enabled)?1:2;
1321 return (u_char *)&long_ret;
1322 }
1323 break;
1324 case LLDP_SNMP_REMOTE_DOT3_POWER_PAIRCONTROL:
1325 if (port->p_power.devicetype) {
1326 long_ret = (port->p_power.paircontrol)?1:2;
1327 return (u_char *)&long_ret;
1328 }
1329 break;
1330 case LLDP_SNMP_REMOTE_DOT3_POWER_PAIRS:
1331 if (port->p_power.devicetype) {
1332 long_ret = port->p_power.pairs;
1333 return (u_char *)&long_ret;
1334 }
1335 break;
1336 case LLDP_SNMP_REMOTE_DOT3_POWER_CLASS:
1337 if (port->p_power.devicetype && port->p_power.class) {
1338 long_ret = port->p_power.class;
1339 return (u_char *)&long_ret;
1340 }
1341 break;
1342 case LLDP_SNMP_REMOTE_DOT3_POWER_TYPE:
1343 if (port->p_power.devicetype &&
1344 port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) {
1345 *var_len = 1;
1346 bit = (((port->p_power.powertype ==
1347 LLDP_DOT3_POWER_8023AT_TYPE1)?1:0) << 7) |
1348 (((port->p_power.devicetype ==
1349 LLDP_DOT3_POWER_PSE)?0:1) << 6);
1350 return (u_char *)&bit;
1351 }
1352 break;
1353 case LLDP_SNMP_REMOTE_DOT3_POWER_SOURCE:
1354 if (port->p_power.devicetype &&
1355 port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) {
1356 *var_len = 1;
1357 bit = swap_bits(port->p_power.source%(1<<2));
1358 return (u_char *)&bit;
1359 }
1360 break;
1361 case LLDP_SNMP_REMOTE_DOT3_POWER_PRIORITY:
1362 if (port->p_power.devicetype &&
1363 port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) {
1364 long_ret = port->p_power.priority;
1365 return (u_char *)&long_ret;
1366 }
1367 break;
1368 case LLDP_SNMP_REMOTE_DOT3_POWER_REQUESTED:
1369 if (port->p_power.devicetype &&
1370 port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) {
1371 long_ret = port->p_power.requested;
1372 return (u_char *)&long_ret;
1373 }
1374 break;
1375 case LLDP_SNMP_REMOTE_DOT3_POWER_ALLOCATED:
1376 if (port->p_power.devicetype &&
1377 port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) {
1378 long_ret = port->p_power.allocated;
1379 return (u_char *)&long_ret;
1380 }
1381 break;
1382 #endif
1383 #ifdef ENABLE_DOT1
1384 case LLDP_SNMP_REMOTE_DOT1_PVID:
1385 long_ret = port->p_pvid;
1386 return (u_char *)&long_ret;
1387 #endif
1388 default:
1389 break;
1390 }
1391 if (!exact && (name[*length-1] < MAX_SUBID))
1392 return agent_h_remote_port(vp, name, length,
1393 exact, var_len, write_method);
1394 return NULL;
1395 }
1396
1397 static u_char*
1398 agent_management(struct variable *vp, size_t *var_len, struct lldpd_chassis *chassis)
1399 {
1400 static unsigned long int long_ret;
1401 static oid zeroDotZero[2] = {0, 0};
1402
1403 switch (vp->magic) {
1404 case LLDP_SNMP_LOCAL_ADDR_LEN:
1405 long_ret = 5;
1406 return (u_char*)&long_ret;
1407 case LLDP_SNMP_LOCAL_ADDR_IFSUBTYPE:
1408 case LLDP_SNMP_REMOTE_ADDR_IFSUBTYPE:
1409 if (chassis->c_mgmt_if != 0)
1410 long_ret = LLDP_MGMT_IFACE_IFINDEX;
1411 else
1412 long_ret = 1;
1413 return (u_char*)&long_ret;
1414 case LLDP_SNMP_LOCAL_ADDR_IFID:
1415 case LLDP_SNMP_REMOTE_ADDR_IFID:
1416 long_ret = chassis->c_mgmt_if;
1417 return (u_char*)&long_ret;
1418 case LLDP_SNMP_LOCAL_ADDR_OID:
1419 case LLDP_SNMP_REMOTE_ADDR_OID:
1420 *var_len = sizeof(zeroDotZero);
1421 return (u_char*)zeroDotZero;
1422 default:
1423 break;
1424 }
1425 return NULL;
1426 }
1427
1428 static u_char*
1429 agent_h_local_management(struct variable *vp, oid *name, size_t *length,
1430 int exact, size_t *var_len, WriteMethod **write_method)
1431 {
1432 oid *target, best[6];
1433 int result, target_len;
1434
1435 if (LOCAL_CHASSIS(scfg)->c_mgmt.s_addr == INADDR_ANY)
1436 return NULL;
1437
1438 if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) {
1439 memcpy(name, vp->name, sizeof(oid) * vp->namelen);
1440 *length = vp->namelen;
1441 }
1442
1443 *write_method = 0;
1444 *var_len = sizeof(long);
1445
1446 target = &name[vp->namelen];
1447 target_len = *length - vp->namelen;
1448
1449 best[0] = 1;
1450 best[1] = 4;
1451 best[5] = LOCAL_CHASSIS(scfg)->c_mgmt.s_addr >> 24;
1452 best[4] = (LOCAL_CHASSIS(scfg)->c_mgmt.s_addr & 0xffffff) >> 16;
1453 best[3] = (LOCAL_CHASSIS(scfg)->c_mgmt.s_addr & 0xffff) >> 8;
1454 best[2] = LOCAL_CHASSIS(scfg)->c_mgmt.s_addr & 0xff;
1455
1456 if ((result = snmp_oid_compare(target, target_len, best, 6)) < 0) {
1457 if (exact)
1458 return NULL;
1459 memcpy(target, best, sizeof(oid) * 6);
1460 *length = vp->namelen + 6;
1461 } else if (exact && (result != 0))
1462 return NULL;
1463 else if (!exact && result == 0)
1464 return NULL;
1465
1466 return agent_management(vp, var_len, LOCAL_CHASSIS(scfg));
1467 }
1468
1469 static u_char*
1470 agent_h_remote_management(struct variable *vp, oid *name, size_t *length,
1471 int exact, size_t *var_len, WriteMethod **write_method)
1472 {
1473 struct lldpd_port *port;
1474
1475 if ((port = header_tprindexed_table(vp, name, length,
1476 exact, var_len, write_method, TPR_VARIANT_IP)) == NULL)
1477 return NULL;
1478
1479 return agent_management(vp, var_len, port->p_chassis);
1480 }
1481
1482 static struct variable8 lldp_vars[] = {
1483 /* Scalars */
1484 {LLDP_SNMP_TXINTERVAL, ASN_INTEGER, RONLY, agent_h_scalars, 3, {1, 1, 1}},
1485 {LLDP_SNMP_TXMULTIPLIER, ASN_INTEGER, RONLY, agent_h_scalars, 3, {1, 1, 2}},
1486 {LLDP_SNMP_REINITDELAY, ASN_INTEGER, RONLY, agent_h_scalars, 3, {1, 1, 3}},
1487 {LLDP_SNMP_TXDELAY, ASN_INTEGER, RONLY, agent_h_scalars, 3, {1, 1, 4}},
1488 {LLDP_SNMP_NOTIFICATION, ASN_INTEGER, RONLY, agent_h_scalars, 3, {1, 1, 5}},
1489 {LLDP_SNMP_LASTUPDATE, ASN_TIMETICKS, RONLY, agent_h_scalars, 3, {1, 2, 1}},
1490 {LLDP_SNMP_STATS_INSERTS, ASN_GAUGE, RONLY, agent_h_scalars, 3, {1, 2, 2}},
1491 {LLDP_SNMP_STATS_DELETES, ASN_GAUGE, RONLY, agent_h_scalars, 3, {1, 2, 3}},
1492 {LLDP_SNMP_STATS_DROPS, ASN_GAUGE, RONLY, agent_h_scalars, 3, {1, 2, 4}},
1493 {LLDP_SNMP_STATS_AGEOUTS, ASN_GAUGE, RONLY, agent_h_scalars, 3, {1, 2, 5}},
1494 /* Local chassis */
1495 {LLDP_SNMP_LOCAL_CIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_local_chassis, 3, {1, 3, 1}},
1496 {LLDP_SNMP_LOCAL_CID, ASN_OCTET_STR, RONLY, agent_h_local_chassis, 3, {1, 3, 2}},
1497 {LLDP_SNMP_LOCAL_SYSNAME, ASN_OCTET_STR, RONLY, agent_h_local_chassis, 3, {1, 3, 3}},
1498 {LLDP_SNMP_LOCAL_SYSDESCR, ASN_OCTET_STR, RONLY, agent_h_local_chassis, 3, {1, 3, 4}},
1499 {LLDP_SNMP_LOCAL_SYSCAP_SUP, ASN_OCTET_STR, RONLY, agent_h_local_chassis, 3, {1, 3, 5}},
1500 {LLDP_SNMP_LOCAL_SYSCAP_ENA, ASN_OCTET_STR, RONLY, agent_h_local_chassis, 3, {1, 3, 6}},
1501 /* Stats */
1502 {LLDP_SNMP_STATS_TX, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 6, 1, 2}},
1503 {LLDP_SNMP_STATS_RX_DISCARDED, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 2}},
1504 {LLDP_SNMP_STATS_RX_ERRORS, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 3}},
1505 {LLDP_SNMP_STATS_RX, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 4}},
1506 {LLDP_SNMP_STATS_RX_TLVDISCARDED, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 5}},
1507 {LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED, ASN_COUNTER, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 6}},
1508 {LLDP_SNMP_STATS_RX_AGEOUTS, ASN_GAUGE, RONLY, agent_h_stats, 5, {1, 2, 7, 1, 7}},
1509 /* Local ports */
1510 {LLDP_SNMP_LOCAL_PIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_local_port, 5, {1, 3, 7, 1, 2}},
1511 {LLDP_SNMP_LOCAL_PID, ASN_OCTET_STR, RONLY, agent_h_local_port, 5, {1, 3, 7, 1, 3}},
1512 {LLDP_SNMP_LOCAL_PORTDESC, ASN_OCTET_STR, RONLY, agent_h_local_port, 5, {1, 3, 7, 1, 4}},
1513 #ifdef ENABLE_DOT3
1514 {LLDP_SNMP_LOCAL_DOT3_AUTONEG_SUPPORT, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1515 {1, 5, 4623, 1, 2, 1, 1, 1}},
1516 {LLDP_SNMP_LOCAL_DOT3_AUTONEG_ENABLED, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1517 {1, 5, 4623, 1, 2, 1, 1, 2}},
1518 {LLDP_SNMP_LOCAL_DOT3_AUTONEG_ADVERTISED, ASN_OCTET_STR, RONLY, agent_h_local_port, 8,
1519 {1, 5, 4623, 1, 2, 1, 1, 3}},
1520 {LLDP_SNMP_LOCAL_DOT3_AUTONEG_MAU, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1521 {1, 5, 4623, 1, 2, 1, 1, 4}},
1522 {LLDP_SNMP_LOCAL_DOT3_POWER_DEVICETYPE, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1523 {1, 5, 4623, 1, 2, 2, 1, 1}},
1524 {LLDP_SNMP_LOCAL_DOT3_POWER_SUPPORT, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1525 {1, 5, 4623, 1, 2, 2, 1, 2}},
1526 {LLDP_SNMP_LOCAL_DOT3_POWER_ENABLED, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1527 {1, 5, 4623, 1, 2, 2, 1, 3}},
1528 {LLDP_SNMP_LOCAL_DOT3_POWER_PAIRCONTROL, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1529 {1, 5, 4623, 1, 2, 2, 1, 4}},
1530 {LLDP_SNMP_LOCAL_DOT3_POWER_PAIRS, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1531 {1, 5, 4623, 1, 2, 2, 1, 5}},
1532 {LLDP_SNMP_LOCAL_DOT3_POWER_CLASS, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1533 {1, 5, 4623, 1, 2, 2, 1, 6}},
1534 {LLDP_SNMP_LOCAL_DOT3_POWER_TYPE, ASN_OCTET_STR, RONLY, agent_h_local_port, 8,
1535 {1, 5, 4623, 1, 2, 2, 1, 7}},
1536 {LLDP_SNMP_LOCAL_DOT3_POWER_SOURCE, ASN_OCTET_STR, RONLY, agent_h_local_port, 8,
1537 {1, 5, 4623, 1, 2, 2, 1, 8}},
1538 {LLDP_SNMP_LOCAL_DOT3_POWER_PRIORITY, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1539 {1, 5, 4623, 1, 2, 2, 1, 9}},
1540 {LLDP_SNMP_LOCAL_DOT3_POWER_REQUESTED, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1541 {1, 5, 4623, 1, 2, 2, 1, 10}},
1542 {LLDP_SNMP_LOCAL_DOT3_POWER_ALLOCATED, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1543 {1, 5, 4623, 1, 2, 2, 1, 11}},
1544 {LLDP_SNMP_LOCAL_DOT3_AGG_STATUS, ASN_OCTET_STR, RONLY, agent_h_local_port, 8,
1545 {1, 5, 4623, 1, 2, 3, 1, 1}},
1546 {LLDP_SNMP_LOCAL_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1547 {1, 5, 4623, 1, 2, 3, 1, 2}},
1548 {LLDP_SNMP_LOCAL_DOT3_MFS, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1549 {1, 5, 4623, 1, 2, 4, 1, 1}},
1550 #endif
1551 #ifdef ENABLE_DOT1
1552 {LLDP_SNMP_LOCAL_DOT1_PVID, ASN_INTEGER, RONLY, agent_h_local_port, 8,
1553 {1, 5, 32962, 1, 2, 1, 1, 1}},
1554 #endif
1555 /* Remote ports */
1556 {LLDP_SNMP_REMOTE_CIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 4}},
1557 {LLDP_SNMP_REMOTE_CID, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 5}},
1558 {LLDP_SNMP_REMOTE_PIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 6}},
1559 {LLDP_SNMP_REMOTE_PID, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 7}},
1560 {LLDP_SNMP_REMOTE_PORTDESC, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 8}},
1561 {LLDP_SNMP_REMOTE_SYSNAME, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 9}},
1562 {LLDP_SNMP_REMOTE_SYSDESC, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 10}},
1563 {LLDP_SNMP_REMOTE_SYSCAP_SUP, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 11}},
1564 {LLDP_SNMP_REMOTE_SYSCAP_ENA, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 12}},
1565 #ifdef ENABLE_DOT3
1566 {LLDP_SNMP_REMOTE_DOT3_AUTONEG_SUPPORT, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1567 {1, 5, 4623, 1, 3, 1, 1, 1}},
1568 {LLDP_SNMP_REMOTE_DOT3_AUTONEG_ENABLED, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1569 {1, 5, 4623, 1, 3, 1, 1, 2}},
1570 {LLDP_SNMP_REMOTE_DOT3_AUTONEG_ADVERTISED, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8,
1571 {1, 5, 4623, 1, 3, 1, 1, 3}},
1572 {LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1573 {1, 5, 4623, 1, 3, 1, 1, 4}},
1574 {LLDP_SNMP_REMOTE_DOT3_POWER_DEVICETYPE, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1575 {1, 5, 4623, 1, 3, 2, 1, 1}},
1576 {LLDP_SNMP_REMOTE_DOT3_POWER_SUPPORT, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1577 {1, 5, 4623, 1, 3, 2, 1, 2}},
1578 {LLDP_SNMP_REMOTE_DOT3_POWER_ENABLED, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1579 {1, 5, 4623, 1, 3, 2, 1, 3}},
1580 {LLDP_SNMP_REMOTE_DOT3_POWER_PAIRCONTROL, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1581 {1, 5, 4623, 1, 3, 2, 1, 4}},
1582 {LLDP_SNMP_REMOTE_DOT3_POWER_PAIRS, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1583 {1, 5, 4623, 1, 3, 2, 1, 5}},
1584 {LLDP_SNMP_REMOTE_DOT3_POWER_CLASS, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1585 {1, 5, 4623, 1, 3, 2, 1, 6}},
1586 {LLDP_SNMP_REMOTE_DOT3_POWER_TYPE, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8,
1587 {1, 5, 4623, 1, 3, 2, 1, 7}},
1588 {LLDP_SNMP_REMOTE_DOT3_POWER_SOURCE, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8,
1589 {1, 5, 4623, 1, 3, 2, 1, 8}},
1590 {LLDP_SNMP_REMOTE_DOT3_POWER_PRIORITY, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1591 {1, 5, 4623, 1, 3, 2, 1, 9}},
1592 {LLDP_SNMP_REMOTE_DOT3_POWER_REQUESTED, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1593 {1, 5, 4623, 1, 3, 2, 1, 10}},
1594 {LLDP_SNMP_REMOTE_DOT3_POWER_ALLOCATED, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1595 {1, 5, 4623, 1, 3, 2, 1, 11}},
1596 {LLDP_SNMP_REMOTE_DOT3_AGG_STATUS, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8,
1597 {1, 5, 4623, 1, 3, 3, 1, 1}},
1598 {LLDP_SNMP_REMOTE_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1599 {1, 5, 4623, 1, 3, 3, 1, 2}},
1600 {LLDP_SNMP_REMOTE_DOT3_MFS, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1601 {1, 5, 4623, 1, 3, 4, 1, 1}},
1602 #endif
1603 #ifdef ENABLE_DOT1
1604 {LLDP_SNMP_REMOTE_DOT1_PVID, ASN_INTEGER, RONLY, agent_h_remote_port, 8,
1605 {1, 5, 32962, 1, 3, 1, 1, 1}},
1606 /* Local vlans */
1607 {LLDP_SNMP_LOCAL_DOT1_VLANNAME, ASN_OCTET_STR, RONLY, agent_h_local_vlan, 8,
1608 {1, 5, 32962, 1, 2, 3, 1, 2}},
1609 /* Remote vlans */
1610 {LLDP_SNMP_REMOTE_DOT1_VLANNAME, ASN_OCTET_STR, RONLY, agent_h_remote_vlan, 8,
1611 {1, 5, 32962, 1, 3, 3, 1, 2}},
1612 #endif
1613 /* Management address */
1614 {LLDP_SNMP_LOCAL_ADDR_LEN, ASN_INTEGER, RONLY, agent_h_local_management, 5,
1615 {1, 3, 8, 1, 3}},
1616 {LLDP_SNMP_LOCAL_ADDR_IFSUBTYPE, ASN_INTEGER, RONLY, agent_h_local_management, 5,
1617 {1, 3, 8, 1, 4}},
1618 {LLDP_SNMP_LOCAL_ADDR_IFID, ASN_INTEGER, RONLY, agent_h_local_management, 5,
1619 {1, 3, 8, 1, 5}},
1620 {LLDP_SNMP_LOCAL_ADDR_OID, ASN_OBJECT_ID, RONLY, agent_h_local_management, 5,
1621 {1, 3, 8, 1, 6}},
1622 {LLDP_SNMP_REMOTE_ADDR_IFSUBTYPE, ASN_INTEGER, RONLY, agent_h_remote_management, 5,
1623 {1, 4, 2, 1, 3}},
1624 {LLDP_SNMP_REMOTE_ADDR_IFID, ASN_INTEGER, RONLY, agent_h_remote_management, 5,
1625 {1, 4, 2, 1, 4}},
1626 {LLDP_SNMP_REMOTE_ADDR_OID, ASN_OBJECT_ID, RONLY, agent_h_remote_management, 5,
1627 {1, 4, 2, 1, 5}},
1628 #ifdef ENABLE_LLDPMED
1629 /* LLDP-MED local */
1630 {LLDP_SNMP_MED_LOCAL_CLASS, ASN_INTEGER, RONLY, agent_h_local_med, 6,
1631 {1, 5, 4795, 1, 1, 1}},
1632 {LLDP_SNMP_MED_LOCAL_POLICY_VID, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8,
1633 {1, 5, 4795, 1, 2, 1, 1, 2}},
1634 {LLDP_SNMP_MED_LOCAL_POLICY_PRIO, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8,
1635 {1, 5, 4795, 1, 2, 1, 1, 3}},
1636 {LLDP_SNMP_MED_LOCAL_POLICY_DSCP, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8,
1637 {1, 5, 4795, 1, 2, 1, 1, 4}},
1638 {LLDP_SNMP_MED_LOCAL_POLICY_UNKNOWN, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8,
1639 {1, 5, 4795, 1, 2, 1, 1, 5}},
1640 {LLDP_SNMP_MED_LOCAL_POLICY_TAGGED, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8,
1641 {1, 5, 4795, 1, 2, 1, 1, 6}},
1642 {LLDP_SNMP_MED_LOCAL_HW, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1643 {1, 5, 4795, 1, 2, 2}},
1644 {LLDP_SNMP_MED_LOCAL_FW, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1645 {1, 5, 4795, 1, 2, 3}},
1646 {LLDP_SNMP_MED_LOCAL_SW, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1647 {1, 5, 4795, 1, 2, 4}},
1648 {LLDP_SNMP_MED_LOCAL_SN, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1649 {1, 5, 4795, 1, 2, 5}},
1650 {LLDP_SNMP_MED_LOCAL_MANUF, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1651 {1, 5, 4795, 1, 2, 6}},
1652 {LLDP_SNMP_MED_LOCAL_MODEL, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1653 {1, 5, 4795, 1, 2, 7}},
1654 {LLDP_SNMP_MED_LOCAL_ASSET, ASN_OCTET_STR, RONLY, agent_h_local_med, 6,
1655 {1, 5, 4795, 1, 2, 8}},
1656 {LLDP_SNMP_MED_LOCAL_LOCATION, ASN_OCTET_STR, RONLY, agent_h_local_med_location, 8,
1657 {1, 5, 4795, 1, 2, 9, 1, 2}},
1658 {LLDP_SNMP_MED_POE_DEVICETYPE, ASN_INTEGER, RONLY, agent_h_local_med, 6,
1659 {1, 5, 4795, 1, 2, 10}},
1660 {LLDP_SNMP_MED_POE_PSE_POWERVAL, ASN_GAUGE, RONLY, agent_h_local_med_power, 8,
1661 {1, 5, 4795, 1, 2, 11, 1, 1}},
1662 {LLDP_SNMP_MED_POE_PSE_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_local_med_power, 8,
1663 {1, 5, 4795, 1, 2, 11, 1, 2}},
1664 {LLDP_SNMP_MED_POE_PSE_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_local_med, 6,
1665 {1, 5, 4795, 1, 2, 12}},
1666 {LLDP_SNMP_MED_POE_PD_POWERVAL, ASN_GAUGE, RONLY, agent_h_local_med, 6,
1667 {1, 5, 4795, 1, 2, 13}},
1668 {LLDP_SNMP_MED_POE_PD_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_local_med, 6,
1669 {1, 5, 4795, 1, 2, 14}},
1670 {LLDP_SNMP_MED_POE_PD_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_local_med, 6,
1671 {1, 5, 4795, 1, 2, 15}},
1672 /* LLDP-MED remote */
1673 {LLDP_SNMP_MED_REMOTE_CAP_AVAILABLE, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1674 {1, 5, 4795, 1, 3, 1, 1, 1}},
1675 {LLDP_SNMP_MED_REMOTE_CAP_ENABLED, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1676 {1, 5, 4795, 1, 3, 1, 1, 2}},
1677 {LLDP_SNMP_MED_REMOTE_CLASS, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1678 {1, 5, 4795, 1, 3, 1, 1, 3}},
1679 {LLDP_SNMP_MED_REMOTE_HW, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1680 {1, 5, 4795, 1, 3, 3, 1, 1}},
1681 {LLDP_SNMP_MED_REMOTE_FW, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1682 {1, 5, 4795, 1, 3, 3, 1, 2}},
1683 {LLDP_SNMP_MED_REMOTE_SW, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1684 {1, 5, 4795, 1, 3, 3, 1, 3}},
1685 {LLDP_SNMP_MED_REMOTE_SN, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1686 {1, 5, 4795, 1, 3, 3, 1, 4}},
1687 {LLDP_SNMP_MED_REMOTE_MANUF, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1688 {1, 5, 4795, 1, 3, 3, 1, 5}},
1689 {LLDP_SNMP_MED_REMOTE_MODEL, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1690 {1, 5, 4795, 1, 3, 3, 1, 6}},
1691 {LLDP_SNMP_MED_REMOTE_ASSET, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8,
1692 {1, 5, 4795, 1, 3, 3, 1, 7}},
1693 {LLDP_SNMP_MED_REMOTE_POLICY_VID, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8,
1694 {1, 5, 4795, 1, 3, 2, 1, 2}},
1695 {LLDP_SNMP_MED_REMOTE_POLICY_PRIO, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8,
1696 {1, 5, 4795, 1, 3, 2, 1, 3}},
1697 {LLDP_SNMP_MED_REMOTE_POLICY_DSCP, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8,
1698 {1, 5, 4795, 1, 3, 2, 1, 4}},
1699 {LLDP_SNMP_MED_REMOTE_POLICY_UNKNOWN, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8,
1700 {1, 5, 4795, 1, 3, 2, 1, 5}},
1701 {LLDP_SNMP_MED_REMOTE_POLICY_TAGGED, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8,
1702 {1, 5, 4795, 1, 3, 2, 1, 6}},
1703 {LLDP_SNMP_MED_REMOTE_LOCATION, ASN_OCTET_STR, RONLY, agent_h_remote_med_location, 8,
1704 {1, 5, 4795, 1, 3, 4, 1, 2}},
1705 {LLDP_SNMP_MED_POE_DEVICETYPE, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1706 {1, 5, 4795, 1, 3, 5, 1, 1}},
1707 {LLDP_SNMP_MED_POE_PSE_POWERVAL, ASN_GAUGE, RONLY, agent_h_remote_med, 8,
1708 {1, 5, 4795, 1, 3, 6, 1, 1}},
1709 {LLDP_SNMP_MED_POE_PSE_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1710 {1, 5, 4795, 1, 3, 6, 1, 2}},
1711 {LLDP_SNMP_MED_POE_PSE_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1712 {1, 5, 4795, 1, 3, 6, 1, 3}},
1713 {LLDP_SNMP_MED_POE_PD_POWERVAL, ASN_GAUGE, RONLY, agent_h_remote_med, 8,
1714 {1, 5, 4795, 1, 3, 7, 1, 1}},
1715 {LLDP_SNMP_MED_POE_PD_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1716 {1, 5, 4795, 1, 3, 7, 1, 2}},
1717 {LLDP_SNMP_MED_POE_PD_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_remote_med, 8,
1718 {1, 5, 4795, 1, 3, 7, 1, 3}},
1719 #endif
1720 };
1721
1722 void
1723 agent_init(struct lldpd *cfg, char *agentx, int debug)
1724 {
1725 int rc;
1726 #ifdef HAVE___PROGNAME
1727 extern char *__progname;
1728 #else
1729 # define __progname "lldpd"
1730 #endif
1731
1732 LLOG_INFO("Enable SNMP subagent");
1733 netsnmp_enable_subagent();
1734 snmp_disable_log();
1735 if (debug)
1736 snmp_enable_stderrlog();
1737 else
1738 snmp_enable_syslog_ident(__progname, LOG_DAEMON);
1739
1740 scfg = cfg;
1741
1742 /* We are chrooted, we don't want to handle persistent states */
1743 netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID,
1744 NETSNMP_DS_LIB_DONT_PERSIST_STATE, TRUE);
1745 /* Do not load any MIB */
1746 setenv("MIBS", "", 1);
1747
1748 /* We provide our UNIX domain transport */
1749 agent_priv_register_domain();
1750
1751 if (agentx)
1752 netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID,
1753 NETSNMP_DS_AGENT_X_SOCKET, agentx);
1754 init_agent("lldpAgent");
1755 REGISTER_MIB("lldp", lldp_vars, variable8, lldp_oid);
1756 init_snmp("lldpAgent");
1757
1758 if ((rc = register_sysORTable(lldp_oid, OID_LENGTH(lldp_oid),
1759 "lldpMIB implementation by lldpd")) != 0)
1760 LLOG_WARNX("Unable to register to sysORTable (%d)", rc);
1761 }
1762
1763 void
1764 agent_shutdown()
1765 {
1766 unregister_sysORTable(lldp_oid, OID_LENGTH(lldp_oid));
1767 snmp_shutdown("lldpAgent");
1768 }