lldp_mib_impl_config.c
Go to the documentation of this file.
1 /**
2  * @file lldp_mib_impl_config.c
3  * @brief LLDP MIB module implementation (lldpConfiguration subtree)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL SNMP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "mibs/mib_common.h"
37 #include "mibs/lldp_mib_module.h"
38 #include "mibs/lldp_mib_impl.h"
40 #include "core/crypto.h"
41 #include "encoding/asn1.h"
42 #include "encoding/oid.h"
43 #include "lldp/lldp_mgmt.h"
44 #include "debug.h"
45 
46 //Check TCP/IP stack configuration
47 #if (LLDP_MIB_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Set lldpMessageTxInterval object value
52  * @param[in] object Pointer to the MIB object descriptor
53  * @param[in] oid Object identifier (object name and instance identifier)
54  * @param[in] oidLen Length of the OID, in bytes
55  * @param[in] value Object value
56  * @param[in] valueLen Length of the object value, in bytes
57  * @param[in] commit This flag tells whether the changes shall be committed
58  * to the MIB base
59  * @return Error code
60  **/
61 
62 error_t lldpMibSetLldpMessageTxInterval(const MibObject *object, const uint8_t *oid,
63  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
64 {
65 #if (LLDP_MIB_SET_SUPPORT == ENABLED)
66  error_t error;
67 
68  //Ensure that the supplied value is valid
69  if(value->integer >= 0)
70  {
71  //This object specifies the interval at which LLDP frames are transmitted
72  //on behalf of this LLDP agent
74  value->integer, commit);
75  }
76  else
77  {
78  //Report an error
79  error = ERROR_WRONG_VALUE;
80  }
81 
82  //Return status code
83  return error;
84 #else
85  //SET operation is not supported
86  return ERROR_WRITE_FAILED;
87 #endif
88 }
89 
90 
91 /**
92  * @brief Get lldpMessageTxInterval object value
93  * @param[in] object Pointer to the MIB object descriptor
94  * @param[in] oid Object identifier (object name and instance identifier)
95  * @param[in] oidLen Length of the OID, in bytes
96  * @param[out] value Object value
97  * @param[in,out] valueLen Length of the object value, in bytes
98  * @return Error code
99  **/
100 
101 error_t lldpMibGetLldpMessageTxInterval(const MibObject *object, const uint8_t *oid,
102  size_t oidLen, MibVariant *value, size_t *valueLen)
103 {
104  error_t error;
105  uint_t msgTxInterval;
106 
107  //This object specifies the interval at which LLDP frames are transmitted
108  //on behalf of this LLDP agent
110  &msgTxInterval);
111 
112  //Check status code
113  if(!error)
114  {
115  //Return the value of the object
116  value->integer = msgTxInterval;
117  }
118 
119  //Return status code
120  return error;
121 }
122 
123 
124 /**
125  * @brief Set lldpMessageTxHoldMultiplier object value
126  * @param[in] object Pointer to the MIB object descriptor
127  * @param[in] oid Object identifier (object name and instance identifier)
128  * @param[in] oidLen Length of the OID, in bytes
129  * @param[in] value Object value
130  * @param[in] valueLen Length of the object value, in bytes
131  * @param[in] commit This flag tells whether the changes shall be committed
132  * to the MIB base
133  * @return Error code
134  **/
135 
137  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
138 {
139 #if (LLDP_MIB_SET_SUPPORT == ENABLED)
140  error_t error;
141 
142  //Ensure that the supplied value is valid
143  if(value->integer >= 0)
144  {
145  //This object specifies the multiplier on the msgTxInterval that
146  //determines the actual TTL value used in an LLDPDU
148  value->integer, commit);
149  }
150  else
151  {
152  //Report an error
153  error = ERROR_WRONG_VALUE;
154  }
155 
156  //Return status code
157  return error;
158 #else
159  //SET operation is not supported
160  return ERROR_WRITE_FAILED;
161 #endif
162 }
163 
164 
165 /**
166  * @brief Get lldpMessageTxHoldMultiplier object value
167  * @param[in] object Pointer to the MIB object descriptor
168  * @param[in] oid Object identifier (object name and instance identifier)
169  * @param[in] oidLen Length of the OID, in bytes
170  * @param[out] value Object value
171  * @param[in,out] valueLen Length of the object value, in bytes
172  * @return Error code
173  **/
174 
176  size_t oidLen, MibVariant *value, size_t *valueLen)
177 {
178  error_t error;
179  uint_t msgTxHold;
180 
181  //This object specifies the multiplier on the msgTxInterval that
182  //determines the actual TTL value used in an LLDPDU
184 
185  //Check status code
186  if(!error)
187  {
188  //Return the value of the object
189  value->integer = msgTxHold;
190  }
191 
192  //Return status code
193  return error;
194 }
195 
196 
197 /**
198  * @brief Set lldpReinitDelay object value
199  * @param[in] object Pointer to the MIB object descriptor
200  * @param[in] oid Object identifier (object name and instance identifier)
201  * @param[in] oidLen Length of the OID, in bytes
202  * @param[in] value Object value
203  * @param[in] valueLen Length of the object value, in bytes
204  * @param[in] commit This flag tells whether the changes shall be committed
205  * to the MIB base
206  * @return Error code
207  **/
208 
209 error_t lldpMibSetLldpReinitDelay(const MibObject *object, const uint8_t *oid,
210  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
211 {
212 #if (LLDP_MIB_SET_SUPPORT == ENABLED)
213  error_t error;
214 
215  //Ensure that the supplied value is valid
216  if(value->integer >= 0)
217  {
218  //This object indicates the delay (in units of seconds) from when
219  //lldpPortConfigAdminStatus object of a particular port becomes disabled
220  //until re-initialization will be attempted
222  value->integer, commit);
223  }
224  else
225  {
226  //Report an error
227  error = ERROR_WRONG_VALUE;
228  }
229 
230  //Return status code
231  return error;
232 #else
233  //SET operation is not supported
234  return ERROR_WRITE_FAILED;
235 #endif
236 }
237 
238 
239 /**
240  * @brief Get lldpReinitDelay object value
241  * @param[in] object Pointer to the MIB object descriptor
242  * @param[in] oid Object identifier (object name and instance identifier)
243  * @param[in] oidLen Length of the OID, in bytes
244  * @param[out] value Object value
245  * @param[in,out] valueLen Length of the object value, in bytes
246  * @return Error code
247  **/
248 
249 error_t lldpMibGetLldpReinitDelay(const MibObject *object, const uint8_t *oid,
250  size_t oidLen, MibVariant *value, size_t *valueLen)
251 {
252  error_t error;
253  uint_t reinitDelay;
254 
255  //This object indicates the delay (in units of seconds) from when
256  //lldpPortConfigAdminStatus object of a particular port becomes disabled
257  //until re-initialization will be attempted
258  error = lldpMgmtGetReinitDelay(lldpMibBase.lldpAgentContext, &reinitDelay);
259 
260  //Check status code
261  if(!error)
262  {
263  //Return the value of the object
264  value->integer = reinitDelay;
265  }
266 
267  //Return status code
268  return error;
269 }
270 
271 
272 /**
273  * @brief Set lldpTxDelay object value
274  * @param[in] object Pointer to the MIB object descriptor
275  * @param[in] oid Object identifier (object name and instance identifier)
276  * @param[in] oidLen Length of the OID, in bytes
277  * @param[in] value Object value
278  * @param[in] valueLen Length of the object value, in bytes
279  * @param[in] commit This flag tells whether the changes shall be committed
280  * to the MIB base
281  * @return Error code
282  **/
283 
284 error_t lldpMibSetLldpTxDelay(const MibObject *object, const uint8_t *oid,
285  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
286 {
287 #if (LLDP_MIB_SET_SUPPORT == ENABLED)
288  error_t error;
289 
290  //Ensure that the supplied value is valid
291  if(value->integer >= 0)
292  {
293  //This object indicates the delay (in units of seconds) between successive
294  //LLDP frame transmissions initiated by value/status changes in the LLDP
295  //local systems MIB
297  value->integer, commit);
298  }
299  else
300  {
301  //Report an error
302  error = ERROR_WRONG_VALUE;
303  }
304 
305  //Return status code
306  return error;
307 #else
308  //SET operation is not supported
309  return ERROR_WRITE_FAILED;
310 #endif
311 }
312 
313 
314 /**
315  * @brief Get lldpTxDelay object value
316  * @param[in] object Pointer to the MIB object descriptor
317  * @param[in] oid Object identifier (object name and instance identifier)
318  * @param[in] oidLen Length of the OID, in bytes
319  * @param[out] value Object value
320  * @param[in,out] valueLen Length of the object value, in bytes
321  * @return Error code
322  **/
323 
324 error_t lldpMibGetLldpTxDelay(const MibObject *object, const uint8_t *oid,
325  size_t oidLen, MibVariant *value, size_t *valueLen)
326 {
327  error_t error;
328  uint_t txDelay;
329 
330  //This object indicates the delay (in units of seconds) between successive
331  //LLDP frame transmissions initiated by value/status changes in the LLDP
332  //local systems MIB
334 
335  //Check status code
336  if(!error)
337  {
338  //Return the value of the object
339  value->integer = txDelay;
340  }
341 
342  //Return status code
343  return error;
344 }
345 
346 
347 /**
348  * @brief Set lldpNotificationInterval object value
349  * @param[in] object Pointer to the MIB object descriptor
350  * @param[in] oid Object identifier (object name and instance identifier)
351  * @param[in] oidLen Length of the OID, in bytes
352  * @param[in] value Object value
353  * @param[in] valueLen Length of the object value, in bytes
354  * @param[in] commit This flag tells whether the changes shall be committed
355  * to the MIB base
356  * @return Error code
357  **/
358 
360  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
361 {
362 #if (LLDP_MIB_SET_SUPPORT == ENABLED)
363  error_t error;
364 
365  //Ensure that the supplied value is valid
366  if(value->integer >= 0)
367  {
368  //This object controls the transmission of LLDP notifications
370  value->integer, commit);
371  }
372  else
373  {
374  //Report an error
375  error = ERROR_WRONG_VALUE;
376  }
377 
378  //Return status code
379  return error;
380 #else
381  //SET operation is not supported
382  return ERROR_WRITE_FAILED;
383 #endif
384 }
385 
386 
387 /**
388  * @brief Get lldpNotificationInterval object value
389  * @param[in] object Pointer to the MIB object descriptor
390  * @param[in] oid Object identifier (object name and instance identifier)
391  * @param[in] oidLen Length of the OID, in bytes
392  * @param[out] value Object value
393  * @param[in,out] valueLen Length of the object value, in bytes
394  * @return Error code
395  **/
396 
398  size_t oidLen, MibVariant *value, size_t *valueLen)
399 {
400  error_t error;
401  uint_t notificationInterval;
402 
403  //This object controls the transmission of LLDP notifications
405  &notificationInterval);
406 
407  //Check status code
408  if(!error)
409  {
410  //Return the value of the object
411  value->integer = notificationInterval;
412  }
413 
414  //Return status code
415  return error;
416 }
417 
418 
419 /**
420  * @brief Set lldpPortConfigEntry object value
421  * @param[in] object Pointer to the MIB object descriptor
422  * @param[in] oid Object identifier (object name and instance identifier)
423  * @param[in] oidLen Length of the OID, in bytes
424  * @param[in] value Object value
425  * @param[in] valueLen Length of the object value, in bytes
426  * @param[in] commit This flag tells whether the changes shall be committed
427  * to the MIB base
428  * @return Error code
429  **/
430 
431 error_t lldpMibSetLldpPortConfigEntry(const MibObject *object, const uint8_t *oid,
432  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
433 {
434 #if (LLDP_MIB_SET_SUPPORT == ENABLED)
435  error_t error;
436  size_t n;
437  uint_t lldpPortConfigPortNum;
438 
439  //Point to the instance identifier
440  n = object->oidLen;
441 
442  //lldpPortConfigPortNum is used as instance identifier
443  error = mibDecodeIndex(oid, oidLen, &n, &lldpPortConfigPortNum);
444  //Invalid instance identifier?
445  if(error)
446  return error;
447 
448  //Sanity check
449  if(n != oidLen)
451 
452  //lldpPortConfigAdminStatus object?
453  if(!strcmp(object->name, "lldpPortConfigAdminStatus"))
454  {
455  //This object specifies the administrative status of the local LLDP agent
456  if(value->integer == LLDP_MIB_ADMIN_STATUS_DISABLED)
457  {
458  //The LLDP agent will not transmit or receive LLDP frames on this port
460  lldpPortConfigPortNum, LLDP_ADMIN_STATUS_DISABLED, commit);
461  }
462  else if(value->integer == LLDP_MIB_ADMIN_STATUS_ENABLED_TX_ONLY)
463  {
464  //The LLDP agent will transmit LLDP frames on this port, but it will
465  //not store any information about the remote systems connected
467  lldpPortConfigPortNum, LLDP_ADMIN_STATUS_ENABLED_TX_ONLY, commit);
468  }
469  else if(value->integer == LLDP_MIB_ADMIN_STATUS_ENABLED_RX_ONLY)
470  {
471  //The LLDP agent will receive, but it will not transmit LLDP frames
472  //on this port
474  lldpPortConfigPortNum, LLDP_ADMIN_STATUS_ENABLED_RX_ONLY, commit);
475  }
476  else if(value->integer == LLDP_MIB_ADMIN_STATUS_ENABLED_TX_RX)
477  {
478  //The LLDP agent will transmit and receive LLDP frames on this port
480  lldpPortConfigPortNum, LLDP_ADMIN_STATUS_ENABLED_TX_RX, commit);
481  }
482  else
483  {
484  //Invalid parameter
485  error = ERROR_WRONG_VALUE;
486  }
487  }
488  //lldpPortConfigNotificationEnable object?
489  else if(!strcmp(object->name, "lldpPortConfigNotificationEnable"))
490  {
491  //This object controls, on a per port basis, whether or not notifications
492  //from the agent are enabled
493  if(value->integer == MIB_TRUTH_VALUE_TRUE)
494  {
495  //Disable notifications
497  lldpPortConfigPortNum, TRUE, commit);
498  }
499  else if(value->integer == MIB_TRUTH_VALUE_FALSE)
500  {
501  //Enable notifications
503  lldpPortConfigPortNum, FALSE, commit);
504  }
505  else
506  {
507  //Report an error
508  error = ERROR_WRONG_VALUE;
509  }
510  }
511  //lldpPortConfigTLVsTxEnable object?
512  else if(!strcmp(object->name, "lldpPortConfigTLVsTxEnable"))
513  {
514  //This object specifies the basic set of LLDP TLVs whose transmission is
515  //allowed on the local LLDP agent by the network management
516  if(valueLen > 0)
517  {
518  //Each bit in the bitmap corresponds to a TLV type associated with a
519  //specific optional TLV
521  lldpPortConfigPortNum, reverseInt8(value->octetString[0]), commit);
522  }
523  else
524  {
525  //An empty set means that no enumerated values are set
527  lldpPortConfigPortNum, 0, commit);
528  }
529  }
530  //Unknown object?
531  else
532  {
533  //The specified object does not exist
534  error = ERROR_OBJECT_NOT_FOUND;
535  }
536 
537  //Return status code
538  return error;
539 #else
540  //SET operation is not supported
541  return ERROR_WRITE_FAILED;
542 #endif
543 }
544 
545 
546 /**
547  * @brief Get lldpPortConfigEntry object value
548  * @param[in] object Pointer to the MIB object descriptor
549  * @param[in] oid Object identifier (object name and instance identifier)
550  * @param[in] oidLen Length of the OID, in bytes
551  * @param[out] value Object value
552  * @param[in,out] valueLen Length of the object value, in bytes
553  * @return Error code
554  **/
555 
556 error_t lldpMibGetLldpPortConfigEntry(const MibObject *object, const uint8_t *oid,
557  size_t oidLen, MibVariant *value, size_t *valueLen)
558 {
559  error_t error;
560  size_t n;
561  uint_t lldpPortConfigPortNum;
562 
563  //Point to the instance identifier
564  n = object->oidLen;
565 
566  //lldpPortConfigPortNum is used as instance identifier
567  error = mibDecodeIndex(oid, oidLen, &n, &lldpPortConfigPortNum);
568  //Invalid instance identifier?
569  if(error)
570  return error;
571 
572  //Sanity check
573  if(n != oidLen)
575 
576  //lldpPortConfigAdminStatus object?
577  if(!strcmp(object->name, "lldpPortConfigAdminStatus"))
578  {
579  LldpAdminStatus adminStatus;
580 
581  //This object specifies the administrative status of the local LLDP agent
583  lldpPortConfigPortNum, &adminStatus);
584 
585  //Check status code
586  if(!error)
587  {
588  //Return the value of the object
589  switch(adminStatus)
590  {
593  break;
596  break;
599  break;
602  break;
603  default:
605  break;
606  }
607  }
608  }
609  //lldpPortConfigNotificationEnable object?
610  else if(!strcmp(object->name, "lldpPortConfigNotificationEnable"))
611  {
612  bool_t notificationEnable;
613 
614  //This object controls, on a per port basis, whether or not notifications
615  //from the agent are enabled
617  lldpPortConfigPortNum, &notificationEnable);
618 
619  //Check status code
620  if(!error)
621  {
622  //Return the value of the object
623  if(notificationEnable)
624  {
625  value->integer = MIB_TRUTH_VALUE_TRUE;
626  }
627  else
628  {
629  value->integer = MIB_TRUTH_VALUE_FALSE;
630  }
631  }
632  }
633  //lldpPortConfigTLVsTxEnable object?
634  else if(!strcmp(object->name, "lldpPortConfigTLVsTxEnable"))
635  {
636  uint8_t mibBasicTlvsTxEnable;
637 
638  //This object specifies the basic set of LLDP TLVs whose transmission is
639  //allowed on the local LLDP agent by the network management
641  lldpPortConfigPortNum, &mibBasicTlvsTxEnable);
642 
643  //Check status code
644  if(!error)
645  {
646  //Each bit in the bitmap corresponds to a TLV type associated with a
647  //specific optional TLV
648  if(mibBasicTlvsTxEnable != 0)
649  {
650  //Make sure the buffer is large enough to hold the entire object
651  if(*valueLen >= sizeof(uint8_t))
652  {
653  //Copy object value
654  value->octetString[0] = reverseInt8(mibBasicTlvsTxEnable);
655  //Return object length
656  *valueLen = sizeof(uint8_t);
657  }
658  else
659  {
660  //Report an error
661  error = ERROR_BUFFER_OVERFLOW;
662  }
663  }
664  else
665  {
666  //An empty set means that no enumerated values are set
667  *valueLen = 0;
668  }
669  }
670  }
671  //Unknown object?
672  else
673  {
674  //The specified object does not exist
675  error = ERROR_OBJECT_NOT_FOUND;
676  }
677 
678  //Return status code
679  return error;
680 }
681 
682 
683 /**
684  * @brief Get next lldpPortConfigEntry object
685  * @param[in] object Pointer to the MIB object descriptor
686  * @param[in] oid Object identifier
687  * @param[in] oidLen Length of the OID, in bytes
688  * @param[out] nextOid OID of the next object in the MIB
689  * @param[out] nextOidLen Length of the next object identifier, in bytes
690  * @return Error code
691  **/
692 
694  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
695 {
696  error_t error;
697  uint_t i;
698  size_t n;
699  uint16_t portNum;
700  uint16_t curPortNum;
701  LldpAgentContext *context;
702 
703  //Initialize variable
704  portNum = 0;
705 
706  //Point to the LLDP agent context
707  context = lldpMibBase.lldpAgentContext;
708  //Make sure the context is valid
709  if(context == NULL)
710  return ERROR_OBJECT_NOT_FOUND;
711 
712  //Make sure the buffer is large enough to hold the OID prefix
713  if(*nextOidLen < object->oidLen)
714  return ERROR_BUFFER_OVERFLOW;
715 
716  //Copy OID prefix
717  osMemcpy(nextOid, object->oid, object->oidLen);
718 
719  //Loop through the ports of the bridge
720  for(i = 0; i < context->numPorts; i++)
721  {
722  //Retrieve the port number associated with the current port
723  curPortNum = context->ports[i].portIndex;
724 
725  //Append the instance identifier to the OID prefix
726  n = object->oidLen;
727 
728  //lldpPortConfigPortNum is used as instance identifier
729  error = mibEncodeIndex(nextOid, *nextOidLen, &n, curPortNum);
730  //Any error to report?
731  if(error)
732  return error;
733 
734  //Check whether the resulting object identifier lexicographically
735  //follows the specified OID
736  if(oidComp(nextOid, n, oid, oidLen) > 0)
737  {
738  //Save the closest object identifier that follows the specified
739  //OID in lexicographic order
740  if(portNum == 0 || curPortNum < portNum)
741  {
742  portNum = curPortNum;
743  }
744  }
745  }
746 
747  //The specified OID does not lexicographically precede the name
748  //of some object?
749  if(portNum == 0)
750  return ERROR_OBJECT_NOT_FOUND;
751 
752  //Append the instance identifier to the OID prefix
753  n = object->oidLen;
754 
755  //lldpPortConfigPortNum is used as instance identifier
756  error = mibEncodeIndex(nextOid, *nextOidLen, &n, portNum);
757  //Any error to report?
758  if(error)
759  return error;
760 
761  //Save the length of the resulting object identifier
762  *nextOidLen = n;
763  //Next object found
764  return NO_ERROR;
765 }
766 
767 
768 /**
769  * @brief Set lldpConfigManAddrEntry object value
770  * @param[in] object Pointer to the MIB object descriptor
771  * @param[in] oid Object identifier (object name and instance identifier)
772  * @param[in] oidLen Length of the OID, in bytes
773  * @param[in] value Object value
774  * @param[in] valueLen Length of the object value, in bytes
775  * @param[in] commit This flag tells whether the changes shall be committed
776  * to the MIB base
777  * @return Error code
778  **/
779 
781  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
782 {
783 #if (LLDP_MIB_SET_SUPPORT == ENABLED)
784  error_t error;
785  uint_t i;
786  size_t n;
787  uint_t lldpLocManAddrSubtype;
788  uint8_t lldpLocManAddr[LLDP_MAX_MGMT_ADDR_LEN];
789  size_t lldpLocManAddrLen;
790  LldpAgentContext *context;
791  int_t index;
792 
793  //Point to the LLDP agent context
794  context = lldpMibBase.lldpAgentContext;
795  //Make sure the context is valid
796  if(context == NULL)
797  return ERROR_OBJECT_NOT_FOUND;
798 
799  //Point to the instance identifier
800  n = object->oidLen;
801 
802  //lldpLocManAddrSubtype is used as 1st instance identifier
803  error = mibDecodeIndex(oid, oidLen, &n, &lldpLocManAddrSubtype);
804  //Invalid instance identifier?
805  if(error)
806  return error;
807 
808  //lldpLocManAddr is used as 2nd instance identifier
809  error = mibDecodeOctetString(oid, oidLen, &n, lldpLocManAddr,
810  LLDP_MAX_MGMT_ADDR_LEN, &lldpLocManAddrLen, FALSE);
811  //Invalid instance identifier?
812  if(error)
813  return error;
814 
815  //Sanity check
816  if(n != oidLen)
818 
819  //Search the local system MIB for a matching management address
820  index = lldpMgmtFindLocalMgmtAddr(context, lldpLocManAddrSubtype,
821  lldpLocManAddr, lldpLocManAddrLen);
822  //No matching address found?
823  if(index < 0)
825 
826  //lldpConfigManAddrPortsTxEnable object?
827  if(!strcmp(object->name, "lldpConfigManAddrPortsTxEnable"))
828  {
829  //This object is a bit map indicating the system ports through which the
830  //particular Management Address TLV is enabled for transmission
831  for(i = 0; i < context->numPorts; i++)
832  {
833  //Each port is represented as a bit
834  if(i >= (valueLen * 8))
835  {
836  context->ports[i].mgmtAddrFilter &= ~(1U << index);
837  }
838  else if((value->octetString[i / 8] & (0x80 >> (i % 8))) != 0)
839  {
840  context->ports[i].mgmtAddrFilter |= (1U << index);
841  }
842  else
843  {
844  context->ports[i].mgmtAddrFilter &= ~(1U << index);
845  }
846  }
847  }
848  //Unknown object?
849  else
850  {
851  //The specified object does not exist
852  error = ERROR_OBJECT_NOT_FOUND;
853  }
854 
855  //Return status code
856  return error;
857 #else
858  //SET operation is not supported
859  return ERROR_WRITE_FAILED;
860 #endif
861 }
862 
863 
864 /**
865  * @brief Get lldpConfigManAddrEntry object value
866  * @param[in] object Pointer to the MIB object descriptor
867  * @param[in] oid Object identifier (object name and instance identifier)
868  * @param[in] oidLen Length of the OID, in bytes
869  * @param[out] value Object value
870  * @param[in,out] valueLen Length of the object value, in bytes
871  * @return Error code
872  **/
873 
875  size_t oidLen, MibVariant *value, size_t *valueLen)
876 {
877  error_t error;
878  uint_t i;
879  uint_t k;
880  size_t n;
881  uint_t lldpLocManAddrSubtype;
882  uint8_t lldpLocManAddr[LLDP_MAX_MGMT_ADDR_LEN];
883  size_t lldpLocManAddrLen;
884  LldpAgentContext *context;
885  int_t index;
886 
887  //Point to the LLDP agent context
888  context = lldpMibBase.lldpAgentContext;
889  //Make sure the context is valid
890  if(context == NULL)
891  return ERROR_OBJECT_NOT_FOUND;
892 
893  //Point to the instance identifier
894  n = object->oidLen;
895 
896  //lldpLocManAddrSubtype is used as 1st instance identifier
897  error = mibDecodeIndex(oid, oidLen, &n, &lldpLocManAddrSubtype);
898  //Invalid instance identifier?
899  if(error)
900  return error;
901 
902  //lldpLocManAddr is used as 2nd instance identifier
903  error = mibDecodeOctetString(oid, oidLen, &n, lldpLocManAddr,
904  LLDP_MAX_MGMT_ADDR_LEN, &lldpLocManAddrLen, FALSE);
905  //Invalid instance identifier?
906  if(error)
907  return error;
908 
909  //Sanity check
910  if(n != oidLen)
912 
913  //Search the local system MIB for a matching management address
914  index = lldpMgmtFindLocalMgmtAddr(context, lldpLocManAddrSubtype,
915  lldpLocManAddr, lldpLocManAddrLen);
916  //No matching address found?
917  if(index < 0)
919 
920  //lldpConfigManAddrPortsTxEnable object?
921  if(!strcmp(object->name, "lldpConfigManAddrPortsTxEnable"))
922  {
923  //Get the highest port index
924  for(k = context->numPorts; k > 0; k--)
925  {
926  if((context->ports[k - 1].mgmtAddrFilter & (1U << index)) != 0)
927  break;
928  }
929 
930  //Each octet within the octet string specifies a set of eight ports
931  k = (k + 7) / 8;
932 
933  //Make sure the buffer is large enough to hold the entire object
934  if(*valueLen >= k)
935  {
936  //This object is a bit map indicating the system ports through which the
937  //particular Management Address TLV is enabled for transmission
938  for(i = 0; i < (k * 8); i++)
939  {
940  //Each port is represented as a bit
941  if(i >= context->numPorts)
942  {
943  value->octetString[i / 8] &= ~(0x80 >> (i % 8));
944  }
945  else if((context->ports[i].mgmtAddrFilter & (1U << index)) != 0)
946  {
947  value->octetString[i / 8] |= (0x80 >> (i % 8));
948  }
949  else
950  {
951  value->octetString[i / 8] &= ~(0x80 >> (i % 8));
952  }
953  }
954 
955  //Return object length
956  *valueLen = k;
957  }
958  else
959  {
960  //Report an error
961  error = ERROR_BUFFER_OVERFLOW;
962  }
963  }
964  //Unknown object?
965  else
966  {
967  //The specified object does not exist
968  error = ERROR_OBJECT_NOT_FOUND;
969  }
970 
971  //Return status code
972  return error;
973 }
974 
975 
976 /**
977  * @brief Get next lldpConfigManAddrEntry object
978  * @param[in] object Pointer to the MIB object descriptor
979  * @param[in] oid Object identifier
980  * @param[in] oidLen Length of the OID, in bytes
981  * @param[out] nextOid OID of the next object in the MIB
982  * @param[out] nextOidLen Length of the next object identifier, in bytes
983  * @return Error code
984  **/
985 
987  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
988 {
989  error_t error;
990  size_t n;
991  bool_t acceptable;
992  LldpTlv tlv;
993  LldpAgentContext *context;
994  const LldpMgmtAddrTlv1 *addr;
995  const LldpMgmtAddrTlv1 *nextAddr;
996 
997  //Initialize variables
998  nextAddr = NULL;
999 
1000  //Point to the LLDP agent context
1001  context = lldpMibBase.lldpAgentContext;
1002  //Make sure the context is valid
1003  if(context == NULL)
1004  return ERROR_OBJECT_NOT_FOUND;
1005 
1006  //Make sure the buffer is large enough to hold the OID prefix
1007  if(*nextOidLen < object->oidLen)
1008  return ERROR_BUFFER_OVERFLOW;
1009 
1010  //Copy OID prefix
1011  osMemcpy(nextOid, object->oid, object->oidLen);
1012 
1013  //Extract the first TLV
1014  error = lldpGetFirstTlv(&context->txInfo, &tlv);
1015 
1016  //Loop through the local system MIB
1017  while(!error)
1018  {
1019  //Check TLV type
1020  if(tlv.type == LLDP_TLV_TYPE_MGMT_ADDR)
1021  {
1022  //Decode the contents of the Management Address TLV
1023  error = lldpDecodeMgmtAddrTlv(tlv.value, tlv.length, &addr, NULL);
1024  //Malformed TLV?
1025  if(error)
1026  {
1027  break;
1028  }
1029 
1030  //Append the instance identifier to the OID prefix
1031  n = object->oidLen;
1032 
1033  //lldpLocManAddrSubtype is used as 1st instance identifier
1034  error = mibEncodeIndex(nextOid, *nextOidLen, &n,
1035  addr->mgmtAddrSubtype);
1036  //Invalid instance identifier?
1037  if(error)
1038  return error;
1039 
1040  //lldpLocManAddr is used as 5th instance identifier
1041  error = mibEncodeOctetString(nextOid, *nextOidLen, &n,
1042  addr->mgmtAddr, addr->mgmtAddrLen - 1, FALSE);
1043  //Invalid instance identifier?
1044  if(error)
1045  return error;
1046 
1047  //Check whether the resulting object identifier lexicographically
1048  //follows the specified OID
1049  if(oidComp(nextOid, n, oid, oidLen) > 0)
1050  {
1051  //Perform lexicographic comparison
1052  if(nextAddr == NULL)
1053  {
1054  acceptable = TRUE;
1055  }
1056  else if(addr->mgmtAddrSubtype < nextAddr->mgmtAddrSubtype)
1057  {
1058  acceptable = TRUE;
1059  }
1060  else if(addr->mgmtAddrSubtype > nextAddr->mgmtAddrSubtype)
1061  {
1062  acceptable = FALSE;
1063  }
1064  else if(addr->mgmtAddrLen < nextAddr->mgmtAddrLen)
1065  {
1066  acceptable = TRUE;
1067  }
1068  else if(addr->mgmtAddrLen > nextAddr->mgmtAddrLen)
1069  {
1070  acceptable = FALSE;
1071  }
1072  else if(osMemcmp(addr->mgmtAddr, nextAddr->mgmtAddr,
1073  nextAddr->mgmtAddrLen) < 0)
1074  {
1075  acceptable = TRUE;
1076  }
1077  else
1078  {
1079  acceptable = FALSE;
1080  }
1081 
1082  //Save the closest object identifier that follows the specified
1083  //OID in lexicographic order
1084  if(acceptable)
1085  {
1086  nextAddr = addr;
1087  }
1088  }
1089  }
1090 
1091  //Extract the next TLV
1092  error = lldpGetNextTlv(&context->txInfo, &tlv);
1093  }
1094 
1095  //The specified OID does not lexicographically precede the name
1096  //of some object?
1097  if(nextAddr == NULL)
1098  return ERROR_OBJECT_NOT_FOUND;
1099 
1100  //Append the instance identifier to the OID prefix
1101  n = object->oidLen;
1102 
1103  //lldpLocManAddrSubtype is used as 1st instance identifier
1104  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextAddr->mgmtAddrSubtype);
1105  //Invalid instance identifier?
1106  if(error)
1107  return error;
1108 
1109  //lldpLocManAddr is used as 5th instance identifier
1110  error = mibEncodeOctetString(nextOid, *nextOidLen, &n, nextAddr->mgmtAddr,
1111  nextAddr->mgmtAddrLen - 1, FALSE);
1112  //Invalid instance identifier?
1113  if(error)
1114  return error;
1115 
1116  //Save the length of the resulting object identifier
1117  *nextOidLen = n;
1118  //Next object found
1119  return NO_ERROR;
1120 }
1121 
1122 #endif
ASN.1 (Abstract Syntax Notation One)
signed int int_t
Definition: compiler_port.h:49
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
uint8_t reverseInt8(uint8_t value)
Reverse bit order in a byte.
Definition: cpu_endian.c:90
General definitions for cryptographic algorithms.
Debugging facilities.
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRITE_FAILED
Definition: error.h:221
@ ERROR_OBJECT_NOT_FOUND
Definition: error.h:255
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:256
@ ERROR_WRONG_VALUE
Definition: error.h:123
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:142
LldpAdminStatus
Administrative status.
Definition: lldp.h:187
@ LLDP_ADMIN_STATUS_ENABLED_TX_RX
Definition: lldp.h:191
@ LLDP_ADMIN_STATUS_ENABLED_RX_ONLY
The local LLDP agent can only receive LLDP frames.
Definition: lldp.h:190
@ LLDP_ADMIN_STATUS_DISABLED
The local LLDP agent can neither transmit or receive LLDP frames.
Definition: lldp.h:188
@ LLDP_ADMIN_STATUS_ENABLED_TX_ONLY
The local LLDP agent can only transmit LLDP frames.
Definition: lldp.h:189
#define LldpAgentContext
Definition: lldp.h:40
error_t lldpMgmtGetTxDelay(LldpAgentContext *context, uint_t *txDelay)
Get transmit delay.
Definition: lldp_mgmt.c:525
error_t lldpMgmtSetMsgTxHold(LldpAgentContext *context, uint_t msgTxHold, bool_t commit)
Set transmit hold multiplier.
Definition: lldp_mgmt.c:127
error_t lldpMgmtSetReinitDelay(LldpAgentContext *context, uint_t reinitDelay, bool_t commit)
Set re-initialization delay.
Definition: lldp_mgmt.c:172
error_t lldpMgmtGetReinitDelay(LldpAgentContext *context, uint_t *reinitDelay)
Get re-initialization delay.
Definition: lldp_mgmt.c:499
error_t lldpMgmtSetNotificationInterval(LldpAgentContext *context, uint_t notificationInterval, bool_t commit)
Set notification interval.
Definition: lldp_mgmt.c:254
int_t lldpMgmtFindLocalMgmtAddr(LldpAgentContext *context, uint8_t mgmtAddrSubtype, const uint8_t *mgmtAddr, size_t mgmtAddrLen)
Search the local system MIB for a given management address.
Definition: lldp_mgmt.c:1023
error_t lldpMgmtGetMibBasicTlvsTxEnable(LldpAgentContext *context, uint_t portIndex, uint8_t *mibBasicTlvsTxEnable)
Get the list of TLVs enabled for transmission.
Definition: lldp_mgmt.c:656
error_t lldpMgmtGetMsgTxHold(LldpAgentContext *context, uint_t *msgTxHold)
Get transmit hold multiplier.
Definition: lldp_mgmt.c:473
error_t lldpMgmtSetAdminStatus(LldpAgentContext *context, uint_t portIndex, LldpAdminStatus adminStatus, bool_t commit)
Set administrative status.
Definition: lldp_mgmt.c:297
error_t lldpMgmtGetNotificationInterval(LldpAgentContext *context, uint_t *notificationInterval)
Get notification interval.
Definition: lldp_mgmt.c:551
error_t lldpMgmtSetNotificationEnable(LldpAgentContext *context, uint_t portIndex, bool_t notificationEnable, bool_t commit)
Enable or disable notifications.
Definition: lldp_mgmt.c:355
error_t lldpMgmtGetNotificationEnable(LldpAgentContext *context, uint_t portIndex, bool_t *notificationEnable)
Check whether notifications are enabled or disabled.
Definition: lldp_mgmt.c:618
error_t lldpMgmtSetBasicTlvFilter(LldpAgentContext *context, uint_t portIndex, uint8_t mask, bool_t commit)
Set the list of TLVs enabled for transmission.
Definition: lldp_mgmt.c:399
error_t lldpMgmtGetAdminStatus(LldpAgentContext *context, uint_t portIndex, LldpAdminStatus *adminStatus)
Get administrative status.
Definition: lldp_mgmt.c:580
error_t lldpMgmtSetMsgTxInterval(LldpAgentContext *context, uint_t msgTxInterval, bool_t commit)
Set transmit interval.
Definition: lldp_mgmt.c:81
error_t lldpMgmtSetTxDelay(LldpAgentContext *context, uint_t txDelay, bool_t commit)
Set transmit delay.
Definition: lldp_mgmt.c:213
error_t lldpMgmtGetMsgTxInterval(LldpAgentContext *context, uint_t *msgTxInterval)
Get transmit interval.
Definition: lldp_mgmt.c:445
Management of the LLDP agent.
LLDP MIB module implementation.
error_t lldpMibSetLldpConfigManAddrEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set lldpConfigManAddrEntry object value.
error_t lldpMibGetLldpNotificationInterval(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpNotificationInterval object value.
error_t lldpMibGetLldpReinitDelay(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpReinitDelay object value.
error_t lldpMibGetLldpConfigManAddrEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpConfigManAddrEntry object value.
error_t lldpMibSetLldpNotificationInterval(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set lldpNotificationInterval object value.
error_t lldpMibSetLldpPortConfigEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set lldpPortConfigEntry object value.
error_t lldpMibGetLldpMessageTxInterval(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpMessageTxInterval object value.
error_t lldpMibSetLldpReinitDelay(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set lldpReinitDelay object value.
error_t lldpMibGetNextLldpPortConfigEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next lldpPortConfigEntry object.
error_t lldpMibSetLldpMessageTxInterval(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set lldpMessageTxInterval object value.
error_t lldpMibSetLldpTxDelay(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set lldpTxDelay object value.
error_t lldpMibGetLldpMessageTxHoldMultiplier(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpMessageTxHoldMultiplier object value.
error_t lldpMibGetLldpTxDelay(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpTxDelay object value.
error_t lldpMibGetLldpPortConfigEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpPortConfigEntry object value.
error_t lldpMibSetLldpMessageTxHoldMultiplier(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set lldpMessageTxHoldMultiplier object value.
error_t lldpMibGetNextLldpConfigManAddrEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next lldpConfigManAddrEntry object.
LLDP MIB module implementation (lldpConfiguration subtree)
LldpMibBase lldpMibBase
LLDP MIB base.
LLDP MIB module.
@ LLDP_MIB_ADMIN_STATUS_ENABLED_TX_RX
@ LLDP_MIB_ADMIN_STATUS_ENABLED_TX_ONLY
@ LLDP_MIB_ADMIN_STATUS_DISABLED
@ LLDP_MIB_ADMIN_STATUS_INVALID
@ LLDP_MIB_ADMIN_STATUS_ENABLED_RX_ONLY
error_t lldpGetNextTlv(LldpDataUnit *lldpdu, LldpTlv *tlv)
Extract the next TLV from an LLDPDU.
Definition: lldp_tlv.c:264
error_t lldpGetFirstTlv(LldpDataUnit *lldpdu, LldpTlv *tlv)
Extract the first TLV from an LLDPDU.
Definition: lldp_tlv.c:247
error_t lldpDecodeMgmtAddrTlv(const uint8_t *value, size_t length, const LldpMgmtAddrTlv1 **mgmtAddr1, const LldpMgmtAddrTlv2 **mgmtAddr2)
Decode the contents of a Management Address TLV.
Definition: lldp_tlv.c:380
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
LldpMgmtAddrTlv1
Definition: lldp_tlv.h:288
#define LLDP_MAX_MGMT_ADDR_LEN
Definition: lldp_tlv.h:74
@ LLDP_TLV_TYPE_MGMT_ADDR
Management Address.
Definition: lldp_tlv.h:101
error_t mibDecodeOctetString(const uint8_t *oid, size_t oidLen, size_t *pos, uint8_t *data, size_t maxDataLen, size_t *dataLen, bool_t implied)
Decode instance identifier (octet string)
Definition: mib_common.c:225
error_t mibDecodeIndex(const uint8_t *oid, size_t oidLen, size_t *pos, uint_t *index)
Decode instance identifier (index)
Definition: mib_common.c:64
error_t mibEncodeOctetString(uint8_t *oid, size_t maxOidLen, size_t *pos, const uint8_t *data, size_t dataLen, bool_t implied)
Encode instance identifier (octet string)
Definition: mib_common.c:182
error_t mibEncodeIndex(uint8_t *oid, size_t maxOidLen, size_t *pos, uint_t index)
Encode instance identifier (index)
Definition: mib_common.c:47
Common definitions for MIB modules.
#define MibObject
Definition: mib_common.h:46
@ MIB_TRUTH_VALUE_TRUE
Definition: mib_common.h:91
@ MIB_TRUTH_VALUE_FALSE
Definition: mib_common.h:92
MibVariant
Definition: mib_common.h:196
Ipv4Addr addr
Definition: nbns_common.h:123
TCP/IP stack core.
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
OID (Object Identifier)
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
LldpAgentContext * lldpAgentContext
TLV structure.
Definition: lldp_tlv.h:200
uint8_t type
Definition: lldp_tlv.h:202
uint8_t * value
Definition: lldp_tlv.h:204
size_t length
Definition: lldp_tlv.h:203
uint8_t value[]
Definition: tcp.h:369