lldp_misc.c
Go to the documentation of this file.
1 /**
2  * @file lldp_misc.c
3  * @brief Helper functions for LLDP
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 LLDP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "lldp/lldp.h"
37 #include "lldp/lldp_fsm.h"
38 #include "lldp/lldp_misc.h"
39 #include "lldp/lldp_debug.h"
40 #include "debug.h"
41 
42 //Check TCP/IP stack configuration
43 #if (LLDP_SUPPORT == ENABLED)
44 
45 //LLDP multicast address (refer to IEEE Std 802.1AB-2005, section 8.1)
46 const MacAddr LLDP_MULTICAST_ADDR = {{{0x01, 0x80, 0xC2, 0x00, 0x00, 0x0E}}};
47 
48 
49 /**
50  * @brief LLDP agent timer handler
51  *
52  * This routine must be periodically called by the TCP/IP stack to
53  * manage LLDP agent operation
54  *
55  * @param[in] context Pointer to the LLDP agent context
56  **/
57 
58 void lldpTick(LldpAgentContext *context)
59 {
60  uint_t i;
61  bool_t linkState;
63  NetInterface *interface;
64 
65  //Point to the underlying network interface
66  interface = context->interface;
67 
68  //Loop through the ports
69  for(i = 0; i < context->numPorts; i++)
70  {
71  //Point to the current port
72  port = &context->ports[i];
73 
74 #if (LLDP_TX_MODE_SUPPORT == ENABLED)
75  //Timers used for the transmit state machine are decremented once per second
76  lldpDecrementTimer(&port->txShutdownWhile);
77  lldpDecrementTimer(&port->txDelayWhile);
78  lldpDecrementTimer(&port->txTTR);
79 #endif
80 
81  //Poll link state
82  linkState = lldpGetLinkState(context, i + 1);
83 
84  //Link state change detected?
85  if(!port->portEnabled && linkState && interface->linkState)
86  {
87  //Debug message
88  TRACE_INFO("Port %" PRIu8 ": Link is up...\r\n", port->portIndex);
89 
90  //The portEnabled variable is externally controlled. Its value reflects
91  //the operational state of the MAC service supporting the port
92  port->portEnabled = TRUE;
93 
94 #if (LLDP_TX_MODE_SUPPORT == ENABLED)
95  //Update LLDP state machines
96  lldpFsm(context);
97 
98  //Force the port to transmit an LLDP frame
99  port->somethingChangedLocal = TRUE;
100 #endif
101  }
102  else if(port->portEnabled && !linkState)
103  {
104  //Debug message
105  TRACE_INFO("Port %" PRIu8 ": Link is down...\r\n", port->portIndex);
106 
107  //The portEnabled variable is externally controlled. Its value reflects
108  //the operational state of the MAC service supporting the port
109  port->portEnabled = FALSE;
110  }
111  else
112  {
113  //No link state change
114  }
115  }
116 
117 #if (LLDP_RX_MODE_SUPPORT == ENABLED)
118  //Timers used for the receive state machine are decremented once per second
119  lldpDecrementTimer(&context->tooManyNeighborsTimer);
120 
121  //Loop through the remote systems MIB
122  for(i = 0; i < context->numNeighbors; i++)
123  {
124  LldpNeighborEntry *entry;
125 
126  //Point to the current entry
127  entry = &context->neighbors[i];
128 
129  //Check whether the entry is valid
130  if(entry->rxInfo.length > 0)
131  {
132  //Decrement the TTL value
133  lldpDecrementTimer(&entry->rxInfoTTL);
134 
135  //Check whether the TTL has expired
136  if(entry->rxInfoTTL == 0)
137  {
138  //Valid port index?
139  if(entry->portIndex >= 1 && entry->portIndex <= context->numPorts)
140  {
141  //Point to the port that matches the specified port index
142  port = &context->ports[entry->portIndex - 1];
143 
144  //The rxInfoAge variable indicates that the rxInfoTTL timing
145  //counter has expired
146  port->rxInfoAge = TRUE;
147  }
148  }
149  }
150  }
151 #endif
152 
153  //Update LLDP state machines
154  lldpFsm(context);
155 
156  //Any registered callback?
157  if(context->tickCallback != NULL)
158  {
159  //Invoke user callback function
160  context->tickCallback(context);
161  }
162 }
163 
164 
165 /**
166  * @brief Process incoming LLDP frame
167  * @param[in] context Pointer to the LLDP agent context
168  **/
169 
171 {
172  error_t error;
173  uint_t portIndex;
174  SocketMsg msg;
176 
177  //Point to the receive buffer
178  msg = SOCKET_DEFAULT_MSG;
179  msg.data = context->lldpdu.data;
181 
182  //Receive LLDP frame
183  error = socketReceiveMsg(context->socket, &msg, 0);
184 
185  //Any frame received?
186  if(!error)
187  {
188  //Save the length of the LLDP frame
189  context->lldpdu.length = msg.length;
190 
191 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
192  //Save the port number on which the LLDP frame was received
193  portIndex = MAX(msg.switchPort, 1);
194 #else
195  //The station has a single port
196  portIndex = 1;
197 #endif
198 
199  //Debug message
200  TRACE_INFO("LLDP frame received on port %u (%" PRIuSIZE " bytes)...\r\n",
201  portIndex, context->lldpdu.length);
202 
203  //Sanity check
204  if(portIndex <= context->numPorts)
205  {
206  //The LLDPDU shall be delivered to the LLDP receive module if, and
207  //only if, the destination address value is the assigned LLDP multicast
208  //address and the Ethertype value is the LLDP Ethertype
210  msg.ethType == ETH_TYPE_LLDP)
211  {
212  //Point to the port that matches the specified port index
213  port = &context->ports[portIndex - 1];
214 
215  //Any registered callback?
216  if(context->receiveCallback != NULL)
217  {
218  //Invoke user callback function
219  context->receiveCallback(port, &context->lldpdu);
220  }
221 
222 #if (LLDP_RX_MODE_SUPPORT == ENABLED)
223  //The global variable rcvFrame shall be set to TRUE
224  port->rcvFrame = TRUE;
225 
226  //The frame shall be sent to the LLDP receive module for validation
227  lldpFsm(context);
228 #endif
229  }
230  }
231  }
232 }
233 
234 
235 /**
236  * @brief LLDP data unit validation
237  * @param[in] port Pointer to the port context
238  * @param[in] lldpdu Pointer to the received LLDP data unit
239  * @return Error code
240  **/
241 
243 {
244 #if (LLDP_RX_MODE_SUPPORT == ENABLED)
245  error_t error;
246  uint_t index;
247  LldpTlv tlv;
248  LldpAgentContext *context;
249 
250  //Initialize index value
251  index = 0;
252 
253  //Point to the LLDP agent context
254  context = port->context;
255  //Initialize rxTTL value
256  context->rxTTL = 0;
257 
258  //Extract the first TLV
259  error = lldpGetFirstTlv(lldpdu, &tlv);
260 
261  //Parse the LLDP data unit
262  while(!error)
263  {
264  //The LLDPDU shall be checked to verify the presence of the three
265  //mandatory TLVs at the beginning of the LLDPDU
266  if(index == 0)
267  {
268  //The first TLV must be the Chassis ID TLV
269  if(tlv.type != LLDP_TLV_TYPE_CHASSIS_ID)
270  {
271  error = ERROR_INVALID_FRAME;
272  break;
273  }
274 
275  //Sanity check
276  if(tlv.length < sizeof(LldpChassisIdTlv))
277  {
278  error = ERROR_INVALID_FRAME;
279  break;
280  }
281 
282  //Out of range information string length?
283  if((tlv.length - sizeof(LldpChassisIdTlv)) < LLDP_MIN_CHASSIS_ID_LEN ||
285  {
286  error = ERROR_INVALID_FRAME;
287  break;
288  }
289  }
290  else if(index == 1)
291  {
292  //The second TLV must be the Port ID TLV
293  if(tlv.type != LLDP_TLV_TYPE_PORT_ID)
294  {
295  error = ERROR_INVALID_FRAME;
296  break;
297  }
298 
299  //Sanity check
300  if(tlv.length < sizeof(LldpPortIdTlv))
301  {
302  error = ERROR_INVALID_FRAME;
303  break;
304  }
305 
306  //Out of range information string length?
307  if((tlv.length - sizeof(LldpPortIdTlv)) < LLDP_MIN_PORT_ID_LEN ||
308  (tlv.length - sizeof(LldpPortIdTlv)) > LLDP_MAX_PORT_ID_LEN)
309  {
310  error = ERROR_INVALID_FRAME;
311  break;
312  }
313  }
314  else if(index == 2)
315  {
316  //The third TLV must be the Time To Live TLV
318  {
319  error = ERROR_INVALID_FRAME;
320  break;
321  }
322 
323  //Check the length of the Time To Live TLV
324  if(tlv.length < sizeof(LldpTimeToLiveTlv))
325  {
326  error = ERROR_INVALID_FRAME;
327  break;
328  }
329 
330  //The first two octets of the TLV information string shall be
331  //extracted and rxTTL shall be set to this value
332  context->rxTTL = LOAD16BE(tlv.value);
333 
334  //If rxTTL equals zero, a shutdown frame has been received. The MSAP
335  //identifier and rxTTL shall be passed up to the LLDP MIB manager, and
336  //further LLDPDU validation shall be terminated
337  if(context->rxTTL == 0)
338  {
339  index++;
340  error = NO_ERROR;
341  break;
342  }
343  }
344  else
345  {
346  //Check optional TLVs
348  {
349  //If the end of the LLDPDU has been reached, the MSAP identifier,
350  //rxTTL, and all validated TLVs shall be passed to the LLDP manager
351  //for LLDP remote systems MIB updating
352  break;
353  }
354  else if(tlv.type >= LLDP_TLV_TYPE_CHASSIS_ID &&
356  {
357  //If the LLDPDU contains more than one Chassis ID TLV, Port ID TLV,
358  //or Time To Live TLV, then the LLDPDU shall be discarded
359  error = ERROR_INVALID_FRAME;
360  break;
361  }
362  else if(tlv.type >= LLDP_TLV_TYPE_PORT_DESC &&
364  {
365  //An LLDPDU should not contain more than one Port Description TLV,
366  //System Name TLV, System Description TLV and System Capabilities TLV
367  }
368  else if(tlv.type == LLDP_TLV_TYPE_MGMT_ADDR)
369  {
370  //An LLDPDU may contain more than one Management Address TLV
371  }
372  else if(tlv.type == LLDP_TLV_TYPE_ORG_DEFINED)
373  {
374  //If the TLV's OUI and/or organizationally defined subtype are
375  //not recognized, the statsTLVsUnrecognizedTotal counter shall be
376  //incremented, and the TLV shall be assumed to be validated
377  }
378  else
379  {
380  //The TLV is unrecognized and may be a basic TLV from a later
381  //LLDP version. The statsTLVsUnrecognizedTotal counter shall be
382  //incremented, and the TLV shall be assumed to be validated
383  port->statsTLVsUnrecognizedTotal++;
384  }
385  }
386 
387  //Increment index value
388  index++;
389 
390  //Extract the next TLV
391  error = lldpGetNextTlv(lldpdu, &tlv);
392  }
393 
394  //Mandatory TLVs are required for all LLDPDUs
395  if(index < 3)
396  {
397  error = ERROR_INVALID_FRAME;
398  }
399 
400  //Check status code
401  if(error == NO_ERROR || error == ERROR_END_OF_STREAM)
402  {
403  //Successful parsing
404  error = NO_ERROR;
405  }
406  else if(error == ERROR_INVALID_SYNTAX)
407  {
408  //If any TLV extends past the physical end of the frame, the TLV shall be
409  //discarded. The statsTLVsDiscardedTotal and statsFramesInErrorsTotal
410  //counters shall both be incremented
411  port->statsTLVsDiscardedTotal++;
412  port->statsFramesInErrorsTotal++;
413 
414  //All validated TLVs shall be passed to the LLDP manager for LLDP remote
415  //systems MIB updating
416  error = NO_ERROR;
417  }
418  else
419  {
420  //The statsFramesDiscardedTotal and statsFramesInErrorsTotal counters
421  //shall both be incremented
422  port->statsFramesDiscardedTotal++;
423  port->statsFramesInErrorsTotal++;
424 
425  //The variable badFrame shall be set to TRUE
426  context->badFrame = TRUE;
427  }
428 
429  //Return status code
430  return error;
431 #else
432  //RX mode is not implemented
433  return ERROR_INVALID_FRAME;
434 #endif
435 }
436 
437 
438 /**
439  * @brief Create a new entry in the remote systems MIB
440  * @param[in] context Pointer to the LLDP agent context
441  * @return Pointer to the newly created entry
442  **/
443 
445 {
446  uint_t i;
447  LldpNeighborEntry *entry;
448 
449  //Initialize pointer
450  entry = NULL;
451 
452  //Loop through the remote systems MIB
453  for(i = 0; i < context->numNeighbors; i++)
454  {
455  //Check whether the current entry is available for use
456  if(context->neighbors[i].rxInfo.length == 0)
457  {
458  //Point to the current entry
459  entry = &context->neighbors[i];
460  break;
461  }
462  }
463 
464  //Return a pointer to the newly created entry
465  return entry;
466 }
467 
468 
469 /**
470  * @brief Search the remote systems MIB for a matching MSAP identifier
471  * @param[in] context Pointer to the LLDP agent context
472  * @param[in] lldpdu Pointer to the received LLDP data unit
473  * @return Pointer to the matching entry, if any
474  **/
475 
477  LldpDataUnit *lldpdu)
478 {
479  error_t error;
480  uint_t i;
481  LldpMsapId msapId1;
482  LldpMsapId msapId2;
483  LldpNeighborEntry *entry;
484 
485  //Initialize pointer
486  entry = NULL;
487 
488  //Extract the MSAP identifier from the received LLDPDU
489  error = lldpGetMsapId(lldpdu, &msapId1);
490 
491  //Check status code
492  if(!error)
493  {
494  //Loop through the remote systems MIB
495  for(i = 0; i < context->numNeighbors; i++)
496  {
497  //Valid entry?
498  if(context->neighbors[i].rxInfo.length > 0)
499  {
500  //Extract the MSAP identifier from the current entry
501  error = lldpGetMsapId(&context->neighbors[i].rxInfo, &msapId2);
502 
503  //Check status code
504  if(!error)
505  {
506  //Compare MSAP identifiers
507  if(lldpCompareMsapId(&msapId1, &msapId2))
508  {
509  //A matching entry has been found
510  entry = &context->neighbors[i];
511  break;
512  }
513  }
514  }
515  }
516  }
517 
518  //Return a pointer to the matching entry, if any
519  return entry;
520 }
521 
522 
523 /**
524  * @brief Remove an entry from the remote systems MIB
525  * @param[in] entry Pointer to a given entry
526  **/
527 
529 {
530  //Invalidate the current entry
531  entry->rxInfoTTL = 0;
532  entry->rxInfo.length = 0;
533  entry->portIndex = 0;
534 }
535 
536 
537 /**
538  * @brief Get link state
539  * @param[in] context Pointer to the LLDP agent context
540  * @param[in] portIndex Port index
541  * @return Error code
542  **/
543 
545 {
546  bool_t linkState;
547  NetInterface *interface;
548 
549  //Point to the underlying network interface
550  interface = context->interface;
551 
552  //Valid switch driver?
553  if(context->numPorts > 1 && interface->switchDriver != NULL &&
554  interface->switchDriver->getLinkState != NULL)
555  {
556  //Get exclusive access
558  //Retrieve the link state of the specified port
559  linkState = interface->switchDriver->getLinkState(interface, portIndex);
560  //Release exclusive access
562  }
563  else
564  {
565  //Retrieve the link state of the network interface
566  linkState = interface->linkState;
567  }
568 
569  //Return link state
570  return linkState;
571 }
572 
573 
574 /**
575  * @brief Add the LLDP multicast address to the static MAC table
576  * @param[in] context Pointer to the LLDP agent context
577  * @return Error code
578  **/
579 
581 {
582 #if (LLDP_RX_MODE_SUPPORT == ENABLED)
583  error_t error;
584  SwitchFdbEntry entry;
585  NetInterface *interface;
586 
587  //Initialize status code
588  error = NO_ERROR;
589 
590  //Point to the underlying network interface
591  interface = context->interface;
592 
593  //Get exclusive access
595 
596  //Valid switch driver?
597  if(interface->switchDriver != NULL &&
598  interface->switchDriver->addStaticFdbEntry != NULL)
599  {
600  //Format forwarding database entry
602  entry.srcPort = 0;
604  entry.override = FALSE;
605 
606  //Update the static MAC table of the switch
607  error = interface->switchDriver->addStaticFdbEntry(interface, &entry);
608  }
609 
610  //Check status code
611  if(!error)
612  {
613  //Add the LLDP multicast address to the MAC filter table
614  error = ethAcceptMacAddr(interface, &LLDP_MULTICAST_ADDR);
615  }
616 
617  //Release exclusive access
619 
620  //Return status code
621  return error;
622 #else
623  //Not implemented
624  return NO_ERROR;
625 #endif
626 }
627 
628 
629 /**
630  * @brief Remove the LLDP multicast address from the static MAC table
631  * @param[in] context Pointer to the LLDP agent context
632  * @return Error code
633  **/
634 
636 {
637 #if (LLDP_RX_MODE_SUPPORT == ENABLED)
638  error_t error;
639  SwitchFdbEntry entry;
640  NetInterface *interface;
641 
642  //Initialize status code
643  error = NO_ERROR;
644 
645  //Point to the underlying network interface
646  interface = context->interface;
647 
648  //Get exclusive access
650 
651  //Valid switch driver?
652  if(interface->switchDriver != NULL &&
653  interface->switchDriver->deleteStaticFdbEntry != NULL)
654  {
655  //Format forwarding database entry
657  entry.srcPort = 0;
658  entry.destPorts = 0;
659  entry.override = FALSE;
660 
661  //Update the static MAC table of the switch
662  error = interface->switchDriver->deleteStaticFdbEntry(interface, &entry);
663  }
664 
665  //Check status code
666  if(!error)
667  {
668  //Remove the LLDP multicast address to the MAC filter table
669  ethDropMacAddr(interface, &LLDP_MULTICAST_ADDR);
670  }
671 
672  //Release exclusive access
674 
675  //Return status code
676  return error;
677 #else
678  //Not implemented
679  return NO_ERROR;
680 #endif
681 }
682 
683 
684 /**
685  * @brief Port's MAC address generation
686  * @param[in] port Pointer to the port context
687  **/
688 
690 {
691  int_t i;
692  uint8_t c;
693  MacAddr *macAddr;
694  LldpAgentContext *context;
695 
696  //Point to the LLDP agent context
697  context = port->context;
698 
699  //Check the number of ports
700  if(context->numPorts > 1)
701  {
702  //Get the MAC address of the underlying network interface
703  macAddr = &context->interface->macAddr;
704 
705  //Retrieve port index
706  c = port->portIndex;
707 
708  //Generate a unique MAC address for the port
709  for(i = 5; i >= 0; i--)
710  {
711  //Generate current byte
712  port->macAddr.b[i] = macAddr->b[i] + c;
713 
714  //Propagate the carry if necessary
715  if(port->macAddr.b[i] < macAddr->b[i])
716  {
717  c = 1;
718  }
719  else
720  {
721  c = 0;
722  }
723  }
724  }
725  else
726  {
727  //Use the MAC address of the underlying network interface
728  port->macAddr = context->interface->macAddr;
729  }
730 }
731 
732 
733 /**
734  * @brief Extract MSAP identifier
735  * @param[in] lldpdu Pointer to the LLDP data unit
736  * @param[out] msapId MSAP identifier
737  * @return Error code
738  **/
739 
741 {
742  error_t error;
743 
744  //Extract chassis identifier
745  error = lldpGetTlv(lldpdu, LLDP_TLV_TYPE_CHASSIS_ID, 0,
746  &msapId->chassisId, &msapId->chassisIdLen);
747 
748  //Check status code
749  if(!error)
750  {
751  //Extract port identifier
752  error = lldpGetTlv(lldpdu, LLDP_TLV_TYPE_PORT_ID, 0,
753  &msapId->portId, &msapId->portIdLen);
754  }
755 
756  //Return status code
757  return error;
758 }
759 
760 
761 /**
762  * @brief Compare MSAP identifiers
763  * @param[in] msapId1 Pointer to the first MSAP identifier
764  * @param[in] msapId2 Pointer to the second MSAP identifier
765  * @return TRUE if the MSAP identifiers match, else FALSE
766  **/
767 
768 bool_t lldpCompareMsapId(const LldpMsapId *msapId1, const LldpMsapId *msapId2)
769 {
770  bool_t res;
771 
772  //Check whether the MSAP identifiers match
773  if(msapId1->chassisIdLen != msapId2->chassisIdLen)
774  {
775  res = FALSE;
776  }
777  else if(osMemcmp(msapId1->chassisId, msapId2->chassisId,
778  msapId1->chassisIdLen) != 0)
779  {
780  res = FALSE;
781  }
782  else if(msapId1->portIdLen != msapId2->portIdLen)
783  {
784  res = FALSE;
785  }
786  else if(osMemcmp(msapId1->portId, msapId2->portId,
787  msapId1->portIdLen) != 0)
788  {
789  res = FALSE;
790  }
791  else
792  {
793  res = TRUE;
794  }
795 
796  //Return comparison result
797  return res;
798 }
799 
800 
801 /**
802  * @brief Notify LLDP that an object in the LLDP local system MIB has changed
803  * @param[in] context Pointer to the LLDP agent context
804  **/
805 
807 {
808 #if (LLDP_TX_MODE_SUPPORT == ENABLED)
809  uint_t i;
810 
811  //Loop through the ports
812  for(i = 0; i < context->numPorts; i++)
813  {
814  context->ports[i].somethingChangedLocal = TRUE;
815  }
816 #endif
817 }
818 
819 
820 /**
821  * @brief Decrement timer value
822  * @param[in,out] x Actual timer value
823  **/
824 
826 {
827  //If the variable has a non-zero value, this procedure decrements the value
828  //of the variable by 1
829  if(*x > 0)
830  {
831  *x -= 1;
832  }
833 }
834 
835 #endif
void lldpFsm(LldpAgentContext *context)
LLDP state machine implementation.
Definition: lldp_fsm.c:84
error_t lldpGetFirstTlv(LldpDataUnit *lldpdu, LldpTlv *tlv)
Extract the first TLV from an LLDPDU.
Definition: lldp_tlv.c:247
error_t ethAcceptMacAddr(NetInterface *interface, const MacAddr *macAddr)
Add a unicast/multicast address to the MAC filter table.
Definition: ethernet.c:594
uint8_t type
Definition: lldp_tlv.h:202
error_t lldpDropMulticastAddr(LldpAgentContext *context)
Remove the LLDP multicast address from the static MAC table.
Definition: lldp_misc.c:635
@ LLDP_TLV_TYPE_SYS_CAP
System Capabilities.
Definition: lldp_tlv.h:100
int bool_t
Definition: compiler_port.h:53
uint32_t destPorts
Definition: nic.h:152
signed int int_t
Definition: compiler_port.h:49
#define netMutex
Definition: net_legacy.h:195
void lldpProcessFrame(LldpAgentContext *context)
Process incoming LLDP frame.
Definition: lldp_misc.c:170
uint8_t x
Definition: lldp_ext_med.h:211
#define TRUE
Definition: os_port.h:50
Message and ancillary data.
Definition: socket.h:241
@ 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
#define LLDP_MAX_PORT_ID_LEN
Definition: lldp_tlv.h:54
void * data
Pointer to the payload.
Definition: socket.h:242
@ LLDP_TLV_TYPE_ORG_DEFINED
Organizationally Specific TLVs.
Definition: lldp_tlv.h:102
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
LLDP state machine.
@ ERROR_END_OF_STREAM
Definition: error.h:210
const uint8_t res[]
const MacAddr LLDP_MULTICAST_ADDR
Definition: lldp_misc.c:46
#define LLDP_MAX_LLDPDU_SIZE
Definition: lldp.h:94
error_t ethDropMacAddr(NetInterface *interface, const MacAddr *macAddr)
Remove a unicast/multicast address from the MAC filter table.
Definition: ethernet.c:666
@ LLDP_TLV_TYPE_END_OF_LLDPDU
End Of LLDPDU.
Definition: lldp_tlv.h:93
uint16_t ethType
Ethernet type field.
Definition: socket.h:256
@ ETH_TYPE_LLDP
Definition: ethernet.h:171
const uint8_t * portId
Port identifier.
Definition: lldp.h:250
Data logging functions for debugging purpose (LLDP)
LldpChassisIdTlv
Definition: lldp_tlv.h:244
#define FALSE
Definition: os_port.h:46
const SocketMsg SOCKET_DEFAULT_MSG
Definition: socket.c:52
size_t length
Actual length of the payload, in bytes.
Definition: socket.h:244
size_t portIdLen
Length of the port identifier, in bytes.
Definition: lldp.h:251
@ ERROR_INVALID_FRAME
Definition: error.h:86
#define LLDP_MIN_CHASSIS_ID_LEN
Definition: lldp_tlv.h:47
error_t
Error codes.
Definition: error.h:43
LldpNeighborEntry * lldpCreateNeighborEntry(LldpAgentContext *context)
Create a new entry in the remote systems MIB.
Definition: lldp_misc.c:444
error_t lldpCheckDataUnit(LldpPortEntry *port, LldpDataUnit *lldpdu)
LLDP data unit validation.
Definition: lldp_misc.c:242
#define LLDP_MAX_CHASSIS_ID_LEN
Definition: lldp_tlv.h:49
const uint8_t * chassisId
Chassis identifier.
Definition: lldp.h:248
void lldpDeleteNeighborEntry(LldpNeighborEntry *entry)
Remove an entry from the remote systems MIB.
Definition: lldp_misc.c:528
uint_t rxInfoTTL
Time remaining until the information is no longer valid.
Definition: lldp.h:264
#define NetInterface
Definition: net.h:36
bool_t lldpCompareMsapId(const LldpMsapId *msapId1, const LldpMsapId *msapId2)
Compare MSAP identifiers.
Definition: lldp_misc.c:768
#define LldpPortEntry
Definition: lldp.h:44
uint8_t switchPort
Switch port identifier.
Definition: socket.h:259
error_t socketReceiveMsg(Socket *socket, SocketMsg *message, uint_t flags)
Receive a message from a connectionless socket.
Definition: socket.c:1894
Helper functions for LLDP.
error_t lldpGetTlv(LldpDataUnit *lldpdu, uint8_t type, uint_t index, const uint8_t **value, size_t *length)
Search a LLDPDU for a given TLV.
Definition: lldp_tlv.c:200
void lldpTick(LldpAgentContext *context)
LLDP agent timer handler.
Definition: lldp_misc.c:58
bool_t lldpGetLinkState(LldpAgentContext *context, uint_t portIndex)
Get link state.
Definition: lldp_misc.c:544
LldpPortIdTlv
Definition: lldp_tlv.h:255
#define TRACE_INFO(...)
Definition: debug.h:95
MacAddr
Definition: ethernet.h:195
uint16_t port
Definition: dns_common.h:267
@ LLDP_TLV_TYPE_CHASSIS_ID
Chassis ID.
Definition: lldp_tlv.h:94
LLDP neighbor entry.
Definition: lldp.h:260
#define MAX(a, b)
Definition: os_port.h:67
MacAddr destMacAddr
Destination MAC address.
Definition: socket.h:255
uint_t portIndex
Port on which the LLDPDU was received.
Definition: lldp.h:263
void lldpSomethingChangedLocal(LldpAgentContext *context)
Notify LLDP that an object in the LLDP local system MIB has changed.
Definition: lldp_misc.c:806
size_t chassisIdLen
Length of the chassis identifier, in bytes.
Definition: lldp.h:249
size_t length
Definition: lldp_tlv.h:203
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
MacAddr macAddr
Definition: nic.h:150
uint8_t srcPort
Definition: nic.h:151
LldpTimeToLiveTlv
Definition: lldp_tlv.h:265
LldpNeighborEntry * lldpFindNeighborEntry(LldpAgentContext *context, LldpDataUnit *lldpdu)
Search the remote systems MIB for a matching MSAP identifier.
Definition: lldp_misc.c:476
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:130
size_t size
Size of the payload, in bytes.
Definition: socket.h:243
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
void lldpDecrementTimer(uint_t *x)
Decrement timer value.
Definition: lldp_misc.c:825
#define LldpAgentContext
Definition: lldp.h:40
error_t lldpAcceptMulticastAddr(LldpAgentContext *context)
Add the LLDP multicast address to the static MAC table.
Definition: lldp_misc.c:580
@ LLDP_TLV_TYPE_PORT_ID
Port ID.
Definition: lldp_tlv.h:95
void lldpGeneratePortAddr(LldpPortEntry *port)
Port's MAC address generation.
Definition: lldp_misc.c:689
#define SWITCH_CPU_PORT_MASK
Definition: nic.h:60
LLDP (Link Layer Discovery Protocol)
#define PRIuSIZE
unsigned int uint_t
Definition: compiler_port.h:50
#define LOAD16BE(p)
Definition: cpu_endian.h:186
TCP/IP stack core.
@ LLDP_TLV_TYPE_TIME_TO_LIVE
Time To Live.
Definition: lldp_tlv.h:96
error_t lldpGetMsapId(LldpDataUnit *lldpdu, LldpMsapId *msapId)
Extract MSAP identifier.
Definition: lldp_misc.c:740
MSAP identifier.
Definition: lldp.h:247
TLV structure.
Definition: lldp_tlv.h:200
@ LLDP_TLV_TYPE_PORT_DESC
Port Description.
Definition: lldp_tlv.h:97
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:514
bool_t override
Definition: nic.h:153
Debugging facilities.
Forwarding database entry.
Definition: nic.h:149
#define LLDP_MIN_PORT_ID_LEN
Definition: lldp_tlv.h:52
#define LldpDataUnit
Definition: lldp.h:36
LldpDataUnit rxInfo
Remote system information.
Definition: lldp.h:265
uint8_t * value
Definition: lldp_tlv.h:204