lldp_mib_impl_remote.c
Go to the documentation of this file.
1 /**
2  * @file lldp_mib_impl_remote.c
3  * @brief LLDP MIB module implementation (lldpRemoteSystemsData 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.4
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 && LLDP_RX_MODE_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Get lldpRemEntry 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[out] value Object value
56  * @param[in,out] valueLen Length of the object value, in bytes
57  * @return Error code
58  **/
59 
60 error_t lldpMibGetLldpRemEntry(const MibObject *object, const uint8_t *oid,
61  size_t oidLen, MibVariant *value, size_t *valueLen)
62 {
63  error_t error;
64  size_t n;
65  uint_t lldpRemTimeMark;
66  uint_t lldpRemLocalPortNum;
67  uint_t lldpRemIndex;
68  LldpNeighborEntry *entry;
69 
70  //Point to the instance identifier
71  n = object->oidLen;
72 
73  //lldpRemTimeMark is used as 1st instance identifier
74  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemTimeMark);
75  //Invalid instance identifier?
76  if(error)
77  return error;
78 
79  //lldpRemLocalPortNum is used as 2nd instance identifier
80  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemLocalPortNum);
81  //Invalid instance identifier?
82  if(error)
83  return error;
84 
85  //lldpRemIndex is used as 3rd instance identifier
86  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemIndex);
87  //Invalid instance identifier?
88  if(error)
89  return error;
90 
91  //Sanity check
92  if(n != oidLen)
94 
95  //Search the remote systems MIB for a matching row
97  lldpRemTimeMark, lldpRemLocalPortNum, lldpRemIndex);
98  //No matching row found?
99  if(entry == NULL)
101 
102  //lldpRemChassisIdSubtype object?
103  if(osStrcmp(object->name, "lldpRemChassisIdSubtype") == 0)
104  {
105  LldpChassisIdSubtype chassisIdSubtype;
106  const uint8_t *chassisId;
107  size_t chassisIdLen;
108 
109  //This object indicates the type of encoding used to identify the
110  //chassis associated with the remote system
111  error = lldpMgmtGetRemoteChassisId(entry, &chassisIdSubtype, &chassisId,
112  &chassisIdLen);
113 
114  //Check status code
115  if(!error)
116  {
117  //Return object value
118  value->integer = (int32_t) chassisIdSubtype;
119  }
120  }
121  //lldpRemChassisId object?
122  else if(osStrcmp(object->name, "lldpRemChassisId") == 0)
123  {
124  LldpChassisIdSubtype chassisIdSubtype;
125  const uint8_t *chassisId;
126  size_t chassisIdLen;
127 
128  //This object identifies the chassis component associated with the
129  //remote system
130  error = lldpMgmtGetRemoteChassisId(entry, &chassisIdSubtype, &chassisId,
131  &chassisIdLen);
132 
133  //Check status code
134  if(!error)
135  {
136  //Make sure the buffer is large enough to hold the entire object
137  if(*valueLen >= chassisIdLen)
138  {
139  //Copy object value
140  osMemcpy(value->octetString, chassisId, chassisIdLen);
141  //Return object length
142  *valueLen = chassisIdLen;
143  }
144  else
145  {
146  //Report an error
147  error = ERROR_BUFFER_OVERFLOW;
148  }
149  }
150  }
151  //lldpRemPortIdSubtype object?
152  else if(osStrcmp(object->name, "lldpRemPortIdSubtype") == 0)
153  {
154  LldpPortIdSubtype portIdSubtype;
155  const uint8_t *portId;
156  size_t portIdLen;
157 
158  //This object indicates the type of port identifier encoding used in
159  //the associated lldpRemPortId object
160  error = lldpMgmtGetRemotePortId(entry, &portIdSubtype, &portId,
161  &portIdLen);
162 
163  //Check status code
164  if(!error)
165  {
166  //Return object value
167  value->integer = (int32_t) portIdSubtype;
168  }
169  }
170  //lldpRemPortId object?
171  else if(osStrcmp(object->name, "lldpRemPortId") == 0)
172  {
173  LldpPortIdSubtype portIdSubtype;
174  const uint8_t *portId;
175  size_t portIdLen;
176 
177  //This object identifies the port component associated with a given port
178  //in the remote system
179  error = lldpMgmtGetRemotePortId(entry, &portIdSubtype, &portId,
180  &portIdLen);
181 
182  //Check status code
183  if(!error)
184  {
185  //Make sure the buffer is large enough to hold the entire object
186  if(*valueLen >= portIdLen)
187  {
188  //Copy object value
189  osMemcpy(value->octetString, portId, portIdLen);
190  //Return object length
191  *valueLen = portIdLen;
192  }
193  else
194  {
195  //Report an error
196  error = ERROR_BUFFER_OVERFLOW;
197  }
198  }
199  }
200  //lldpRemPortDesc object?
201  else if(osStrcmp(object->name, "lldpRemPortDesc") == 0)
202  {
203  const char_t *portDesc;
204  size_t portDescLen;
205 
206  //This object identifies the description associated of the given port
207  //associated with the remote system
208  error = lldpMgmtGetRemotePortDesc(entry, &portDesc, &portDescLen);
209 
210  //Check status code
211  if(!error)
212  {
213  //Make sure the buffer is large enough to hold the entire object
214  if(*valueLen >= portDescLen)
215  {
216  //Copy object value
217  osMemcpy(value->octetString, portDesc, portDescLen);
218  //Return object length
219  *valueLen = portDescLen;
220  }
221  else
222  {
223  //Report an error
224  error = ERROR_BUFFER_OVERFLOW;
225  }
226  }
227  }
228  //lldpRemSysName object?
229  else if(osStrcmp(object->name, "lldpRemSysName") == 0)
230  {
231  const char_t *sysName;
232  size_t sysNameLen;
233 
234  //This object identifies the system name of the remote system
235  error = lldpMgmtGetRemoteSysName(entry, &sysName, &sysNameLen);
236 
237  //Check status code
238  if(!error)
239  {
240  //Make sure the buffer is large enough to hold the entire object
241  if(*valueLen >= sysNameLen)
242  {
243  //Copy object value
244  osMemcpy(value->octetString, sysName, sysNameLen);
245  //Return object length
246  *valueLen = sysNameLen;
247  }
248  else
249  {
250  //Report an error
251  error = ERROR_BUFFER_OVERFLOW;
252  }
253  }
254  }
255  //lldpRemSysDesc object?
256  else if(osStrcmp(object->name, "lldpRemSysDesc") == 0)
257  {
258  const char_t *sysDesc;
259  size_t sysDescLen;
260 
261  //This object identifies the system description of the remote system
262  error = lldpMgmtGetRemoteSysDesc(entry, &sysDesc, &sysDescLen);
263 
264  //Check status code
265  if(!error)
266  {
267  //Make sure the buffer is large enough to hold the entire object
268  if(*valueLen >= sysDescLen)
269  {
270  //Copy object value
271  osMemcpy(value->octetString, sysDesc, sysDescLen);
272  //Return object length
273  *valueLen = sysDescLen;
274  }
275  else
276  {
277  //Report an error
278  error = ERROR_BUFFER_OVERFLOW;
279  }
280  }
281  }
282  //lldpRemSysCapSupported object?
283  else if(osStrcmp(object->name, "lldpRemSysCapSupported") == 0)
284  {
285  error_t error;
286  uint16_t supportedCap;
287  uint16_t enabledCap;
288 
289  //This object identifies which system capabilities are supported on the
290  //remote system
291  error = lldpMgmtGetRemoteSysCap(entry, &supportedCap, &enabledCap);
292 
293  //Check status code
294  if(!error)
295  {
296  //Each bit in the bitmap corresponds to a given capability
297  if(supportedCap != 0)
298  {
299  //Make sure the buffer is large enough to hold the entire object
300  if(*valueLen >= sizeof(uint8_t))
301  {
302  //Copy object value
303  value->octetString[0] = reverseInt8((uint8_t) supportedCap);
304  //Return object length
305  *valueLen = sizeof(uint8_t);
306  }
307  else
308  {
309  //Report an error
310  error = ERROR_BUFFER_OVERFLOW;
311  }
312  }
313  else
314  {
315  //An empty set means that no enumerated values are set
316  *valueLen = 0;
317  }
318  }
319  }
320  //lldpRemSysCapEnabled object?
321  else if(osStrcmp(object->name, "lldpRemSysCapEnabled") == 0)
322  {
323  error_t error;
324  uint16_t supportedCap;
325  uint16_t enabledCap;
326 
327  //This object identifies which system capabilities are enabled on the
328  //remote system
329  error = lldpMgmtGetRemoteSysCap(entry, &supportedCap, &enabledCap);
330 
331  //Check status code
332  if(!error)
333  {
334  //Each bit in the bitmap corresponds to a given capability
335  if(supportedCap != 0)
336  {
337  //Make sure the buffer is large enough to hold the entire object
338  if(*valueLen >= sizeof(uint8_t))
339  {
340  //Copy object value
341  value->octetString[0] = reverseInt8((uint8_t) enabledCap);
342  //Return object length
343  *valueLen = sizeof(uint8_t);
344  }
345  else
346  {
347  //Report an error
348  error = ERROR_BUFFER_OVERFLOW;
349  }
350  }
351  else
352  {
353  //An empty set means that no enumerated values are set
354  *valueLen = 0;
355  }
356  }
357  }
358  //Unknown object?
359  else
360  {
361  //The specified object does not exist
362  error = ERROR_OBJECT_NOT_FOUND;
363  }
364 
365  //Return status code
366  return error;
367 }
368 
369 
370 /**
371  * @brief Get next lldpRemEntry object
372  * @param[in] object Pointer to the MIB object descriptor
373  * @param[in] oid Object identifier
374  * @param[in] oidLen Length of the OID, in bytes
375  * @param[out] nextOid OID of the next object in the MIB
376  * @param[out] nextOidLen Length of the next object identifier, in bytes
377  * @return Error code
378  **/
379 
380 error_t lldpMibGetNextLldpRemEntry(const MibObject *object, const uint8_t *oid,
381  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
382 {
383  error_t error;
384  uint_t i;
385  size_t n;
386  bool_t acceptable;
387  LldpAgentContext *context;
388  LldpNeighborEntry *entry;
389  LldpNeighborEntry *nextEntry;
390 
391  //Initialize variables
392  nextEntry = NULL;
393 
394  //Point to the LLDP agent context
395  context = lldpMibBase.lldpAgentContext;
396  //Make sure the context is valid
397  if(context == NULL)
398  return ERROR_OBJECT_NOT_FOUND;
399 
400  //Make sure the buffer is large enough to hold the OID prefix
401  if(*nextOidLen < object->oidLen)
402  return ERROR_BUFFER_OVERFLOW;
403 
404  //Copy OID prefix
405  osMemcpy(nextOid, object->oid, object->oidLen);
406 
407  //Loop through the remote systems MIB
408  for(i = 0; i < context->numNeighbors; i++)
409  {
410  //Point to the current entry
411  entry = &context->neighbors[i];
412 
413  //Check whether the entry is valid
414  if(entry->rxInfo.length > 0)
415  {
416  //Append the instance identifier to the OID prefix
417  n = object->oidLen;
418 
419  //lldpRemTimeMark is used as 1st instance identifier
420  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->timeMark);
421  //Invalid instance identifier?
422  if(error)
423  return error;
424 
425  //lldpRemLocalPortNum is used as 2nd instance identifier
426  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->portIndex);
427  //Invalid instance identifier?
428  if(error)
429  return error;
430 
431  //lldpRemIndex is used as 3rd instance identifier
432  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->index);
433  //Invalid instance identifier?
434  if(error)
435  return error;
436 
437  //Check whether the resulting object identifier lexicographically
438  //follows the specified OID
439  if(oidComp(nextOid, n, oid, oidLen) > 0)
440  {
441  //Perform lexicographic comparison
442  if(nextEntry == NULL)
443  {
444  acceptable = TRUE;
445  }
446  else if(entry->timeMark < nextEntry->timeMark)
447  {
448  acceptable = TRUE;
449  }
450  else if(entry->timeMark > nextEntry->timeMark)
451  {
452  acceptable = FALSE;
453  }
454  else if(entry->portIndex < nextEntry->portIndex)
455  {
456  acceptable = TRUE;
457  }
458  else if(entry->portIndex > nextEntry->portIndex)
459  {
460  acceptable = FALSE;
461  }
462  else if(entry->index < nextEntry->index)
463  {
464  acceptable = TRUE;
465  }
466  else
467  {
468  acceptable = FALSE;
469  }
470 
471  //Save the closest object identifier that follows the specified
472  //OID in lexicographic order
473  if(acceptable)
474  {
475  nextEntry = entry;
476  }
477  }
478  }
479  }
480 
481  //The specified OID does not lexicographically precede the name
482  //of some object?
483  if(nextEntry == NULL)
484  return ERROR_OBJECT_NOT_FOUND;
485 
486  //Append the instance identifier to the OID prefix
487  n = object->oidLen;
488 
489  //lldpRemTimeMark is used as 1st instance identifier
490  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->timeMark);
491  //Invalid instance identifier?
492  if(error)
493  return error;
494 
495  //lldpRemLocalPortNum is used as 2nd instance identifier
496  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->portIndex);
497  //Invalid instance identifier?
498  if(error)
499  return error;
500 
501  //lldpRemIndex is used as 3rd instance identifier
502  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->index);
503  //Invalid instance identifier?
504  if(error)
505  return error;
506 
507  //Save the length of the resulting object identifier
508  *nextOidLen = n;
509  //Next object found
510  return NO_ERROR;
511 }
512 
513 
514 /**
515  * @brief Get lldpRemManAddrEntry object value
516  * @param[in] object Pointer to the MIB object descriptor
517  * @param[in] oid Object identifier (object name and instance identifier)
518  * @param[in] oidLen Length of the OID, in bytes
519  * @param[out] value Object value
520  * @param[in,out] valueLen Length of the object value, in bytes
521  * @return Error code
522  **/
523 
524 error_t lldpMibGetLldpRemManAddrEntry(const MibObject *object, const uint8_t *oid,
525  size_t oidLen, MibVariant *value, size_t *valueLen)
526 {
527  error_t error;
528  size_t n;
529  int_t index;
530  uint_t lldpRemTimeMark;
531  uint_t lldpRemLocalPortNum;
532  uint_t lldpRemIndex;
533  uint_t lldpRemManAddrSubtype;
534  uint8_t lldpRemManAddr[LLDP_MAX_MGMT_ADDR_LEN];
535  size_t lldpRemManAddrLen;
536  LldpNeighborEntry *entry;
537  LldpIfNumSubtype ifNumSubtype;
538  uint32_t ifNum;
539  const uint8_t *addrOid;
540  size_t addrOidLen;
541 
542  //Point to the instance identifier
543  n = object->oidLen;
544 
545  //lldpRemTimeMark is used as 1st instance identifier
546  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemTimeMark);
547  //Invalid instance identifier?
548  if(error)
549  return error;
550 
551  //lldpRemLocalPortNum is used as 2nd instance identifier
552  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemLocalPortNum);
553  //Invalid instance identifier?
554  if(error)
555  return error;
556 
557  //lldpRemIndex is used as 3rd instance identifier
558  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemIndex);
559  //Invalid instance identifier?
560  if(error)
561  return error;
562 
563  //lldpRemManAddrSubtype is used as 4th instance identifier
564  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemManAddrSubtype);
565  //Invalid instance identifier?
566  if(error)
567  return error;
568 
569  //lldpRemManAddr is used as 5th instance identifier
570  error = mibDecodeOctetString(oid, oidLen, &n, lldpRemManAddr,
571  LLDP_MAX_MGMT_ADDR_LEN, &lldpRemManAddrLen, FALSE);
572  //Invalid instance identifier?
573  if(error)
574  return error;
575 
576  //Sanity check
577  if(n != oidLen)
579 
580  //Search the remote systems MIB for a matching row
582  lldpRemTimeMark, lldpRemLocalPortNum, lldpRemIndex);
583  //No matching row found?
584  if(entry == NULL)
586 
587  //Search the remote systems MIB for a matching address
588  index = lldpMgmtFindRemoteMgmtAddr(entry, lldpRemManAddrSubtype,
589  lldpRemManAddr, lldpRemManAddrLen);
590  //No matching address found?
591  if(index < 0)
593 
594  //Extract the management address from the remote systems MIB
595  error = lldpMgmtGetRemoteMgmtAddr(entry, index, NULL, NULL, NULL,
596  &ifNumSubtype, &ifNum, &addrOid, &addrOidLen);
597  //No matching address found?
598  if(error)
600 
601  //lldpRemManAddrIfSubtype object?
602  if(osStrcmp(object->name, "lldpRemManAddrIfSubtype") == 0)
603  {
604  //This object identifies the interface numbering method used for defining
605  //the interface number, associated with the remote system
606  if(ifNumSubtype == LLDP_IF_NUM_SUBTYPE_IF_INDEX)
607  {
608  //interface identifier based on the ifIndex MIB object
610  }
611  else if(ifNumSubtype == LLDP_IF_NUM_SUBTYPE_SYS_PORT_NUM)
612  {
613  //interface identifier based on the system port numbering convention
615  }
616  else
617  {
618  //The interface is not known
620  }
621  }
622  //lldpRemManAddrIfId object?
623  else if(osStrcmp(object->name, "lldpRemManAddrIfId") == 0)
624  {
625  //This object identifies the interface number regarding the management
626  //address component associated with the remote system
627  value->integer = ifNum;
628  }
629  //lldpRemManAddrOID object?
630  else if(osStrcmp(object->name, "lldpRemManAddrOID") == 0)
631  {
632  //Make sure the buffer is large enough to hold the entire object
633  if(*valueLen >= addrOidLen)
634  {
635  //Copy object value
636  osMemcpy(value->octetString, addrOid, addrOidLen);
637  //Return object length
638  *valueLen = addrOidLen;
639  }
640  else
641  {
642  //Report an error
643  error = ERROR_BUFFER_OVERFLOW;
644  }
645  }
646  //Unknown object?
647  else
648  {
649  //The specified object does not exist
650  error = ERROR_OBJECT_NOT_FOUND;
651  }
652 
653  //Return status code
654  return error;
655 }
656 
657 
658 /**
659  * @brief Get next lldpRemManAddrEntry object
660  * @param[in] object Pointer to the MIB object descriptor
661  * @param[in] oid Object identifier
662  * @param[in] oidLen Length of the OID, in bytes
663  * @param[out] nextOid OID of the next object in the MIB
664  * @param[out] nextOidLen Length of the next object identifier, in bytes
665  * @return Error code
666  **/
667 
669  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
670 {
671  error_t error;
672  uint_t i;
673  size_t n;
674  bool_t acceptable;
675  LldpTlv tlv;
676  LldpAgentContext *context;
677  LldpNeighborEntry *entry;
678  LldpNeighborEntry *nextEntry;
679  const LldpMgmtAddrTlv1 *addr;
680  const LldpMgmtAddrTlv1 *nextAddr;
681 
682  //Initialize variables
683  nextEntry = NULL;
684  nextAddr = NULL;
685 
686  //Point to the LLDP agent context
687  context = lldpMibBase.lldpAgentContext;
688  //Make sure the context is valid
689  if(context == NULL)
690  return ERROR_OBJECT_NOT_FOUND;
691 
692  //Make sure the buffer is large enough to hold the OID prefix
693  if(*nextOidLen < object->oidLen)
694  return ERROR_BUFFER_OVERFLOW;
695 
696  //Copy OID prefix
697  osMemcpy(nextOid, object->oid, object->oidLen);
698 
699  //Loop through the remote systems MIB
700  for(i = 0; i < context->numNeighbors; i++)
701  {
702  //Point to the current entry
703  entry = &context->neighbors[i];
704 
705  //Check whether the entry is valid
706  if(entry->rxInfo.length > 0)
707  {
708  //Extract the first TLV
709  error = lldpGetFirstTlv(&entry->rxInfo, &tlv);
710 
711  //Loop through the TLVs
712  while(!error)
713  {
714  //Check TLV type
715  if(tlv.type == LLDP_TLV_TYPE_MGMT_ADDR)
716  {
717  //Decode the contents of the Management Address TLV
718  error = lldpDecodeMgmtAddrTlv(tlv.value, tlv.length, &addr, NULL);
719  //Malformed TLV?
720  if(error)
721  {
722  break;
723  }
724 
725  //Append the instance identifier to the OID prefix
726  n = object->oidLen;
727 
728  //lldpRemTimeMark is used as 1st instance identifier
729  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->timeMark);
730  //Invalid instance identifier?
731  if(error)
732  return error;
733 
734  //lldpRemLocalPortNum is used as 2nd instance identifier
735  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->portIndex);
736  //Invalid instance identifier?
737  if(error)
738  return error;
739 
740  //lldpRemIndex is used as 3rd instance identifier
741  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->index);
742  //Invalid instance identifier?
743  if(error)
744  return error;
745 
746  //lldpRemManAddrSubtype is used as 4th instance identifier
747  error = mibEncodeIndex(nextOid, *nextOidLen, &n,
748  addr->mgmtAddrSubtype);
749  //Invalid instance identifier?
750  if(error)
751  return error;
752 
753  //lldpRemManAddr is used as 5th instance identifier
754  error = mibEncodeOctetString(nextOid, *nextOidLen, &n,
755  addr->mgmtAddr, addr->mgmtAddrLen - 1, FALSE);
756  //Invalid instance identifier?
757  if(error)
758  return error;
759 
760  //Check whether the resulting object identifier lexicographically
761  //follows the specified OID
762  if(oidComp(nextOid, n, oid, oidLen) > 0)
763  {
764  //Perform lexicographic comparison
765  if(nextEntry == NULL || nextAddr == NULL)
766  {
767  acceptable = TRUE;
768  }
769  else if(entry->timeMark < nextEntry->timeMark)
770  {
771  acceptable = TRUE;
772  }
773  else if(entry->timeMark > nextEntry->timeMark)
774  {
775  acceptable = FALSE;
776  }
777  else if(entry->portIndex < nextEntry->portIndex)
778  {
779  acceptable = TRUE;
780  }
781  else if(entry->portIndex > nextEntry->portIndex)
782  {
783  acceptable = FALSE;
784  }
785  else if(entry->index < nextEntry->index)
786  {
787  acceptable = TRUE;
788  }
789  else if(entry->index > nextEntry->index)
790  {
791  acceptable = FALSE;
792  }
793  else if(addr->mgmtAddrSubtype < nextAddr->mgmtAddrSubtype)
794  {
795  acceptable = TRUE;
796  }
797  else if(addr->mgmtAddrSubtype > nextAddr->mgmtAddrSubtype)
798  {
799  acceptable = FALSE;
800  }
801  else if(addr->mgmtAddrLen < nextAddr->mgmtAddrLen)
802  {
803  acceptable = TRUE;
804  }
805  else if(addr->mgmtAddrLen > nextAddr->mgmtAddrLen)
806  {
807  acceptable = FALSE;
808  }
809  else if(osMemcmp(addr->mgmtAddr, nextAddr->mgmtAddr,
810  nextAddr->mgmtAddrLen) < 0)
811  {
812  acceptable = TRUE;
813  }
814  else
815  {
816  acceptable = FALSE;
817  }
818 
819  //Save the closest object identifier that follows the specified
820  //OID in lexicographic order
821  if(acceptable)
822  {
823  nextEntry = entry;
824  nextAddr = addr;
825  }
826  }
827  }
828 
829  //Extract the next TLV
830  error = lldpGetNextTlv(&entry->rxInfo, &tlv);
831  }
832  }
833  }
834 
835  //The specified OID does not lexicographically precede the name
836  //of some object?
837  if(nextEntry == NULL || nextAddr == NULL)
838  return ERROR_OBJECT_NOT_FOUND;
839 
840  //Append the instance identifier to the OID prefix
841  n = object->oidLen;
842 
843  //lldpRemTimeMark is used as 1st instance identifier
844  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->timeMark);
845  //Invalid instance identifier?
846  if(error)
847  return error;
848 
849  //lldpRemLocalPortNum is used as 2nd instance identifier
850  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->portIndex);
851  //Invalid instance identifier?
852  if(error)
853  return error;
854 
855  //lldpRemIndex is used as 3rd instance identifier
856  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->index);
857  //Invalid instance identifier?
858  if(error)
859  return error;
860 
861  //lldpRemManAddrSubtype is used as 4th instance identifier
862  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextAddr->mgmtAddrSubtype);
863  //Invalid instance identifier?
864  if(error)
865  return error;
866 
867  //lldpRemManAddr is used as 5th instance identifier
868  error = mibEncodeOctetString(nextOid, *nextOidLen, &n, nextAddr->mgmtAddr,
869  nextAddr->mgmtAddrLen - 1, FALSE);
870  //Invalid instance identifier?
871  if(error)
872  return error;
873 
874  //Save the length of the resulting object identifier
875  *nextOidLen = n;
876  //Next object found
877  return NO_ERROR;
878 }
879 
880 
881 /**
882  * @brief Get lldpRemUnknownTLVEntry object value
883  * @param[in] object Pointer to the MIB object descriptor
884  * @param[in] oid Object identifier (object name and instance identifier)
885  * @param[in] oidLen Length of the OID, in bytes
886  * @param[out] value Object value
887  * @param[in,out] valueLen Length of the object value, in bytes
888  * @return Error code
889  **/
890 
892  size_t oidLen, MibVariant *value, size_t *valueLen)
893 {
894  error_t error;
895  size_t n;
896  uint_t lldpRemTimeMark;
897  uint_t lldpRemLocalPortNum;
898  uint_t lldpRemIndex;
899  uint_t lldpRemUnknownTLVType;
900  LldpNeighborEntry *entry;
901  const uint8_t *info;
902  size_t infoLen;
903 
904  //Point to the instance identifier
905  n = object->oidLen;
906 
907  //lldpRemTimeMark is used as 1st instance identifier
908  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemTimeMark);
909  //Invalid instance identifier?
910  if(error)
911  return error;
912 
913  //lldpRemLocalPortNum is used as 2nd instance identifier
914  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemLocalPortNum);
915  //Invalid instance identifier?
916  if(error)
917  return error;
918 
919  //lldpRemIndex is used as 3rd instance identifier
920  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemIndex);
921  //Invalid instance identifier?
922  if(error)
923  return error;
924 
925  //lldpRemUnknownTLVType is used as 4th instance identifier
926  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemUnknownTLVType);
927  //Invalid instance identifier?
928  if(error)
929  return error;
930 
931  //Sanity check
932  if(n != oidLen)
934 
935  //Search the remote systems MIB for a matching row
937  lldpRemTimeMark, lldpRemLocalPortNum, lldpRemIndex);
938  //No matching row found?
939  if(entry == NULL)
941 
942  //Search the remote systems MIB for a matching TLV
943  error = lldpMgmtGetRemoteUnknownTlv(entry, lldpRemUnknownTLVType, 0,
944  &info, &infoLen);
945  //No matching TLV found?
946  if(error)
948 
949  //lldpRemUnknownTLVInfo object?
950  if(osStrcmp(object->name, "lldpRemUnknownTLVInfo") == 0)
951  {
952  //Make sure the buffer is large enough to hold the entire object
953  if(*valueLen >= infoLen)
954  {
955  //Copy object value
956  osMemcpy(value->octetString, info, infoLen);
957  //Return object length
958  *valueLen = infoLen;
959  }
960  else
961  {
962  //Report an error
963  error = ERROR_BUFFER_OVERFLOW;
964  }
965  }
966  //Unknown object?
967  else
968  {
969  //The specified object does not exist
970  error = ERROR_OBJECT_NOT_FOUND;
971  }
972 
973  //Return status code
974  return error;
975 }
976 
977 
978 /**
979  * @brief Get next lldpRemUnknownTLVEntry object
980  * @param[in] object Pointer to the MIB object descriptor
981  * @param[in] oid Object identifier
982  * @param[in] oidLen Length of the OID, in bytes
983  * @param[out] nextOid OID of the next object in the MIB
984  * @param[out] nextOidLen Length of the next object identifier, in bytes
985  * @return Error code
986  **/
987 
989  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
990 {
991  error_t error;
992  uint_t i;
993  size_t n;
994  bool_t acceptable;
995  LldpTlv tlv;
996  LldpAgentContext *context;
997  LldpNeighborEntry *entry;
998  LldpNeighborEntry *nextEntry;
999  uint8_t nextType;
1000 
1001  //Initialize variables
1002  nextEntry = NULL;
1003  nextType = 0;
1004 
1005  //Point to the LLDP agent context
1006  context = lldpMibBase.lldpAgentContext;
1007  //Make sure the context is valid
1008  if(context == NULL)
1009  return ERROR_OBJECT_NOT_FOUND;
1010 
1011  //Make sure the buffer is large enough to hold the OID prefix
1012  if(*nextOidLen < object->oidLen)
1013  return ERROR_BUFFER_OVERFLOW;
1014 
1015  //Copy OID prefix
1016  osMemcpy(nextOid, object->oid, object->oidLen);
1017 
1018  //Loop through the remote systems MIB
1019  for(i = 0; i < context->numNeighbors; i++)
1020  {
1021  //Point to the current entry
1022  entry = &context->neighbors[i];
1023 
1024  //Check whether the entry is valid
1025  if(entry->rxInfo.length > 0)
1026  {
1027  //Extract the first TLV
1028  error = lldpGetFirstTlv(&entry->rxInfo, &tlv);
1029 
1030  //Loop through the TLVs
1031  while(!error)
1032  {
1033  //Unrecognized TLV?
1034  if(tlv.type > LLDP_TLV_TYPE_MGMT_ADDR &&
1036  {
1037  //Append the instance identifier to the OID prefix
1038  n = object->oidLen;
1039 
1040  //lldpRemTimeMark is used as 1st instance identifier
1041  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->timeMark);
1042  //Invalid instance identifier?
1043  if(error)
1044  return error;
1045 
1046  //lldpRemLocalPortNum is used as 2nd instance identifier
1047  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->portIndex);
1048  //Invalid instance identifier?
1049  if(error)
1050  return error;
1051 
1052  //lldpRemIndex is used as 3rd instance identifier
1053  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->index);
1054  //Invalid instance identifier?
1055  if(error)
1056  return error;
1057 
1058  //lldpRemUnknownTLVType is used as 4th instance identifier
1059  error = mibEncodeIndex(nextOid, *nextOidLen, &n, tlv.type);
1060  //Invalid instance identifier?
1061  if(error)
1062  return error;
1063 
1064  //Check whether the resulting object identifier lexicographically
1065  //follows the specified OID
1066  if(oidComp(nextOid, n, oid, oidLen) > 0)
1067  {
1068  //Perform lexicographic comparison
1069  if(nextEntry == NULL || nextType == 0)
1070  {
1071  acceptable = TRUE;
1072  }
1073  else if(entry->timeMark < nextEntry->timeMark)
1074  {
1075  acceptable = TRUE;
1076  }
1077  else if(entry->timeMark > nextEntry->timeMark)
1078  {
1079  acceptable = FALSE;
1080  }
1081  else if(entry->portIndex < nextEntry->portIndex)
1082  {
1083  acceptable = TRUE;
1084  }
1085  else if(entry->portIndex > nextEntry->portIndex)
1086  {
1087  acceptable = FALSE;
1088  }
1089  else if(entry->index < nextEntry->index)
1090  {
1091  acceptable = TRUE;
1092  }
1093  else if(entry->index > nextEntry->index)
1094  {
1095  acceptable = FALSE;
1096  }
1097  else if(tlv.type < nextType)
1098  {
1099  acceptable = TRUE;
1100  }
1101  else
1102  {
1103  acceptable = FALSE;
1104  }
1105 
1106  //Save the closest object identifier that follows the specified
1107  //OID in lexicographic order
1108  if(acceptable)
1109  {
1110  nextEntry = entry;
1111  nextType = tlv.type;
1112  }
1113  }
1114  }
1115 
1116  //Extract the next TLV
1117  error = lldpGetNextTlv(&entry->rxInfo, &tlv);
1118  }
1119  }
1120  }
1121 
1122  //The specified OID does not lexicographically precede the name
1123  //of some object?
1124  if(nextEntry == NULL || nextType == 0)
1125  return ERROR_OBJECT_NOT_FOUND;
1126 
1127  //Append the instance identifier to the OID prefix
1128  n = object->oidLen;
1129 
1130  //lldpRemTimeMark is used as 1st instance identifier
1131  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->timeMark);
1132  //Invalid instance identifier?
1133  if(error)
1134  return error;
1135 
1136  //lldpRemLocalPortNum is used as 2nd instance identifier
1137  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->portIndex);
1138  //Invalid instance identifier?
1139  if(error)
1140  return error;
1141 
1142  //lldpRemIndex is used as 3rd instance identifier
1143  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->index);
1144  //Invalid instance identifier?
1145  if(error)
1146  return error;
1147 
1148  //lldpRemUnknownTLVType is used as 4th instance identifier
1149  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextType);
1150  //Invalid instance identifier?
1151  if(error)
1152  return error;
1153 
1154  //Save the length of the resulting object identifier
1155  *nextOidLen = n;
1156  //Next object found
1157  return NO_ERROR;
1158 }
1159 
1160 
1161 /**
1162  * @brief Get lldpRemOrgDefInfoEntry object value
1163  * @param[in] object Pointer to the MIB object descriptor
1164  * @param[in] oid Object identifier (object name and instance identifier)
1165  * @param[in] oidLen Length of the OID, in bytes
1166  * @param[out] value Object value
1167  * @param[in,out] valueLen Length of the object value, in bytes
1168  * @return Error code
1169  **/
1170 
1172  size_t oidLen, MibVariant *value, size_t *valueLen)
1173 {
1174  error_t error;
1175  size_t n;
1176  uint_t lldpRemTimeMark;
1177  uint_t lldpRemLocalPortNum;
1178  uint_t lldpRemIndex;
1179  uint8_t lldpRemOrgDefInfoOUI[LLDP_OUI_SIZE];
1180  size_t lldpRemOrgDefInfoOUILen;
1181  uint_t lldpRemOrgDefInfoSubtype;
1182  uint_t lldpRemOrgDefInfoIndex;
1183  LldpNeighborEntry *entry;
1184  const uint8_t *info;
1185  size_t infoLen;
1186 
1187  //Point to the instance identifier
1188  n = object->oidLen;
1189 
1190  //lldpRemTimeMark is used as 1st instance identifier
1191  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemTimeMark);
1192  //Invalid instance identifier?
1193  if(error)
1194  return error;
1195 
1196  //lldpRemLocalPortNum is used as 2nd instance identifier
1197  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemLocalPortNum);
1198  //Invalid instance identifier?
1199  if(error)
1200  return error;
1201 
1202  //lldpRemIndex is used as 3rd instance identifier
1203  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemIndex);
1204  //Invalid instance identifier?
1205  if(error)
1206  return error;
1207 
1208  //lldpRemOrgDefInfoOUI is used as 4th instance identifier
1209  error = mibDecodeOctetString(oid, oidLen, &n, lldpRemOrgDefInfoOUI,
1210  LLDP_OUI_SIZE, &lldpRemOrgDefInfoOUILen, FALSE);
1211  //Invalid instance identifier?
1212  if(error)
1213  return error;
1214 
1215  //lldpRemOrgDefInfoSubtype is used as 5th instance identifier
1216  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemOrgDefInfoSubtype);
1217  //Invalid instance identifier?
1218  if(error)
1219  return error;
1220 
1221  //lldpRemOrgDefInfoIndex is used as 6th instance identifier
1222  error = mibDecodeIndex(oid, oidLen, &n, &lldpRemOrgDefInfoIndex);
1223  //Invalid instance identifier?
1224  if(error)
1225  return error;
1226 
1227  //Sanity check
1228  if(n != oidLen)
1229  return ERROR_INSTANCE_NOT_FOUND;
1230 
1231  //Check the length of the OUI
1232  if(lldpRemOrgDefInfoOUILen != LLDP_OUI_SIZE)
1233  return ERROR_INSTANCE_NOT_FOUND;
1234 
1235  //Check index value
1236  if(lldpRemOrgDefInfoIndex == 0)
1237  return ERROR_INSTANCE_NOT_FOUND;
1238 
1239  //Search the remote systems MIB for a matching row
1241  lldpRemTimeMark, lldpRemLocalPortNum, lldpRemIndex);
1242  //No matching row found?
1243  if(entry == NULL)
1244  return ERROR_INSTANCE_NOT_FOUND;
1245 
1246  //Search the remote systems MIB for a matching TLV
1247  error = lldpMgmtGetRemoteOrgDefInfo(entry, LOAD24BE(lldpRemOrgDefInfoOUI),
1248  lldpRemOrgDefInfoSubtype, lldpRemOrgDefInfoIndex - 1, &info, &infoLen);
1249  //No matching TLV found?
1250  if(error)
1251  return ERROR_INSTANCE_NOT_FOUND;
1252 
1253  //lldpRemOrgDefInfo object?
1254  if(osStrcmp(object->name, "lldpRemOrgDefInfo") == 0)
1255  {
1256  //Make sure the buffer is large enough to hold the entire object
1257  if(*valueLen >= infoLen)
1258  {
1259  //Copy object value
1260  osMemcpy(value->octetString, info, infoLen);
1261  //Return object length
1262  *valueLen = infoLen;
1263  }
1264  else
1265  {
1266  //Report an error
1267  error = ERROR_BUFFER_OVERFLOW;
1268  }
1269  }
1270  //Unknown object?
1271  else
1272  {
1273  //The specified object does not exist
1274  error = ERROR_OBJECT_NOT_FOUND;
1275  }
1276 
1277  //Return status code
1278  return error;
1279 }
1280 
1281 
1282 /**
1283  * @brief Get next lldpRemOrgDefInfoEntry object
1284  * @param[in] object Pointer to the MIB object descriptor
1285  * @param[in] oid Object identifier
1286  * @param[in] oidLen Length of the OID, in bytes
1287  * @param[out] nextOid OID of the next object in the MIB
1288  * @param[out] nextOidLen Length of the next object identifier, in bytes
1289  * @return Error code
1290  **/
1291 
1293  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
1294 {
1295  error_t error;
1296  uint_t k;
1297  uint_t i;
1298  size_t n;
1299  bool_t acceptable;
1300  LldpTlv tlv;
1301  LldpAgentContext *context;
1302  LldpNeighborEntry *entry;
1303  LldpNeighborEntry *nextEntry;
1304  LldpOrgDefTlv *orgDefTlv;
1305  LldpOrgDefTlv *nextOrgDefTlv;
1306  uint_t index;
1307  uint_t nextIndex;
1308 
1309  //Initialize variables
1310  nextEntry = NULL;
1311  nextOrgDefTlv = NULL;
1312  nextIndex = 0;
1313 
1314  //Point to the LLDP agent context
1315  context = lldpMibBase.lldpAgentContext;
1316  //Make sure the context is valid
1317  if(context == NULL)
1318  return ERROR_OBJECT_NOT_FOUND;
1319 
1320  //Make sure the buffer is large enough to hold the OID prefix
1321  if(*nextOidLen < object->oidLen)
1322  return ERROR_BUFFER_OVERFLOW;
1323 
1324  //Copy OID prefix
1325  osMemcpy(nextOid, object->oid, object->oidLen);
1326 
1327  //Loop through the remote systems MIB
1328  for(i = 0; i < context->numNeighbors; i++)
1329  {
1330  //Point to the current entry
1331  entry = &context->neighbors[i];
1332 
1333  //Check whether the entry is valid
1334  if(entry->rxInfo.length > 0)
1335  {
1336  //Initialize occurrence index
1337  k = 0;
1338 
1339  //Extract the first TLV
1340  error = lldpGetFirstTlv(&entry->rxInfo, &tlv);
1341 
1342  //Loop through the TLVs
1343  while(!error)
1344  {
1345  //Organizationally specific TLV?
1346  if(tlv.type == LLDP_TLV_TYPE_ORG_DEFINED)
1347  {
1348  //Malformed TLV?
1349  if(tlv.length < sizeof(LldpOrgDefTlv))
1350  {
1351  break;
1352  }
1353 
1354  //Point to the organizationally specific tag
1355  orgDefTlv = (LldpOrgDefTlv *) tlv.value;
1356 
1357  //Append the instance identifier to the OID prefix
1358  n = object->oidLen;
1359 
1360  //lldpRemTimeMark is used as 1st instance identifier
1361  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->timeMark);
1362  //Invalid instance identifier?
1363  if(error)
1364  return error;
1365 
1366  //lldpRemLocalPortNum is used as 2nd instance identifier
1367  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->portIndex);
1368  //Invalid instance identifier?
1369  if(error)
1370  return error;
1371 
1372  //lldpRemIndex is used as 3rd instance identifier
1373  error = mibEncodeIndex(nextOid, *nextOidLen, &n, entry->index);
1374  //Invalid instance identifier?
1375  if(error)
1376  return error;
1377 
1378  //lldpRemOrgDefInfoOUI is used as 4th instance identifier
1379  error = mibEncodeOctetString(nextOid, *nextOidLen, &n,
1380  orgDefTlv->oui, LLDP_OUI_SIZE, FALSE);
1381  //Invalid instance identifier?
1382  if(error)
1383  return error;
1384 
1385  //lldpRemOrgDefInfoSubtype is used as 5th instance identifier
1386  error = mibEncodeIndex(nextOid, *nextOidLen, &n,
1387  orgDefTlv->subtype);
1388  //Invalid instance identifier?
1389  if(error)
1390  return error;
1391 
1392  //lldpRemOrgDefInfoIndex is used to identify a particular
1393  //instance of the TLV
1394  if(n <= oidLen && oidComp(nextOid, n, oid, n) == 0)
1395  {
1396  index = ++k;
1397  }
1398  else
1399  {
1400  index = 1;
1401  }
1402 
1403  //lldpRemOrgDefInfoIndex is used as 6th instance identifier
1404  error = mibEncodeIndex(nextOid, *nextOidLen, &n, index);
1405  //Invalid instance identifier?
1406  if(error)
1407  return error;
1408 
1409  //Check whether the resulting object identifier lexicographically
1410  //follows the specified OID
1411  if(oidComp(nextOid, n, oid, oidLen) > 0)
1412  {
1413  //Perform lexicographic comparison
1414  if(nextEntry == NULL || nextOrgDefTlv == NULL)
1415  {
1416  acceptable = TRUE;
1417  }
1418  else if(entry->timeMark < nextEntry->timeMark)
1419  {
1420  acceptable = TRUE;
1421  }
1422  else if(entry->timeMark > nextEntry->timeMark)
1423  {
1424  acceptable = FALSE;
1425  }
1426  else if(entry->portIndex < nextEntry->portIndex)
1427  {
1428  acceptable = TRUE;
1429  }
1430  else if(entry->portIndex > nextEntry->portIndex)
1431  {
1432  acceptable = FALSE;
1433  }
1434  else if(entry->index < nextEntry->index)
1435  {
1436  acceptable = TRUE;
1437  }
1438  else if(entry->index > nextEntry->index)
1439  {
1440  acceptable = FALSE;
1441  }
1442  else if(osMemcmp(orgDefTlv->oui, nextOrgDefTlv->oui,
1443  LLDP_OUI_SIZE) < 0)
1444  {
1445  acceptable = TRUE;
1446  }
1447  else if(osMemcmp(orgDefTlv->oui, nextOrgDefTlv->oui,
1448  LLDP_OUI_SIZE) > 0)
1449  {
1450  acceptable = FALSE;
1451  }
1452  else if(orgDefTlv->subtype < nextOrgDefTlv->subtype)
1453  {
1454  acceptable = TRUE;
1455  }
1456  else if(orgDefTlv->subtype > nextOrgDefTlv->subtype)
1457  {
1458  acceptable = FALSE;
1459  }
1460  else if(index < nextIndex)
1461  {
1462  acceptable = TRUE;
1463  }
1464  else
1465  {
1466  acceptable = FALSE;
1467  }
1468 
1469  //Save the closest object identifier that follows the specified
1470  //OID in lexicographic order
1471  if(acceptable)
1472  {
1473  nextEntry = entry;
1474  nextOrgDefTlv = orgDefTlv;
1475  nextIndex = index;
1476  }
1477  }
1478  }
1479 
1480  //Extract the next TLV
1481  error = lldpGetNextTlv(&entry->rxInfo, &tlv);
1482  }
1483  }
1484  }
1485 
1486  //The specified OID does not lexicographically precede the name
1487  //of some object?
1488  if(nextEntry == NULL || nextOrgDefTlv == NULL || nextIndex == 0)
1489  return ERROR_OBJECT_NOT_FOUND;
1490 
1491  //Append the instance identifier to the OID prefix
1492  n = object->oidLen;
1493 
1494  //lldpRemTimeMark is used as 1st instance identifier
1495  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->timeMark);
1496  //Invalid instance identifier?
1497  if(error)
1498  return error;
1499 
1500  //lldpRemLocalPortNum is used as 2nd instance identifier
1501  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->portIndex);
1502  //Invalid instance identifier?
1503  if(error)
1504  return error;
1505 
1506  //lldpRemIndex is used as 3rd instance identifier
1507  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextEntry->index);
1508  //Invalid instance identifier?
1509  if(error)
1510  return error;
1511 
1512  //lldpRemOrgDefInfoOUI is used as 4th instance identifier
1513  error = mibEncodeOctetString(nextOid, *nextOidLen, &n,
1514  nextOrgDefTlv->oui, LLDP_OUI_SIZE, FALSE);
1515  //Invalid instance identifier?
1516  if(error)
1517  return error;
1518 
1519  //lldpRemOrgDefInfoSubtype is used as 5th instance identifier
1520  error = mibEncodeIndex(nextOid, *nextOidLen, &n,
1521  nextOrgDefTlv->subtype);
1522  //Invalid instance identifier?
1523  if(error)
1524  return error;
1525 
1526  //lldpRemOrgDefInfoIndex is used as 6th instance identifier
1527  error = mibEncodeIndex(nextOid, *nextOidLen, &n, nextIndex);
1528  //Invalid instance identifier?
1529  if(error)
1530  return error;
1531 
1532  //Save the length of the resulting object identifier
1533  *nextOidLen = n;
1534  //Next object found
1535  return NO_ERROR;
1536 }
1537 
1538 #endif
error_t lldpGetFirstTlv(LldpDataUnit *lldpdu, LldpTlv *tlv)
Extract the first TLV from an LLDPDU.
Definition: lldp_tlv.c:247
uint8_t type
Definition: lldp_tlv.h:202
uint32_t timeMark
Timestamp used to implement time-filtered rows.
Definition: lldp.h:262
error_t lldpMibGetNextLldpRemManAddrEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next lldpRemManAddrEntry object.
int bool_t
Definition: compiler_port.h:53
error_t lldpMgmtGetRemoteSysName(LldpNeighborEntry *entry, const char_t **sysName, size_t *sysNameLen)
Extract system name from remote systems MIB.
Definition: lldp_mgmt.c:1403
uint8_t portId[]
Definition: lldp_tlv.h:254
uint16_t enabledCap
Definition: lldp_tlv.h:275
uint8_t chassisId[]
Definition: lldp_tlv.h:243
signed int int_t
Definition: compiler_port.h:49
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:142
int_t lldpMgmtFindRemoteMgmtAddr(LldpNeighborEntry *entry, uint8_t mgmtAddrSubtype, const uint8_t *mgmtAddr, size_t mgmtAddrLen)
Search the remote system MIB for a given management address.
Definition: lldp_mgmt.c:1539
OID (Object Identifier)
#define TRUE
Definition: os_port.h:50
LldpOrgDefTlv
Definition: lldp_tlv.h:313
@ LLDP_TLV_TYPE_MGMT_ADDR
Management Address.
Definition: lldp_tlv.h:101
error_t lldpGetNextTlv(LldpDataUnit *lldpdu, LldpTlv *tlv)
Extract the next TLV from an LLDPDU.
Definition: lldp_tlv.c:264
error_t lldpMgmtGetRemoteMgmtAddr(LldpNeighborEntry *entry, uint_t index, LldpMgmtAddrSubtype *mgmtAddrSubtype, const uint8_t **mgmtAddr, size_t *mgmtAddrLen, LldpIfNumSubtype *ifNumSubtype, uint32_t *ifNum, const uint8_t **oid, size_t *oidLen)
Extract management address from remote systems MIB.
Definition: lldp_mgmt.c:1608
error_t lldpMibGetLldpRemOrgDefInfoEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpRemOrgDefInfoEntry object value.
@ LLDP_TLV_TYPE_ORG_DEFINED
Organizationally Specific TLVs.
Definition: lldp_tlv.h:102
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
#define osStrcmp(s1, s2)
Definition: os_port.h:171
LldpAgentContext * lldpAgentContext
LldpPortIdSubtype
Port ID subtypes.
Definition: lldp_tlv.h:128
@ LLDP_IF_NUM_SUBTYPE_SYS_PORT_NUM
System port number.
Definition: lldp_tlv.h:178
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
LLDP MIB module implementation (lldpRemoteSystemsData subtree)
uint8_t oid[]
Definition: lldp_tlv.h:300
@ LLDP_MIB_MAN_ADDR_IF_SUBTYPE_UNKNOWN
Unknown.
error_t lldpMgmtGetRemoteOrgDefInfo(LldpNeighborEntry *entry, uint32_t oui, uint8_t subtype, uint_t index, const uint8_t **info, size_t *infoLen)
Extract organizationally defined TLV from remote systems MIB.
Definition: lldp_mgmt.c:1705
#define LLDP_OUI_SIZE
Definition: lldp_tlv.h:39
#define FALSE
Definition: os_port.h:46
error_t lldpMgmtGetRemotePortDesc(LldpNeighborEntry *entry, const char_t **portDesc, size_t *portDescLen)
Extract port description from remote systems MIB.
Definition: lldp_mgmt.c:1360
error_t lldpMibGetLldpRemUnknownTLVEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpRemUnknownTLVEntry object value.
LldpIfNumSubtype
Interface numbering subtypes.
Definition: lldp_tlv.h:175
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
error_t
Error codes.
Definition: error.h:43
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:257
LLDP MIB module.
General definitions for cryptographic algorithms.
error_t lldpMibGetNextLldpRemUnknownTLVEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next lldpRemUnknownTLVEntry object.
error_t lldpMibGetNextLldpRemOrgDefInfoEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next lldpRemOrgDefInfoEntry object.
error_t lldpMibGetLldpRemManAddrEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpRemManAddrEntry object value.
@ LLDP_MIB_MAN_ADDR_IF_SUBTYPE_IF_INDEX
Interface index.
error_t lldpMibGetLldpRemEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get lldpRemEntry object value.
error_t lldpMibGetNextLldpRemEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next lldpRemEntry object.
error_t lldpMgmtGetRemoteSysDesc(LldpNeighborEntry *entry, const char_t **sysDesc, size_t *sysDescLen)
Extract system description from remote systems MIB.
Definition: lldp_mgmt.c:1446
error_t lldpMgmtGetRemoteSysCap(LldpNeighborEntry *entry, uint16_t *supportedCap, uint16_t *enabledCap)
Extract system capabilities from remote systems MIB.
Definition: lldp_mgmt.c:1489
@ LLDP_MIB_MAN_ADDR_IF_SUBTYPE_SYS_PORT_NUM
System port number.
LLDP neighbor entry.
Definition: lldp.h:260
char char_t
Definition: compiler_port.h:48
@ LLDP_IF_NUM_SUBTYPE_IF_INDEX
Interface index.
Definition: lldp_tlv.h:177
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 mibDecodeIndex(const uint8_t *oid, size_t oidLen, size_t *pos, uint_t *index)
Decode instance identifier (index)
Definition: mib_common.c:64
uint_t portIndex
Port on which the LLDPDU was received.
Definition: lldp.h:263
error_t lldpMgmtGetRemotePortId(LldpNeighborEntry *entry, LldpPortIdSubtype *portIdSubtype, const uint8_t **portId, size_t *portIdLen)
Extract port ID from remote systems MIB.
Definition: lldp_mgmt.c:1309
Common definitions for MIB modules.
uint8_t n
size_t length
Definition: lldp_tlv.h:203
@ ERROR_OBJECT_NOT_FOUND
Definition: error.h:256
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
#define LOAD24BE(p)
Definition: cpu_endian.h:197
uint32_t ifNum
Definition: lldp_tlv.h:298
#define MibObject
Definition: mib_common.h:46
uint8_t value[]
Definition: tcp.h:369
uint8_t oidLen
Definition: lldp_tlv.h:299
LldpChassisIdSubtype
Chassis ID subtypes.
Definition: lldp_tlv.h:111
uint8_t reverseInt8(uint8_t value)
Reverse bit order in a byte.
Definition: cpu_endian.c:90
error_t lldpMgmtGetRemoteChassisId(LldpNeighborEntry *entry, LldpChassisIdSubtype *chassisIdSubtype, const uint8_t **chassisId, size_t *chassisIdLen)
Extract chassis ID from remote systems MIB.
Definition: lldp_mgmt.c:1257
#define LldpAgentContext
Definition: lldp.h:40
uint32_t index
Arbitrary local integer value used to identify the entry.
Definition: lldp.h:261
LldpNeighborEntry * lldpMgmtFindRemoteTableEntry(LldpAgentContext *context, uint32_t timeMark, uint_t portIndex, uint32_t index)
Search the remote systems MIB for a given entry.
Definition: lldp_mgmt.c:1218
Management of the LLDP agent.
error_t mibEncodeIndex(uint8_t *oid, size_t maxOidLen, size_t *pos, uint_t index)
Encode instance identifier (index)
Definition: mib_common.c:47
LldpMibBase lldpMibBase
LLDP MIB base.
Ipv4Addr addr
Definition: nbns_common.h:123
MibVariant
Definition: mib_common.h:196
#define LLDP_MAX_MGMT_ADDR_LEN
Definition: lldp_tlv.h:74
unsigned int uint_t
Definition: compiler_port.h:50
TCP/IP stack core.
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
LLDP MIB module implementation.
LldpMgmtAddrTlv1
Definition: lldp_tlv.h:288
TLV structure.
Definition: lldp_tlv.h:200
error_t lldpMgmtGetRemoteUnknownTlv(LldpNeighborEntry *entry, uint8_t type, uint_t index, const uint8_t **info, size_t *infoLen)
Extract unknown TLV from remote systems MIB.
Definition: lldp_mgmt.c:1686
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
ASN.1 (Abstract Syntax Notation One)
LldpDataUnit rxInfo
Remote system information.
Definition: lldp.h:265
uint8_t * value
Definition: lldp_tlv.h:204