]>
Commit | Line | Data |
---|---|---|
43c02e7b VB |
1 | /* |
2 | * Copyright (c) 2008 Vincent Bernat <bernat@luffy.cx> | |
3 | * | |
4 | * Permission to use, copy, modify, and distribute this software for any | |
5 | * purpose with or without fee is hereby granted, provided that the above | |
6 | * copyright notice and this permission notice appear in all copies. | |
7 | * | |
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 | */ | |
16 | ||
17 | #include "lldpd.h" | |
18 | ||
19 | #include <net-snmp/net-snmp-config.h> | |
20 | #include <net-snmp/net-snmp-includes.h> | |
21 | #include <net-snmp/agent/net-snmp-agent-includes.h> | |
22 | #include <net-snmp/agent/snmp_vars.h> | |
23 | #include <net-snmp/agent/util_funcs.h> | |
24 | ||
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. */ | |
8888d191 | 34 | static struct lldpd *scfg; |
43c02e7b VB |
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 | ||
8888d191 | 46 | static struct lldpd_hardware* |
43c02e7b VB |
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) { | |
6e75df87 VB |
59 | aport = hardware->h_ifindex; |
60 | if (aport == port) { | |
61 | /* Exact match */ | |
62 | return hardware; | |
63 | } | |
64 | if (aport < port) | |
65 | continue; | |
66 | if (aport - port < distance) { | |
67 | phardware = hardware; | |
68 | distance = aport - port; | |
43c02e7b VB |
69 | } |
70 | } | |
71 | if (phardware == NULL) | |
72 | return NULL; | |
73 | if (exact) | |
74 | return NULL; | |
75 | if (distance == -1) | |
76 | return NULL; | |
77 | aport = distance + port; | |
78 | name[*length - 1] = aport; | |
79 | return phardware; | |
80 | } | |
81 | ||
fd6aa9a3 | 82 | #ifdef ENABLE_LLDPMED |
1dcd4665 VB |
83 | #define PMED_VARIANT_POLICY 0 |
84 | #define PMED_VARIANT_LOCATION 1 | |
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) | |
fd6aa9a3 VB |
88 | { |
89 | struct lldpd_hardware *hardware; | |
1dcd4665 VB |
90 | void *squid, *psquid = NULL; |
91 | int result, target_len, i, max; | |
fd6aa9a3 VB |
92 | oid *target, current[2], best[2]; |
93 | ||
94 | if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) { | |
95 | memcpy(name, vp->name, sizeof(oid) * vp->namelen); | |
96 | *length = vp->namelen; | |
97 | } | |
98 | ||
99 | *write_method = 0; | |
100 | *var_len = sizeof(long); | |
101 | ||
102 | best[0] = best[1] = MAX_SUBID; | |
103 | target = &name[vp->namelen]; | |
104 | target_len = *length - vp->namelen; | |
105 | TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) { | |
1dcd4665 VB |
106 | max = (variant == PMED_VARIANT_POLICY)? |
107 | LLDPMED_APPTYPE_LAST:LLDPMED_LOCFORMAT_LAST; | |
108 | for (i = 0; | |
109 | i < max; | |
110 | i++) { | |
111 | if (variant == PMED_VARIANT_POLICY) { | |
112 | if (hardware->h_lport.p_med_policy[i].type != i+1) | |
113 | continue; | |
114 | squid = &(hardware->h_lport.p_med_policy[i]); | |
115 | } else { | |
116 | if (hardware->h_lport.p_med_location[i].format != i+1) | |
117 | continue; | |
118 | squid = &(hardware->h_lport.p_med_location[i]); | |
119 | } | |
fd6aa9a3 VB |
120 | current[0] = hardware->h_ifindex; |
121 | current[1] = i+1; | |
122 | if ((result = snmp_oid_compare(current, 2, target, | |
123 | target_len)) < 0) | |
124 | continue; | |
125 | if ((result == 0) && !exact) | |
126 | continue; | |
127 | if (result == 0) | |
1dcd4665 | 128 | return squid; |
fd6aa9a3 VB |
129 | if (snmp_oid_compare(current, 2, best, 2) < 0) { |
130 | memcpy(best, current, sizeof(oid) * 2); | |
1dcd4665 | 131 | psquid = squid; |
fd6aa9a3 VB |
132 | } |
133 | } | |
134 | } | |
1dcd4665 | 135 | if (psquid == NULL) |
fd6aa9a3 VB |
136 | return NULL; |
137 | if (exact) | |
138 | return NULL; | |
139 | if ((best[0] == best[1]) && | |
140 | (best[0] == MAX_SUBID)) | |
141 | return NULL; | |
142 | memcpy(target, best, sizeof(oid) * 2); | |
143 | *length = vp->namelen + 2; | |
144 | ||
1dcd4665 | 145 | return psquid; |
fd6aa9a3 VB |
146 | } |
147 | #endif | |
148 | ||
4a2acc8e VB |
149 | #define TPR_VARIANT_NONE 0 |
150 | #define TPR_VARIANT_IP 1 | |
151 | #define TPR_VARIANT_MED_POLICY 2 | |
152 | #define TPR_VARIANT_MED_LOCATION 3 | |
7a53c5b9 | 153 | static struct lldpd_port* |
43c02e7b | 154 | header_tprindexed_table(struct variable *vp, oid *name, size_t *length, |
4a2acc8e | 155 | int exact, size_t *var_len, WriteMethod **write_method, int variant) |
43c02e7b | 156 | { |
7a53c5b9 VB |
157 | struct lldpd_hardware *hardware = NULL; |
158 | struct lldpd_port *port, *pport = NULL; | |
43c02e7b VB |
159 | oid *target, current[9], best[9]; |
160 | int result, target_len, oid_len; | |
4a2acc8e | 161 | int i, j, k; |
43c02e7b VB |
162 | |
163 | if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) { | |
164 | memcpy(name, vp->name, sizeof(oid) * vp->namelen); | |
165 | *length = vp->namelen; | |
166 | } | |
167 | ||
168 | *write_method = 0; | |
169 | *var_len = sizeof(long); | |
170 | ||
4a2acc8e VB |
171 | switch (variant) { |
172 | case TPR_VARIANT_IP: | |
173 | oid_len = 9; break; | |
174 | #ifdef ENABLE_LLDPMED | |
175 | case TPR_VARIANT_MED_POLICY: | |
176 | case TPR_VARIANT_MED_LOCATION: | |
177 | oid_len = 4; break; | |
178 | #endif | |
179 | case TPR_VARIANT_NONE: | |
180 | default: | |
181 | oid_len = 3; | |
182 | } | |
43c02e7b VB |
183 | for (i = 0; i < oid_len; i++) best[i] = MAX_SUBID; |
184 | target = &name[vp->namelen]; | |
185 | target_len = *length - vp->namelen; | |
186 | TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) { | |
7a53c5b9 | 187 | TAILQ_FOREACH(port, &hardware->h_rports, p_entries) { |
42b39485 | 188 | if (SMART_HIDDEN(scfg, port)) continue; |
4a2acc8e | 189 | if ((variant == TPR_VARIANT_IP) && |
7a53c5b9 | 190 | (port->p_chassis->c_mgmt.s_addr == INADDR_ANY)) |
43c02e7b | 191 | continue; |
7a53c5b9 | 192 | if (port->p_lastchange > starttime.tv_sec) |
777c32ea | 193 | current[0] = |
7a53c5b9 | 194 | (port->p_lastchange - starttime.tv_sec)*100; |
777c32ea VB |
195 | else |
196 | current[0] = 0; | |
6e75df87 | 197 | current[1] = hardware->h_ifindex; |
7a53c5b9 | 198 | current[2] = port->p_chassis->c_index; |
4a2acc8e VB |
199 | k = j = 0; |
200 | switch (variant) { | |
201 | case TPR_VARIANT_IP: | |
202 | current[3] = 1; | |
203 | current[4] = 4; | |
7a53c5b9 VB |
204 | current[8] = port->p_chassis->c_mgmt.s_addr >> 24; |
205 | current[7] = (port->p_chassis->c_mgmt.s_addr & | |
4a2acc8e | 206 | 0xffffff) >> 16; |
7a53c5b9 | 207 | current[6] = (port->p_chassis->c_mgmt.s_addr & |
4a2acc8e | 208 | 0xffff) >> 8; |
7a53c5b9 | 209 | current[5] = port->p_chassis->c_mgmt.s_addr & |
4a2acc8e VB |
210 | 0xff; |
211 | break; | |
212 | #ifdef ENABLE_LLDPMED | |
213 | case TPR_VARIANT_MED_POLICY: | |
214 | j = LLDPMED_APPTYPE_LAST; | |
215 | break; | |
216 | case TPR_VARIANT_MED_LOCATION: | |
217 | j = LLDPMED_LOCFORMAT_LAST; | |
218 | break; | |
219 | #endif | |
220 | } | |
221 | do { | |
222 | if (j > 0) | |
223 | current[3] = ++k; | |
224 | if ((result = snmp_oid_compare(current, oid_len, target, | |
225 | target_len)) < 0) | |
226 | continue; | |
227 | if ((result == 0) && !exact) | |
228 | continue; | |
229 | if (result == 0) | |
7a53c5b9 | 230 | return port; |
4a2acc8e VB |
231 | if (snmp_oid_compare(current, oid_len, best, oid_len) < 0) { |
232 | memcpy(best, current, sizeof(oid) * oid_len); | |
7a53c5b9 | 233 | pport = port; |
4a2acc8e VB |
234 | } |
235 | } while (k < j); | |
43c02e7b VB |
236 | } |
237 | } | |
7a53c5b9 | 238 | if (pport == NULL) |
43c02e7b VB |
239 | return NULL; |
240 | if (exact) | |
241 | return NULL; | |
242 | for (i = 0; i < oid_len; i++) | |
243 | if (best[i] != MAX_SUBID) break; | |
244 | if (i == oid_len) | |
245 | return NULL; | |
246 | memcpy(target, best, sizeof(oid) * oid_len); | |
247 | *length = vp->namelen + oid_len; | |
248 | ||
7a53c5b9 | 249 | return pport; |
43c02e7b VB |
250 | } |
251 | ||
a1347cd8 | 252 | #ifdef ENABLE_DOT1 |
8888d191 | 253 | static struct lldpd_vlan* |
43c02e7b VB |
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) { | |
6e75df87 VB |
274 | TAILQ_FOREACH(vlan, &hardware->h_lport.p_vlans, v_entries) { |
275 | current[0] = hardware->h_ifindex; | |
276 | current[1] = vlan->v_vid; | |
277 | if ((result = snmp_oid_compare(current, 2, target, | |
278 | target_len)) < 0) | |
279 | continue; | |
280 | if ((result == 0) && !exact) | |
281 | continue; | |
282 | if (result == 0) | |
283 | return vlan; | |
284 | if (snmp_oid_compare(current, 2, best, 2) < 0) { | |
285 | memcpy(best, current, sizeof(oid) * 2); | |
286 | pvlan = vlan; | |
287 | } | |
43c02e7b VB |
288 | } |
289 | } | |
290 | if (pvlan == NULL) | |
291 | return NULL; | |
292 | if (exact) | |
293 | return NULL; | |
294 | if ((best[0] == best[1]) && | |
295 | (best[0] == MAX_SUBID)) | |
296 | return NULL; | |
297 | memcpy(target, best, sizeof(oid) * 2); | |
298 | *length = vp->namelen + 2; | |
299 | ||
300 | return pvlan; | |
301 | } | |
302 | ||
8888d191 | 303 | static struct lldpd_vlan* |
43c02e7b VB |
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; | |
7a53c5b9 | 308 | struct lldpd_port *port; |
43c02e7b VB |
309 | struct lldpd_vlan *vlan, *pvlan = NULL; |
310 | oid *target, current[4], best[4]; | |
311 | int result, target_len; | |
312 | ||
313 | if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) { | |
314 | memcpy(name, vp->name, sizeof(oid) * vp->namelen); | |
315 | *length = vp->namelen; | |
316 | } | |
317 | ||
318 | *write_method = 0; | |
319 | *var_len = sizeof(long); | |
320 | ||
321 | best[0] = best[1] = best[2] = best[3] = MAX_SUBID; | |
322 | target = &name[vp->namelen]; | |
323 | target_len = *length - vp->namelen; | |
324 | TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) { | |
7a53c5b9 | 325 | TAILQ_FOREACH(port, &hardware->h_rports, p_entries) { |
42b39485 | 326 | if (SMART_HIDDEN(scfg, port)) continue; |
7a53c5b9 VB |
327 | TAILQ_FOREACH(vlan, &port->p_vlans, v_entries) { |
328 | if (port->p_lastchange > starttime.tv_sec) | |
777c32ea | 329 | current[0] = |
7a53c5b9 | 330 | (port->p_lastchange - starttime.tv_sec)*100; |
777c32ea VB |
331 | else |
332 | current[0] = 0; | |
6e75df87 | 333 | current[1] = hardware->h_ifindex; |
7a53c5b9 | 334 | current[2] = port->p_chassis->c_index; |
43c02e7b VB |
335 | current[3] = vlan->v_vid; |
336 | if ((result = snmp_oid_compare(current, 4, target, | |
337 | target_len)) < 0) | |
338 | continue; | |
339 | if ((result == 0) && !exact) | |
340 | continue; | |
341 | if (result == 0) | |
342 | return vlan; | |
343 | if (snmp_oid_compare(current, 4, best, 4) < 0) { | |
344 | memcpy(best, current, sizeof(oid) * 4); | |
345 | pvlan = vlan; | |
346 | } | |
347 | } | |
348 | } | |
349 | } | |
350 | if (pvlan == NULL) | |
351 | return NULL; | |
352 | if (exact) | |
353 | return NULL; | |
354 | if ((best[0] == best[1]) && (best[1] == best[2]) && | |
355 | (best[2] == best[3]) && (best[0] == MAX_SUBID)) | |
356 | return NULL; | |
357 | memcpy(target, best, sizeof(oid) * 4); | |
358 | *length = vp->namelen + 4; | |
359 | ||
360 | return pvlan; | |
361 | } | |
a1347cd8 | 362 | #endif |
43c02e7b VB |
363 | |
364 | /* Scalars */ | |
365 | #define LLDP_SNMP_TXINTERVAL 1 | |
366 | #define LLDP_SNMP_TXMULTIPLIER 2 | |
367 | #define LLDP_SNMP_REINITDELAY 3 | |
368 | #define LLDP_SNMP_TXDELAY 4 | |
369 | #define LLDP_SNMP_NOTIFICATION 5 | |
370 | #define LLDP_SNMP_LASTUPDATE 6 | |
371 | #define LLDP_SNMP_STATS_INSERTS 7 | |
372 | #define LLDP_SNMP_STATS_DELETES 8 | |
373 | #define LLDP_SNMP_STATS_DROPS 9 | |
374 | #define LLDP_SNMP_STATS_AGEOUTS 10 | |
375 | /* Local chassis */ | |
376 | #define LLDP_SNMP_LOCAL_CIDSUBTYPE 1 | |
377 | #define LLDP_SNMP_LOCAL_CID 2 | |
378 | #define LLDP_SNMP_LOCAL_SYSNAME 3 | |
379 | #define LLDP_SNMP_LOCAL_SYSDESCR 4 | |
380 | #define LLDP_SNMP_LOCAL_SYSCAP_SUP 5 | |
381 | #define LLDP_SNMP_LOCAL_SYSCAP_ENA 6 | |
382 | /* Stats */ | |
383 | #define LLDP_SNMP_STATS_TX_PORTNUM 1 | |
384 | #define LLDP_SNMP_STATS_TX 2 | |
385 | #define LLDP_SNMP_STATS_RX_PORTNUM 3 | |
386 | #define LLDP_SNMP_STATS_RX_DISCARDED 4 | |
387 | #define LLDP_SNMP_STATS_RX_ERRORS 5 | |
388 | #define LLDP_SNMP_STATS_RX 6 | |
389 | #define LLDP_SNMP_STATS_RX_TLVDISCARDED 7 | |
390 | #define LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED 8 | |
391 | #define LLDP_SNMP_STATS_RX_AGEOUTS 9 | |
392 | /* Local ports */ | |
393 | #define LLDP_SNMP_LOCAL_PORTNUM 1 | |
394 | #define LLDP_SNMP_LOCAL_PIDSUBTYPE 2 | |
395 | #define LLDP_SNMP_LOCAL_PID 3 | |
396 | #define LLDP_SNMP_LOCAL_PORTDESC 4 | |
397 | #define LLDP_SNMP_LOCAL_DOT3_AUTONEG_SUPPORT 5 | |
398 | #define LLDP_SNMP_LOCAL_DOT3_AUTONEG_ENABLED 6 | |
399 | #define LLDP_SNMP_LOCAL_DOT3_AUTONEG_ADVERTISED 7 | |
400 | #define LLDP_SNMP_LOCAL_DOT3_AUTONEG_MAU 8 | |
401 | #define LLDP_SNMP_LOCAL_DOT3_AGG_STATUS 9 | |
402 | #define LLDP_SNMP_LOCAL_DOT3_AGG_ID 10 | |
548109b2 | 403 | #define LLDP_SNMP_LOCAL_DOT3_MFS 11 |
75b3469d | 404 | #define LLDP_SNMP_LOCAL_DOT1_PVID 12 |
43c02e7b VB |
405 | /* Remote ports */ |
406 | #define LLDP_SNMP_REMOTE_CIDSUBTYPE 1 | |
407 | #define LLDP_SNMP_REMOTE_CID 2 | |
408 | #define LLDP_SNMP_REMOTE_PIDSUBTYPE 3 | |
409 | #define LLDP_SNMP_REMOTE_PID 4 | |
410 | #define LLDP_SNMP_REMOTE_PORTDESC 5 | |
411 | #define LLDP_SNMP_REMOTE_SYSNAME 6 | |
412 | #define LLDP_SNMP_REMOTE_SYSDESC 7 | |
413 | #define LLDP_SNMP_REMOTE_SYSCAP_SUP 8 | |
414 | #define LLDP_SNMP_REMOTE_SYSCAP_ENA 9 | |
415 | #define LLDP_SNMP_REMOTE_DOT3_AUTONEG_SUPPORT 10 | |
416 | #define LLDP_SNMP_REMOTE_DOT3_AUTONEG_ENABLED 11 | |
417 | #define LLDP_SNMP_REMOTE_DOT3_AUTONEG_ADVERTISED 12 | |
418 | #define LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU 13 | |
419 | #define LLDP_SNMP_REMOTE_DOT3_AGG_STATUS 14 | |
420 | #define LLDP_SNMP_REMOTE_DOT3_AGG_ID 15 | |
548109b2 | 421 | #define LLDP_SNMP_REMOTE_DOT3_MFS 16 |
75b3469d | 422 | #define LLDP_SNMP_REMOTE_DOT1_PVID 17 |
43c02e7b VB |
423 | /* Local vlans */ |
424 | #define LLDP_SNMP_LOCAL_DOT1_VLANNAME 1 | |
425 | /* Remote vlans */ | |
426 | #define LLDP_SNMP_REMOTE_DOT1_VLANNAME 1 | |
427 | /* Management address */ | |
428 | #define LLDP_SNMP_LOCAL_ADDR_LEN 1 | |
429 | #define LLDP_SNMP_LOCAL_ADDR_IFSUBTYPE 2 | |
430 | #define LLDP_SNMP_LOCAL_ADDR_IFID 3 | |
431 | #define LLDP_SNMP_LOCAL_ADDR_OID 4 | |
432 | #define LLDP_SNMP_REMOTE_ADDR_IFSUBTYPE 5 | |
433 | #define LLDP_SNMP_REMOTE_ADDR_IFID 6 | |
434 | #define LLDP_SNMP_REMOTE_ADDR_OID 7 | |
1d88c843 VB |
435 | /* LLDP-MED local */ |
436 | #define LLDP_SNMP_MED_LOCAL_CLASS 1 | |
437 | #define LLDP_SNMP_MED_LOCAL_HW 2 | |
438 | #define LLDP_SNMP_MED_LOCAL_FW 3 | |
439 | #define LLDP_SNMP_MED_LOCAL_SW 4 | |
440 | #define LLDP_SNMP_MED_LOCAL_SN 5 | |
441 | #define LLDP_SNMP_MED_LOCAL_MANUF 6 | |
442 | #define LLDP_SNMP_MED_LOCAL_MODEL 7 | |
443 | #define LLDP_SNMP_MED_LOCAL_ASSET 8 | |
fd6aa9a3 VB |
444 | #define LLDP_SNMP_MED_LOCAL_POLICY_VID 9 |
445 | #define LLDP_SNMP_MED_LOCAL_POLICY_PRIO 10 | |
446 | #define LLDP_SNMP_MED_LOCAL_POLICY_DSCP 11 | |
447 | #define LLDP_SNMP_MED_LOCAL_POLICY_UNKNOWN 12 | |
448 | #define LLDP_SNMP_MED_LOCAL_POLICY_TAGGED 13 | |
1dcd4665 | 449 | #define LLDP_SNMP_MED_LOCAL_LOCATION 14 |
8e44f2dc | 450 | /* No more than 17 since we reuse LLDP_SNMP_MED_POE_DEVICETYPE and above */ |
1d88c843 | 451 | /* LLDP-MED remote */ |
40ecae87 VB |
452 | #define LLDP_SNMP_MED_REMOTE_CAP_AVAILABLE 1 |
453 | #define LLDP_SNMP_MED_REMOTE_CAP_ENABLED 2 | |
454 | #define LLDP_SNMP_MED_REMOTE_CLASS 3 | |
455 | #define LLDP_SNMP_MED_REMOTE_HW 4 | |
456 | #define LLDP_SNMP_MED_REMOTE_FW 5 | |
457 | #define LLDP_SNMP_MED_REMOTE_SW 6 | |
458 | #define LLDP_SNMP_MED_REMOTE_SN 7 | |
459 | #define LLDP_SNMP_MED_REMOTE_MANUF 8 | |
460 | #define LLDP_SNMP_MED_REMOTE_MODEL 9 | |
461 | #define LLDP_SNMP_MED_REMOTE_ASSET 10 | |
4a2acc8e VB |
462 | #define LLDP_SNMP_MED_REMOTE_POLICY_VID 11 |
463 | #define LLDP_SNMP_MED_REMOTE_POLICY_PRIO 12 | |
464 | #define LLDP_SNMP_MED_REMOTE_POLICY_DSCP 13 | |
465 | #define LLDP_SNMP_MED_REMOTE_POLICY_UNKNOWN 14 | |
466 | #define LLDP_SNMP_MED_REMOTE_POLICY_TAGGED 15 | |
467 | #define LLDP_SNMP_MED_REMOTE_LOCATION 16 | |
8e44f2dc VB |
468 | #define LLDP_SNMP_MED_POE_DEVICETYPE 17 |
469 | #define LLDP_SNMP_MED_POE_PSE_POWERVAL 19 | |
470 | #define LLDP_SNMP_MED_POE_PSE_POWERSOURCE 20 | |
471 | #define LLDP_SNMP_MED_POE_PSE_POWERPRIORITY 21 | |
472 | #define LLDP_SNMP_MED_POE_PD_POWERVAL 22 | |
473 | #define LLDP_SNMP_MED_POE_PD_POWERSOURCE 23 | |
474 | #define LLDP_SNMP_MED_POE_PD_POWERPRIORITY 24 | |
43c02e7b VB |
475 | |
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; | |
7a53c5b9 | 482 | struct lldpd_port *port; |
43c02e7b VB |
483 | |
484 | if (header_generic(vp, name, length, exact, var_len, write_method)) | |
485 | return NULL; | |
486 | ||
487 | switch (vp->magic) { | |
488 | case LLDP_SNMP_TXINTERVAL: | |
489 | long_ret = scfg->g_delay; | |
490 | return (u_char *)&long_ret; | |
491 | case LLDP_SNMP_TXMULTIPLIER: | |
7a53c5b9 | 492 | long_ret = LOCAL_CHASSIS(scfg)->c_ttl / scfg->g_delay; |
43c02e7b VB |
493 | return (u_char *)&long_ret; |
494 | case LLDP_SNMP_REINITDELAY: | |
495 | long_ret = 1; | |
496 | return (u_char *)&long_ret; | |
497 | case LLDP_SNMP_TXDELAY: | |
498 | long_ret = LLDPD_TX_MSGDELAY; | |
499 | return (u_char *)&long_ret; | |
500 | case LLDP_SNMP_NOTIFICATION: | |
501 | long_ret = 5; | |
502 | return (u_char *)&long_ret; | |
503 | case LLDP_SNMP_LASTUPDATE: | |
504 | long_ret = 0; | |
505 | TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) | |
42b39485 VB |
506 | TAILQ_FOREACH(port, &hardware->h_rports, p_entries) { |
507 | if (SMART_HIDDEN(scfg, port)) continue; | |
7a53c5b9 VB |
508 | if (port->p_lastchange > long_ret) |
509 | long_ret = port->p_lastchange; | |
42b39485 | 510 | } |
43c02e7b VB |
511 | if (long_ret) |
512 | long_ret = (long_ret - starttime.tv_sec) * 100; | |
513 | return (u_char *)&long_ret; | |
514 | case LLDP_SNMP_STATS_INSERTS: | |
515 | /* We assume this is equal to valid frames received on all ports */ | |
516 | long_ret = 0; | |
517 | TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) | |
518 | long_ret += hardware->h_rx_cnt; | |
519 | return (u_char *)&long_ret; | |
520 | case LLDP_SNMP_STATS_AGEOUTS: | |
521 | long_ret = 0; | |
522 | TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) | |
523 | long_ret += hardware->h_rx_ageout_cnt; | |
524 | return (u_char *)&long_ret; | |
525 | case LLDP_SNMP_STATS_DELETES: | |
526 | long_ret = 0; | |
527 | TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) | |
528 | long_ret += hardware->h_rx_ageout_cnt + | |
529 | hardware->h_rx_cnt?(hardware->h_rx_cnt - 1):0; | |
530 | return (u_char *)&long_ret; | |
531 | case LLDP_SNMP_STATS_DROPS: | |
532 | /* We assume that we never have insufficient resources */ | |
533 | long_ret = 0; | |
534 | return (u_char *)&long_ret; | |
535 | default: | |
536 | break; | |
537 | } | |
538 | return NULL; | |
539 | } | |
540 | ||
1d88c843 | 541 | #ifdef ENABLE_LLDPMED |
8e44f2dc VB |
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 | ||
1d88c843 VB |
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; | |
8e44f2dc VB |
633 | struct lldpd_hardware *hardware; |
634 | struct lldpd_med_power *power; | |
635 | int pse; | |
1d88c843 | 636 | |
7a53c5b9 | 637 | if (!LOCAL_CHASSIS(scfg)->c_med_cap_available) |
1d88c843 VB |
638 | return NULL; |
639 | ||
4a2acc8e | 640 | if (header_generic(vp, name, length, exact, var_len, write_method)) |
1d88c843 VB |
641 | return NULL; |
642 | ||
643 | switch (vp->magic) { | |
644 | case LLDP_SNMP_MED_LOCAL_CLASS: | |
7a53c5b9 | 645 | long_ret = LOCAL_CHASSIS(scfg)->c_med_type; |
4a2acc8e | 646 | return (u_char *)&long_ret; |
8e44f2dc VB |
647 | case LLDP_SNMP_MED_POE_DEVICETYPE: |
648 | case LLDP_SNMP_MED_POE_PSE_POWERSOURCE: | |
649 | case LLDP_SNMP_MED_POE_PD_POWERVAL: | |
650 | case LLDP_SNMP_MED_POE_PD_POWERSOURCE: | |
651 | case LLDP_SNMP_MED_POE_PD_POWERPRIORITY: | |
652 | /* LLDP-MED requires only one device type for all | |
653 | ports. Moreover, a PSE can only have one power source. At | |
654 | least, all PD values are global and not per-port. We try to | |
655 | do our best. For device type, we decide on the number of | |
656 | PD/PSE ports. */ | |
657 | pse = 0; power = NULL; | |
658 | TAILQ_FOREACH(hardware, &scfg->g_hardware, h_entries) { | |
659 | if (hardware->h_lport.p_med_power.devicetype == | |
660 | LLDPMED_POW_TYPE_PSE) { | |
661 | pse++; | |
662 | if (pse == 1) /* Take this port as a reference */ | |
663 | power = &hardware->h_lport.p_med_power; | |
664 | } else if (hardware->h_lport.p_med_power.devicetype == | |
665 | LLDPMED_POW_TYPE_PD) { | |
666 | pse--; | |
667 | if (pse == -1) /* Take this one instead */ | |
668 | power = &hardware->h_lport.p_med_power; | |
669 | } | |
670 | } | |
671 | if (!power) | |
672 | break; /* Neither PSE nor PD */ | |
673 | long_ret = agent_h_med_power(vp, power); | |
674 | if (long_ret != (unsigned long)-1) | |
675 | return (u_char *)&long_ret; | |
676 | break; | |
1d88c843 VB |
677 | |
678 | #define LLDP_H_LOCAL_MED(magic, variable) \ | |
679 | case magic: \ | |
7a53c5b9 | 680 | if (LOCAL_CHASSIS(scfg)->variable) { \ |
1d88c843 | 681 | *var_len = strlen( \ |
7a53c5b9 VB |
682 | LOCAL_CHASSIS(scfg)->variable); \ |
683 | return (u_char *)LOCAL_CHASSIS(scfg)->variable; \ | |
1d88c843 VB |
684 | } \ |
685 | break | |
686 | ||
687 | LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_HW, | |
688 | c_med_hw); | |
689 | LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_SW, | |
690 | c_med_sw); | |
691 | LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_FW, | |
692 | c_med_fw); | |
693 | LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_SN, | |
694 | c_med_sn); | |
695 | LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_MANUF, | |
696 | c_med_manuf); | |
697 | LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_MODEL, | |
698 | c_med_model); | |
699 | LLDP_H_LOCAL_MED(LLDP_SNMP_MED_LOCAL_ASSET, | |
700 | c_med_asset); | |
701 | ||
702 | default: | |
4a2acc8e | 703 | return NULL; |
1d88c843 | 704 | } |
4a2acc8e VB |
705 | /* At this point, we seem to have hit an inventory variable that is not |
706 | * available, try to get the next one */ | |
707 | if (name[*length-1] < MAX_SUBID) | |
708 | return agent_h_local_med(vp, name, length, | |
709 | exact, var_len, write_method); | |
1d88c843 VB |
710 | return NULL; |
711 | } | |
712 | ||
fd6aa9a3 VB |
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 | ||
1dcd4665 VB |
720 | if ((policy = (struct lldpd_med_policy *)header_pmedindexed_table(vp, name, length, |
721 | exact, var_len, write_method, PMED_VARIANT_POLICY)) == NULL) | |
fd6aa9a3 VB |
722 | return NULL; |
723 | ||
724 | switch (vp->magic) { | |
725 | case LLDP_SNMP_MED_LOCAL_POLICY_VID: | |
726 | long_ret = policy->vid; | |
727 | break; | |
728 | case LLDP_SNMP_MED_LOCAL_POLICY_PRIO: | |
729 | long_ret = policy->priority; | |
730 | break; | |
731 | case LLDP_SNMP_MED_LOCAL_POLICY_DSCP: | |
732 | long_ret = policy->dscp; | |
733 | break; | |
734 | case LLDP_SNMP_MED_LOCAL_POLICY_UNKNOWN: | |
735 | long_ret = policy->unknown?1:2; | |
736 | break; | |
737 | case LLDP_SNMP_MED_LOCAL_POLICY_TAGGED: | |
738 | long_ret = policy->tagged?1:2; | |
739 | break; | |
740 | default: | |
741 | return NULL; | |
742 | } | |
743 | return (u_char *)&long_ret; | |
744 | } | |
745 | ||
1dcd4665 VB |
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 | ||
8e44f2dc VB |
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 | ||
1d88c843 VB |
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 | { | |
7a53c5b9 | 793 | struct lldpd_port *port; |
1d88c843 VB |
794 | static uint8_t bit; |
795 | static unsigned long long_ret; | |
796 | ||
7a53c5b9 | 797 | if ((port = header_tprindexed_table(vp, name, length, |
4a2acc8e | 798 | exact, var_len, write_method, TPR_VARIANT_NONE)) == NULL) |
1d88c843 VB |
799 | return NULL; |
800 | ||
7a53c5b9 | 801 | if (!port->p_chassis->c_med_cap_available) { |
4a2acc8e VB |
802 | if (!exact && (name[*length-2] < MAX_SUBID)) |
803 | name[*length-2]++; | |
804 | goto remotemed_failed; | |
805 | } | |
1d88c843 VB |
806 | |
807 | switch (vp->magic) { | |
808 | case LLDP_SNMP_MED_REMOTE_CLASS: | |
7a53c5b9 | 809 | long_ret = port->p_chassis->c_med_type; |
1be9e1b5 | 810 | return (u_char *)&long_ret; |
40ecae87 | 811 | case LLDP_SNMP_MED_REMOTE_CAP_AVAILABLE: |
1d88c843 | 812 | *var_len = 1; |
7a53c5b9 | 813 | bit = swap_bits(port->p_chassis->c_med_cap_available); |
40ecae87 VB |
814 | return (u_char *)&bit; |
815 | case LLDP_SNMP_MED_REMOTE_CAP_ENABLED: | |
816 | *var_len = 1; | |
7a53c5b9 | 817 | bit = swap_bits(port->p_med_cap_enabled); |
1d88c843 | 818 | return (u_char *)&bit; |
8e44f2dc VB |
819 | |
820 | case LLDP_SNMP_MED_POE_DEVICETYPE: | |
821 | case LLDP_SNMP_MED_POE_PSE_POWERVAL: | |
822 | case LLDP_SNMP_MED_POE_PD_POWERVAL: | |
823 | case LLDP_SNMP_MED_POE_PSE_POWERSOURCE: | |
824 | case LLDP_SNMP_MED_POE_PD_POWERSOURCE: | |
825 | case LLDP_SNMP_MED_POE_PSE_POWERPRIORITY: | |
826 | case LLDP_SNMP_MED_POE_PD_POWERPRIORITY: | |
827 | long_ret = agent_h_med_power(vp, &port->p_med_power); | |
828 | if (long_ret != (unsigned long)-1) | |
1be9e1b5 | 829 | return (u_char *)&long_ret; |
1be9e1b5 VB |
830 | break; |
831 | ||
1d88c843 VB |
832 | #define LLDP_H_REMOTE_MED(magic, variable) \ |
833 | case magic: \ | |
7a53c5b9 | 834 | if (port->p_chassis->variable) { \ |
1d88c843 | 835 | *var_len = strlen( \ |
7a53c5b9 | 836 | port->p_chassis->variable); \ |
1d88c843 | 837 | return (u_char *) \ |
7a53c5b9 | 838 | port->p_chassis->variable; \ |
1d88c843 VB |
839 | } \ |
840 | break | |
841 | ||
842 | LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_HW, | |
843 | c_med_hw); | |
844 | LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_SW, | |
845 | c_med_sw); | |
846 | LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_FW, | |
847 | c_med_fw); | |
848 | LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_SN, | |
849 | c_med_sn); | |
850 | LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_MANUF, | |
851 | c_med_manuf); | |
852 | LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_MODEL, | |
853 | c_med_model); | |
854 | LLDP_H_REMOTE_MED(LLDP_SNMP_MED_REMOTE_ASSET, | |
855 | c_med_asset); | |
856 | ||
857 | default: | |
4a2acc8e | 858 | return NULL; |
1d88c843 | 859 | } |
4a2acc8e VB |
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); | |
1d88c843 VB |
865 | return NULL; |
866 | } | |
4a2acc8e VB |
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; | |
7a53c5b9 | 873 | struct lldpd_port *port; |
4a2acc8e VB |
874 | struct lldpd_med_policy *policy; |
875 | static unsigned long long_ret; | |
876 | ||
7a53c5b9 | 877 | if ((port = header_tprindexed_table(vp, name, length, |
4a2acc8e VB |
878 | exact, var_len, write_method, TPR_VARIANT_MED_POLICY)) == NULL) |
879 | return NULL; | |
880 | ||
7a53c5b9 | 881 | if (!port->p_chassis->c_med_cap_available) { |
4a2acc8e VB |
882 | if (!exact && (name[*length-2] < MAX_SUBID)) |
883 | name[*length-2]++; | |
884 | goto remotemedpolicy_failed; | |
885 | } | |
886 | ||
887 | type = name[*length - 1]; | |
888 | if ((type < 1) || (type > LLDPMED_APPTYPE_LAST)) | |
889 | goto remotemedpolicy_failed; | |
7a53c5b9 | 890 | policy = &port->p_med_policy[type-1]; |
4a2acc8e VB |
891 | if (policy->type != type) |
892 | goto remotemedpolicy_failed; | |
893 | ||
894 | switch (vp->magic) { | |
895 | case LLDP_SNMP_MED_REMOTE_POLICY_VID: | |
896 | long_ret = policy->vid; | |
897 | return (u_char *)&long_ret; | |
898 | case LLDP_SNMP_MED_REMOTE_POLICY_PRIO: | |
899 | long_ret = policy->priority; | |
900 | return (u_char *)&long_ret; | |
901 | case LLDP_SNMP_MED_REMOTE_POLICY_DSCP: | |
902 | long_ret = policy->dscp; | |
903 | return (u_char *)&long_ret; | |
904 | case LLDP_SNMP_MED_REMOTE_POLICY_UNKNOWN: | |
905 | long_ret = policy->unknown?1:2; | |
906 | return (u_char *)&long_ret; | |
907 | case LLDP_SNMP_MED_REMOTE_POLICY_TAGGED: | |
908 | long_ret = policy->tagged?1:2; | |
909 | return (u_char *)&long_ret; | |
910 | default: | |
911 | return NULL; | |
912 | } | |
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; | |
7a53c5b9 | 926 | struct lldpd_port *port; |
4a2acc8e VB |
927 | struct lldpd_med_loc *location; |
928 | ||
7a53c5b9 | 929 | if ((port = header_tprindexed_table(vp, name, length, |
4a2acc8e VB |
930 | exact, var_len, write_method, TPR_VARIANT_MED_LOCATION)) == NULL) |
931 | return NULL; | |
932 | ||
7a53c5b9 | 933 | if (!port->p_chassis->c_med_cap_available) { |
4a2acc8e VB |
934 | if (!exact && (name[*length-2] < MAX_SUBID)) |
935 | name[*length-2]++; | |
936 | goto remotemedlocation_failed; | |
937 | } | |
938 | ||
939 | type = name[*length - 1]; | |
940 | if ((type < 1) || (type > LLDPMED_APPTYPE_LAST)) | |
941 | goto remotemedlocation_failed; | |
7a53c5b9 | 942 | location = &port->p_med_location[type-1]; |
4a2acc8e VB |
943 | if (location->format != type) |
944 | goto remotemedlocation_failed; | |
945 | ||
946 | switch (vp->magic) { | |
947 | case LLDP_SNMP_MED_REMOTE_LOCATION: | |
948 | *var_len = location->data_len; | |
949 | return (u_char *)location->data; | |
950 | default: | |
951 | return NULL; | |
952 | } | |
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 | } | |
1d88c843 VB |
960 | #endif |
961 | ||
43c02e7b VB |
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: | |
7a53c5b9 | 974 | long_ret = LOCAL_CHASSIS(scfg)->c_id_subtype; |
43c02e7b VB |
975 | return (u_char *)&long_ret; |
976 | case LLDP_SNMP_LOCAL_CID: | |
7a53c5b9 VB |
977 | *var_len = LOCAL_CHASSIS(scfg)->c_id_len; |
978 | return (u_char *)LOCAL_CHASSIS(scfg)->c_id; | |
43c02e7b | 979 | case LLDP_SNMP_LOCAL_SYSNAME: |
7a53c5b9 VB |
980 | *var_len = strlen(LOCAL_CHASSIS(scfg)->c_name); |
981 | return (u_char *)LOCAL_CHASSIS(scfg)->c_name; | |
43c02e7b | 982 | case LLDP_SNMP_LOCAL_SYSDESCR: |
7a53c5b9 VB |
983 | *var_len = strlen(LOCAL_CHASSIS(scfg)->c_descr); |
984 | return (u_char *)LOCAL_CHASSIS(scfg)->c_descr; | |
43c02e7b VB |
985 | case LLDP_SNMP_LOCAL_SYSCAP_SUP: |
986 | *var_len = 1; | |
7a53c5b9 | 987 | bit = swap_bits(LOCAL_CHASSIS(scfg)->c_cap_available); |
43c02e7b VB |
988 | return (u_char *)&bit; |
989 | case LLDP_SNMP_LOCAL_SYSCAP_ENA: | |
990 | *var_len = 1; | |
7a53c5b9 | 991 | bit = swap_bits(LOCAL_CHASSIS(scfg)->c_cap_enabled); |
43c02e7b VB |
992 | return (u_char *)&bit; |
993 | default: | |
994 | break; | |
995 | } | |
996 | return NULL; | |
997 | } | |
998 | ||
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: | |
37387046 VB |
1019 | /* We discard only frame with errors. Therefore, the two values |
1020 | * are equal */ | |
43c02e7b VB |
1021 | long_ret = hardware->h_rx_discarded_cnt; |
1022 | return (u_char *)&long_ret; | |
1023 | case LLDP_SNMP_STATS_RX_TLVDISCARDED: | |
1024 | case LLDP_SNMP_STATS_RX_TLVUNRECOGNIZED: | |
37387046 VB |
1025 | /* We discard only unrecognized TLV. Malformed TLV |
1026 | implies dropping the whole frame */ | |
1027 | long_ret = hardware->h_rx_unrecognized_cnt; | |
43c02e7b VB |
1028 | return (u_char *)&long_ret; |
1029 | case LLDP_SNMP_STATS_RX_AGEOUTS: | |
1030 | long_ret = hardware->h_rx_ageout_cnt; | |
1031 | return (u_char *)&long_ret; | |
1032 | default: | |
1033 | break; | |
1034 | } | |
1035 | return NULL; | |
1036 | } | |
1037 | ||
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 | { | |
a1347cd8 | 1042 | #ifdef ENABLE_DOT3 |
43c02e7b | 1043 | static uint8_t bit; |
a1347cd8 | 1044 | #endif |
43c02e7b VB |
1045 | struct lldpd_hardware *hardware; |
1046 | static unsigned long long_ret; | |
1047 | ||
1048 | if ((hardware = header_portindexed_table(vp, name, length, | |
1049 | exact, var_len, write_method)) == NULL) | |
1050 | return NULL; | |
1051 | ||
1052 | switch (vp->magic) { | |
1053 | case LLDP_SNMP_LOCAL_PIDSUBTYPE: | |
1054 | long_ret = hardware->h_lport.p_id_subtype; | |
1055 | return (u_char *)&long_ret; | |
1056 | case LLDP_SNMP_LOCAL_PID: | |
1057 | *var_len = hardware->h_lport.p_id_len; | |
1058 | return (u_char *)hardware->h_lport.p_id; | |
1059 | case LLDP_SNMP_LOCAL_PORTDESC: | |
1060 | *var_len = strlen(hardware->h_lport.p_descr); | |
1061 | return (u_char *)hardware->h_lport.p_descr; | |
a1347cd8 | 1062 | #ifdef ENABLE_DOT3 |
43c02e7b VB |
1063 | case LLDP_SNMP_LOCAL_DOT3_AUTONEG_SUPPORT: |
1064 | long_ret = 2 - hardware->h_lport.p_autoneg_support; | |
1065 | return (u_char *)&long_ret; | |
1066 | case LLDP_SNMP_LOCAL_DOT3_AUTONEG_ENABLED: | |
1067 | long_ret = 2 - hardware->h_lport.p_autoneg_enabled; | |
1068 | return (u_char *)&long_ret; | |
1069 | case LLDP_SNMP_LOCAL_DOT3_AUTONEG_ADVERTISED: | |
1070 | *var_len = 2; | |
1071 | return (u_char *)&hardware->h_lport.p_autoneg_advertised; | |
1072 | case LLDP_SNMP_LOCAL_DOT3_AUTONEG_MAU: | |
1073 | long_ret = hardware->h_lport.p_mau_type; | |
1074 | return (u_char *)&long_ret; | |
1075 | case LLDP_SNMP_LOCAL_DOT3_AGG_STATUS: | |
1076 | bit = swap_bits((hardware->h_lport.p_aggregid > 0) ? 3 : 0); | |
1077 | *var_len = 1; | |
1078 | return (u_char *)&bit; | |
1079 | case LLDP_SNMP_LOCAL_DOT3_AGG_ID: | |
1080 | long_ret = hardware->h_lport.p_aggregid; | |
1081 | return (u_char *)&long_ret; | |
548109b2 VB |
1082 | case LLDP_SNMP_LOCAL_DOT3_MFS: |
1083 | long_ret = hardware->h_lport.p_mfs; | |
1084 | return (u_char *)&long_ret; | |
75b3469d VB |
1085 | #endif |
1086 | #ifdef ENABLE_DOT1 | |
1087 | case LLDP_SNMP_LOCAL_DOT1_PVID: | |
1088 | long_ret = hardware->h_lport.p_pvid; /* Should always be 0 */ | |
1089 | return (u_char *)&long_ret; | |
a1347cd8 | 1090 | #endif |
43c02e7b VB |
1091 | default: |
1092 | break; | |
1093 | } | |
1094 | return NULL; | |
1095 | } | |
1096 | ||
a1347cd8 | 1097 | #ifdef ENABLE_DOT1 |
43c02e7b VB |
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 | } | |
a1347cd8 | 1137 | #endif |
43c02e7b VB |
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 | { | |
7a53c5b9 | 1143 | struct lldpd_port *port; |
43c02e7b VB |
1144 | static uint8_t bit; |
1145 | static unsigned long long_ret; | |
1146 | ||
7a53c5b9 | 1147 | if ((port = header_tprindexed_table(vp, name, length, |
4a2acc8e | 1148 | exact, var_len, write_method, TPR_VARIANT_NONE)) == NULL) |
43c02e7b VB |
1149 | return NULL; |
1150 | ||
1151 | switch (vp->magic) { | |
1152 | case LLDP_SNMP_REMOTE_CIDSUBTYPE: | |
7a53c5b9 | 1153 | long_ret = port->p_chassis->c_id_subtype; |
43c02e7b VB |
1154 | return (u_char *)&long_ret; |
1155 | case LLDP_SNMP_REMOTE_CID: | |
7a53c5b9 VB |
1156 | *var_len = port->p_chassis->c_id_len; |
1157 | return (u_char *)port->p_chassis->c_id; | |
43c02e7b | 1158 | case LLDP_SNMP_REMOTE_PIDSUBTYPE: |
7a53c5b9 | 1159 | long_ret = port->p_id_subtype; |
43c02e7b VB |
1160 | return (u_char *)&long_ret; |
1161 | case LLDP_SNMP_REMOTE_PID: | |
7a53c5b9 VB |
1162 | *var_len = port->p_id_len; |
1163 | return (u_char *)port->p_id; | |
43c02e7b | 1164 | case LLDP_SNMP_REMOTE_PORTDESC: |
7a53c5b9 VB |
1165 | *var_len = strlen(port->p_descr); |
1166 | return (u_char *)port->p_descr; | |
43c02e7b | 1167 | case LLDP_SNMP_REMOTE_SYSNAME: |
7a53c5b9 VB |
1168 | *var_len = strlen(port->p_chassis->c_name); |
1169 | return (u_char *)port->p_chassis->c_name; | |
43c02e7b | 1170 | case LLDP_SNMP_REMOTE_SYSDESC: |
7a53c5b9 VB |
1171 | *var_len = strlen(port->p_chassis->c_descr); |
1172 | return (u_char *)port->p_chassis->c_descr; | |
43c02e7b VB |
1173 | case LLDP_SNMP_REMOTE_SYSCAP_SUP: |
1174 | *var_len = 1; | |
7a53c5b9 | 1175 | bit = swap_bits(port->p_chassis->c_cap_available); |
43c02e7b VB |
1176 | return (u_char *)&bit; |
1177 | case LLDP_SNMP_REMOTE_SYSCAP_ENA: | |
1178 | *var_len = 1; | |
7a53c5b9 | 1179 | bit = swap_bits(port->p_chassis->c_cap_enabled); |
43c02e7b | 1180 | return (u_char *)&bit; |
a1347cd8 | 1181 | #ifdef ENABLE_DOT3 |
43c02e7b | 1182 | case LLDP_SNMP_REMOTE_DOT3_AUTONEG_SUPPORT: |
7a53c5b9 | 1183 | long_ret = 2 - port->p_autoneg_support; |
43c02e7b VB |
1184 | return (u_char *)&long_ret; |
1185 | case LLDP_SNMP_REMOTE_DOT3_AUTONEG_ENABLED: | |
7a53c5b9 | 1186 | long_ret = 2 - port->p_autoneg_enabled; |
43c02e7b VB |
1187 | return (u_char *)&long_ret; |
1188 | case LLDP_SNMP_REMOTE_DOT3_AUTONEG_ADVERTISED: | |
1189 | *var_len = 2; | |
7a53c5b9 | 1190 | return (u_char *)&port->p_autoneg_advertised; |
43c02e7b | 1191 | case LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU: |
7a53c5b9 | 1192 | long_ret = port->p_mau_type; |
43c02e7b VB |
1193 | return (u_char *)&long_ret; |
1194 | case LLDP_SNMP_REMOTE_DOT3_AGG_STATUS: | |
7a53c5b9 | 1195 | bit = swap_bits((port->p_aggregid > 0) ? 3 : 0); |
43c02e7b VB |
1196 | *var_len = 1; |
1197 | return (u_char *)&bit; | |
1198 | case LLDP_SNMP_REMOTE_DOT3_AGG_ID: | |
7a53c5b9 | 1199 | long_ret = port->p_aggregid; |
43c02e7b | 1200 | return (u_char *)&long_ret; |
548109b2 | 1201 | case LLDP_SNMP_REMOTE_DOT3_MFS: |
7a53c5b9 | 1202 | long_ret = port->p_mfs; |
548109b2 | 1203 | return (u_char *)&long_ret; |
75b3469d VB |
1204 | #endif |
1205 | #ifdef ENABLE_DOT1 | |
1206 | case LLDP_SNMP_REMOTE_DOT1_PVID: | |
7a53c5b9 | 1207 | long_ret = port->p_pvid; |
75b3469d | 1208 | return (u_char *)&long_ret; |
a1347cd8 | 1209 | #endif |
43c02e7b VB |
1210 | default: |
1211 | break; | |
1212 | } | |
1213 | return NULL; | |
1214 | } | |
1215 | ||
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 | ||
7a53c5b9 | 1254 | if (LOCAL_CHASSIS(scfg)->c_mgmt.s_addr == INADDR_ANY) |
43c02e7b VB |
1255 | return NULL; |
1256 | ||
1257 | if ((result = snmp_oid_compare(name, *length, vp->name, vp->namelen)) < 0) { | |
1258 | memcpy(name, vp->name, sizeof(oid) * vp->namelen); | |
1259 | *length = vp->namelen; | |
1260 | } | |
1261 | ||
1262 | *write_method = 0; | |
1263 | *var_len = sizeof(long); | |
1264 | ||
1265 | target = &name[vp->namelen]; | |
1266 | target_len = *length - vp->namelen; | |
1267 | ||
1268 | best[0] = 1; | |
1269 | best[1] = 4; | |
7a53c5b9 VB |
1270 | best[5] = LOCAL_CHASSIS(scfg)->c_mgmt.s_addr >> 24; |
1271 | best[4] = (LOCAL_CHASSIS(scfg)->c_mgmt.s_addr & 0xffffff) >> 16; | |
1272 | best[3] = (LOCAL_CHASSIS(scfg)->c_mgmt.s_addr & 0xffff) >> 8; | |
1273 | best[2] = LOCAL_CHASSIS(scfg)->c_mgmt.s_addr & 0xff; | |
43c02e7b | 1274 | |
bff3c98d | 1275 | if ((result = snmp_oid_compare(target, target_len, best, 6)) < 0) { |
43c02e7b VB |
1276 | if (exact) |
1277 | return NULL; | |
1278 | memcpy(target, best, sizeof(oid) * 6); | |
1279 | *length = vp->namelen + 6; | |
1280 | } else if (exact && (result != 0)) | |
1281 | return NULL; | |
1282 | else if (!exact && result == 0) | |
1283 | return NULL; | |
1284 | ||
7a53c5b9 | 1285 | return agent_management(vp, var_len, LOCAL_CHASSIS(scfg)); |
43c02e7b VB |
1286 | } |
1287 | ||
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 | { | |
7a53c5b9 | 1292 | struct lldpd_port *port; |
43c02e7b | 1293 | |
7a53c5b9 | 1294 | if ((port = header_tprindexed_table(vp, name, length, |
4a2acc8e | 1295 | exact, var_len, write_method, TPR_VARIANT_IP)) == NULL) |
43c02e7b VB |
1296 | return NULL; |
1297 | ||
7a53c5b9 | 1298 | return agent_management(vp, var_len, port->p_chassis); |
43c02e7b VB |
1299 | } |
1300 | ||
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}}, | |
a1347cd8 | 1332 | #ifdef ENABLE_DOT3 |
43c02e7b VB |
1333 | {LLDP_SNMP_LOCAL_DOT3_AUTONEG_SUPPORT, ASN_INTEGER, RONLY, agent_h_local_port, 8, |
1334 | {1, 5, 4623, 1, 2, 1, 1, 1}}, | |
1335 | {LLDP_SNMP_LOCAL_DOT3_AUTONEG_ENABLED, ASN_INTEGER, RONLY, agent_h_local_port, 8, | |
1336 | {1, 5, 4623, 1, 2, 1, 1, 2}}, | |
1337 | {LLDP_SNMP_LOCAL_DOT3_AUTONEG_ADVERTISED, ASN_OCTET_STR, RONLY, agent_h_local_port, 8, | |
1338 | {1, 5, 4623, 1, 2, 1, 1, 3}}, | |
1339 | {LLDP_SNMP_LOCAL_DOT3_AUTONEG_MAU, ASN_INTEGER, RONLY, agent_h_local_port, 8, | |
1340 | {1, 5, 4623, 1, 2, 1, 1, 4}}, | |
1341 | {LLDP_SNMP_LOCAL_DOT3_AGG_STATUS, ASN_OCTET_STR, RONLY, agent_h_local_port, 8, | |
1342 | {1, 5, 4623, 1, 2, 3, 1, 1}}, | |
1343 | {LLDP_SNMP_LOCAL_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_local_port, 8, | |
1344 | {1, 5, 4623, 1, 2, 3, 1, 2}}, | |
548109b2 VB |
1345 | {LLDP_SNMP_LOCAL_DOT3_MFS, ASN_INTEGER, RONLY, agent_h_local_port, 8, |
1346 | {1, 5, 4623, 1, 2, 4, 1, 1}}, | |
75b3469d VB |
1347 | #endif |
1348 | #ifdef ENABLE_DOT1 | |
1349 | {LLDP_SNMP_LOCAL_DOT1_PVID, ASN_INTEGER, RONLY, agent_h_local_port, 8, | |
1350 | {1, 5, 32962, 1, 2, 1, 1, 1}}, | |
a1347cd8 | 1351 | #endif |
43c02e7b VB |
1352 | /* Remote ports */ |
1353 | {LLDP_SNMP_REMOTE_CIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 4}}, | |
1354 | {LLDP_SNMP_REMOTE_CID, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 5}}, | |
1355 | {LLDP_SNMP_REMOTE_PIDSUBTYPE, ASN_INTEGER, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 6}}, | |
1356 | {LLDP_SNMP_REMOTE_PID, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 7}}, | |
1357 | {LLDP_SNMP_REMOTE_PORTDESC, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 8}}, | |
1358 | {LLDP_SNMP_REMOTE_SYSNAME, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 9}}, | |
1359 | {LLDP_SNMP_REMOTE_SYSDESC, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 10}}, | |
1360 | {LLDP_SNMP_REMOTE_SYSCAP_SUP, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 11}}, | |
1361 | {LLDP_SNMP_REMOTE_SYSCAP_ENA, ASN_OCTET_STR, RONLY, agent_h_remote_port, 5, {1, 4, 1, 1, 12}}, | |
a1347cd8 | 1362 | #ifdef ENABLE_DOT3 |
43c02e7b VB |
1363 | {LLDP_SNMP_REMOTE_DOT3_AUTONEG_SUPPORT, ASN_INTEGER, RONLY, agent_h_remote_port, 8, |
1364 | {1, 5, 4623, 1, 3, 1, 1, 1}}, | |
1365 | {LLDP_SNMP_REMOTE_DOT3_AUTONEG_ENABLED, ASN_INTEGER, RONLY, agent_h_remote_port, 8, | |
1366 | {1, 5, 4623, 1, 3, 1, 1, 2}}, | |
1367 | {LLDP_SNMP_REMOTE_DOT3_AUTONEG_ADVERTISED, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8, | |
1368 | {1, 5, 4623, 1, 3, 1, 1, 3}}, | |
1369 | {LLDP_SNMP_REMOTE_DOT3_AUTONEG_MAU, ASN_INTEGER, RONLY, agent_h_remote_port, 8, | |
1370 | {1, 5, 4623, 1, 3, 1, 1, 4}}, | |
1371 | {LLDP_SNMP_REMOTE_DOT3_AGG_STATUS, ASN_OCTET_STR, RONLY, agent_h_remote_port, 8, | |
1372 | {1, 5, 4623, 1, 3, 3, 1, 1}}, | |
1373 | {LLDP_SNMP_REMOTE_DOT3_AGG_ID, ASN_INTEGER, RONLY, agent_h_remote_port, 8, | |
1374 | {1, 5, 4623, 1, 3, 3, 1, 2}}, | |
548109b2 VB |
1375 | {LLDP_SNMP_REMOTE_DOT3_MFS, ASN_INTEGER, RONLY, agent_h_remote_port, 8, |
1376 | {1, 5, 4623, 1, 3, 4, 1, 1}}, | |
a1347cd8 VB |
1377 | #endif |
1378 | #ifdef ENABLE_DOT1 | |
75b3469d VB |
1379 | {LLDP_SNMP_REMOTE_DOT1_PVID, ASN_INTEGER, RONLY, agent_h_remote_port, 8, |
1380 | {1, 5, 32962, 1, 3, 1, 1, 1}}, | |
43c02e7b VB |
1381 | /* Local vlans */ |
1382 | {LLDP_SNMP_LOCAL_DOT1_VLANNAME, ASN_OCTET_STR, RONLY, agent_h_local_vlan, 8, | |
1383 | {1, 5, 32962, 1, 2, 3, 1, 2}}, | |
1384 | /* Remote vlans */ | |
1385 | {LLDP_SNMP_REMOTE_DOT1_VLANNAME, ASN_OCTET_STR, RONLY, agent_h_remote_vlan, 8, | |
1386 | {1, 5, 32962, 1, 3, 3, 1, 2}}, | |
a1347cd8 | 1387 | #endif |
43c02e7b VB |
1388 | /* Management address */ |
1389 | {LLDP_SNMP_LOCAL_ADDR_LEN, ASN_INTEGER, RONLY, agent_h_local_management, 5, | |
1390 | {1, 3, 8, 1, 3}}, | |
1391 | {LLDP_SNMP_LOCAL_ADDR_IFSUBTYPE, ASN_INTEGER, RONLY, agent_h_local_management, 5, | |
1392 | {1, 3, 8, 1, 4}}, | |
1393 | {LLDP_SNMP_LOCAL_ADDR_IFID, ASN_INTEGER, RONLY, agent_h_local_management, 5, | |
1394 | {1, 3, 8, 1, 5}}, | |
1395 | {LLDP_SNMP_LOCAL_ADDR_OID, ASN_OBJECT_ID, RONLY, agent_h_local_management, 5, | |
1396 | {1, 3, 8, 1, 6}}, | |
1397 | {LLDP_SNMP_REMOTE_ADDR_IFSUBTYPE, ASN_INTEGER, RONLY, agent_h_remote_management, 5, | |
1398 | {1, 4, 2, 1, 3}}, | |
1399 | {LLDP_SNMP_REMOTE_ADDR_IFID, ASN_INTEGER, RONLY, agent_h_remote_management, 5, | |
1400 | {1, 4, 2, 1, 4}}, | |
1401 | {LLDP_SNMP_REMOTE_ADDR_OID, ASN_OBJECT_ID, RONLY, agent_h_remote_management, 5, | |
1402 | {1, 4, 2, 1, 5}}, | |
1d88c843 VB |
1403 | #ifdef ENABLE_LLDPMED |
1404 | /* LLDP-MED local */ | |
1405 | {LLDP_SNMP_MED_LOCAL_CLASS, ASN_INTEGER, RONLY, agent_h_local_med, 6, | |
1406 | {1, 5, 4795, 1, 1, 1}}, | |
fd6aa9a3 VB |
1407 | {LLDP_SNMP_MED_LOCAL_POLICY_VID, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8, |
1408 | {1, 5, 4795, 1, 2, 1, 1, 2}}, | |
1409 | {LLDP_SNMP_MED_LOCAL_POLICY_PRIO, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8, | |
1410 | {1, 5, 4795, 1, 2, 1, 1, 3}}, | |
1411 | {LLDP_SNMP_MED_LOCAL_POLICY_DSCP, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8, | |
1412 | {1, 5, 4795, 1, 2, 1, 1, 4}}, | |
1413 | {LLDP_SNMP_MED_LOCAL_POLICY_UNKNOWN, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8, | |
1414 | {1, 5, 4795, 1, 2, 1, 1, 5}}, | |
1415 | {LLDP_SNMP_MED_LOCAL_POLICY_TAGGED, ASN_INTEGER, RONLY, agent_h_local_med_policy, 8, | |
1416 | {1, 5, 4795, 1, 2, 1, 1, 6}}, | |
1d88c843 VB |
1417 | {LLDP_SNMP_MED_LOCAL_HW, ASN_OCTET_STR, RONLY, agent_h_local_med, 6, |
1418 | {1, 5, 4795, 1, 2, 2}}, | |
1419 | {LLDP_SNMP_MED_LOCAL_FW, ASN_OCTET_STR, RONLY, agent_h_local_med, 6, | |
1420 | {1, 5, 4795, 1, 2, 3}}, | |
1421 | {LLDP_SNMP_MED_LOCAL_SW, ASN_OCTET_STR, RONLY, agent_h_local_med, 6, | |
1422 | {1, 5, 4795, 1, 2, 4}}, | |
1423 | {LLDP_SNMP_MED_LOCAL_SN, ASN_OCTET_STR, RONLY, agent_h_local_med, 6, | |
1424 | {1, 5, 4795, 1, 2, 5}}, | |
1425 | {LLDP_SNMP_MED_LOCAL_MANUF, ASN_OCTET_STR, RONLY, agent_h_local_med, 6, | |
1426 | {1, 5, 4795, 1, 2, 6}}, | |
1427 | {LLDP_SNMP_MED_LOCAL_MODEL, ASN_OCTET_STR, RONLY, agent_h_local_med, 6, | |
1428 | {1, 5, 4795, 1, 2, 7}}, | |
1429 | {LLDP_SNMP_MED_LOCAL_ASSET, ASN_OCTET_STR, RONLY, agent_h_local_med, 6, | |
1430 | {1, 5, 4795, 1, 2, 8}}, | |
1dcd4665 VB |
1431 | {LLDP_SNMP_MED_LOCAL_LOCATION, ASN_OCTET_STR, RONLY, agent_h_local_med_location, 8, |
1432 | {1, 5, 4795, 1, 2, 9, 1, 2}}, | |
8e44f2dc VB |
1433 | {LLDP_SNMP_MED_POE_DEVICETYPE, ASN_INTEGER, RONLY, agent_h_local_med, 6, |
1434 | {1, 5, 4795, 1, 2, 10}}, | |
1435 | {LLDP_SNMP_MED_POE_PSE_POWERVAL, ASN_GAUGE, RONLY, agent_h_local_med_power, 8, | |
1436 | {1, 5, 4795, 1, 2, 11, 1, 1}}, | |
1437 | {LLDP_SNMP_MED_POE_PSE_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_local_med_power, 8, | |
1438 | {1, 5, 4795, 1, 2, 11, 1, 2}}, | |
1439 | {LLDP_SNMP_MED_POE_PSE_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_local_med, 6, | |
1440 | {1, 5, 4795, 1, 2, 12}}, | |
1441 | {LLDP_SNMP_MED_POE_PD_POWERVAL, ASN_GAUGE, RONLY, agent_h_local_med, 6, | |
1442 | {1, 5, 4795, 1, 2, 13}}, | |
1443 | {LLDP_SNMP_MED_POE_PD_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_local_med, 6, | |
1444 | {1, 5, 4795, 1, 2, 14}}, | |
1445 | {LLDP_SNMP_MED_POE_PD_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_local_med, 6, | |
1446 | {1, 5, 4795, 1, 2, 15}}, | |
1d88c843 | 1447 | /* LLDP-MED remote */ |
40ecae87 | 1448 | {LLDP_SNMP_MED_REMOTE_CAP_AVAILABLE, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8, |
1d88c843 | 1449 | {1, 5, 4795, 1, 3, 1, 1, 1}}, |
40ecae87 | 1450 | {LLDP_SNMP_MED_REMOTE_CAP_ENABLED, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8, |
1d88c843 VB |
1451 | {1, 5, 4795, 1, 3, 1, 1, 2}}, |
1452 | {LLDP_SNMP_MED_REMOTE_CLASS, ASN_INTEGER, RONLY, agent_h_remote_med, 8, | |
1453 | {1, 5, 4795, 1, 3, 1, 1, 3}}, | |
1454 | {LLDP_SNMP_MED_REMOTE_HW, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8, | |
1455 | {1, 5, 4795, 1, 3, 3, 1, 1}}, | |
1456 | {LLDP_SNMP_MED_REMOTE_FW, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8, | |
1457 | {1, 5, 4795, 1, 3, 3, 1, 2}}, | |
1458 | {LLDP_SNMP_MED_REMOTE_SW, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8, | |
1459 | {1, 5, 4795, 1, 3, 3, 1, 3}}, | |
1460 | {LLDP_SNMP_MED_REMOTE_SN, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8, | |
1461 | {1, 5, 4795, 1, 3, 3, 1, 4}}, | |
1462 | {LLDP_SNMP_MED_REMOTE_MANUF, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8, | |
1463 | {1, 5, 4795, 1, 3, 3, 1, 5}}, | |
1464 | {LLDP_SNMP_MED_REMOTE_MODEL, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8, | |
1465 | {1, 5, 4795, 1, 3, 3, 1, 6}}, | |
1466 | {LLDP_SNMP_MED_REMOTE_ASSET, ASN_OCTET_STR, RONLY, agent_h_remote_med, 8, | |
1467 | {1, 5, 4795, 1, 3, 3, 1, 7}}, | |
4a2acc8e VB |
1468 | {LLDP_SNMP_MED_REMOTE_POLICY_VID, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8, |
1469 | {1, 5, 4795, 1, 3, 2, 1, 2}}, | |
1470 | {LLDP_SNMP_MED_REMOTE_POLICY_PRIO, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8, | |
1471 | {1, 5, 4795, 1, 3, 2, 1, 3}}, | |
1472 | {LLDP_SNMP_MED_REMOTE_POLICY_DSCP, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8, | |
1473 | {1, 5, 4795, 1, 3, 2, 1, 4}}, | |
1474 | {LLDP_SNMP_MED_REMOTE_POLICY_UNKNOWN, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8, | |
1475 | {1, 5, 4795, 1, 3, 2, 1, 5}}, | |
1476 | {LLDP_SNMP_MED_REMOTE_POLICY_TAGGED, ASN_INTEGER, RONLY, agent_h_remote_med_policy, 8, | |
1477 | {1, 5, 4795, 1, 3, 2, 1, 6}}, | |
1478 | {LLDP_SNMP_MED_REMOTE_LOCATION, ASN_OCTET_STR, RONLY, agent_h_remote_med_location, 8, | |
1479 | {1, 5, 4795, 1, 3, 4, 1, 2}}, | |
8e44f2dc | 1480 | {LLDP_SNMP_MED_POE_DEVICETYPE, ASN_INTEGER, RONLY, agent_h_remote_med, 8, |
1be9e1b5 | 1481 | {1, 5, 4795, 1, 3, 5, 1, 1}}, |
8e44f2dc | 1482 | {LLDP_SNMP_MED_POE_PSE_POWERVAL, ASN_GAUGE, RONLY, agent_h_remote_med, 8, |
1be9e1b5 | 1483 | {1, 5, 4795, 1, 3, 6, 1, 1}}, |
8e44f2dc | 1484 | {LLDP_SNMP_MED_POE_PSE_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_remote_med, 8, |
1be9e1b5 | 1485 | {1, 5, 4795, 1, 3, 6, 1, 2}}, |
8e44f2dc | 1486 | {LLDP_SNMP_MED_POE_PSE_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_remote_med, 8, |
1be9e1b5 | 1487 | {1, 5, 4795, 1, 3, 6, 1, 3}}, |
8e44f2dc | 1488 | {LLDP_SNMP_MED_POE_PD_POWERVAL, ASN_GAUGE, RONLY, agent_h_remote_med, 8, |
1be9e1b5 | 1489 | {1, 5, 4795, 1, 3, 7, 1, 1}}, |
8e44f2dc | 1490 | {LLDP_SNMP_MED_POE_PD_POWERSOURCE, ASN_INTEGER, RONLY, agent_h_remote_med, 8, |
1be9e1b5 | 1491 | {1, 5, 4795, 1, 3, 7, 1, 2}}, |
8e44f2dc | 1492 | {LLDP_SNMP_MED_POE_PD_POWERPRIORITY, ASN_INTEGER, RONLY, agent_h_remote_med, 8, |
1be9e1b5 | 1493 | {1, 5, 4795, 1, 3, 7, 1, 3}}, |
1d88c843 | 1494 | #endif |
43c02e7b VB |
1495 | }; |
1496 | ||
1497 | void | |
bbea66e1 | 1498 | agent_init(struct lldpd *cfg, char *agentx, int debug) |
43c02e7b VB |
1499 | { |
1500 | int rc; | |
6bb9c4e0 | 1501 | #ifdef HAVE___PROGNAME |
43c02e7b | 1502 | extern char *__progname; |
6bb9c4e0 VB |
1503 | #else |
1504 | # define __progname "lldpd" | |
1505 | #endif | |
43c02e7b VB |
1506 | |
1507 | LLOG_INFO("Enable SNMP subagent"); | |
1508 | netsnmp_enable_subagent(); | |
1509 | snmp_disable_log(); | |
1510 | if (debug) | |
1511 | snmp_enable_stderrlog(); | |
1512 | else | |
1513 | snmp_enable_syslog_ident(__progname, LOG_DAEMON); | |
1514 | ||
1515 | scfg = cfg; | |
1516 | ||
37954d62 VB |
1517 | /* We are chrooted, we don't want to handle persistent states */ |
1518 | netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, | |
1519 | NETSNMP_DS_LIB_DONT_PERSIST_STATE, TRUE); | |
1520 | /* Do not load any MIB */ | |
1521 | setenv("MIBS", "", 1); | |
43c02e7b | 1522 | |
d72a05d4 VB |
1523 | /* We provide our UNIX domain transport */ |
1524 | agent_priv_register_domain(); | |
1525 | ||
bbea66e1 V |
1526 | if (agentx) |
1527 | netsnmp_ds_set_string(NETSNMP_DS_APPLICATION_ID, | |
1528 | NETSNMP_DS_AGENT_X_SOCKET, agentx); | |
37954d62 | 1529 | init_agent("lldpAgent"); |
43c02e7b | 1530 | REGISTER_MIB("lldp", lldp_vars, variable8, lldp_oid); |
43c02e7b VB |
1531 | init_snmp("lldpAgent"); |
1532 | ||
1533 | if ((rc = register_sysORTable(lldp_oid, OID_LENGTH(lldp_oid), | |
1534 | "lldpMIB implementation by lldpd")) != 0) | |
1535 | LLOG_WARNX("Unable to register to sysORTable (%d)", rc); | |
1536 | } | |
1537 | ||
1538 | void | |
1539 | agent_shutdown() | |
1540 | { | |
1541 | unregister_sysORTable(lldp_oid, OID_LENGTH(lldp_oid)); | |
1542 | snmp_shutdown("lldpAgent"); | |
1543 | } |