bridge_mib_impl_base.c
Go to the documentation of this file.
1 /**
2  * @file bridge_mib_impl.c
3  * @brief Bridge MIB module implementation (dot1dBase subtree)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2019-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSTP 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/bridge_mib_module.h"
38 #include "mibs/bridge_mib_impl.h"
40 #include "core/crypto.h"
41 #include "encoding/asn1.h"
42 #include "encoding/oid.h"
43 #include "stp/stp.h"
44 #include "stp/stp_mgmt.h"
45 #include "rstp/rstp.h"
46 #include "rstp/rstp_mgmt.h"
47 #include "debug.h"
48 
49 //Check TCP/IP stack configuration
50 #if (BRIDGE_MIB_SUPPORT == ENABLED)
51 
52 
53 /**
54  * @brief Get dot1dBaseBridgeAddress object value
55  * @param[in] object Pointer to the MIB object descriptor
56  * @param[in] oid Object identifier (object name and instance identifier)
57  * @param[in] oidLen Length of the OID, in bytes
58  * @param[out] value Object value
59  * @param[in,out] valueLen Length of the object value, in bytes
60  * @return Error code
61  **/
62 
64  size_t oidLen, MibVariant *value, size_t *valueLen)
65 {
66  error_t error;
67  MacAddr bridgeAddr;
68 
69  //Make sure the buffer is large enough to hold the entire object
70  if(*valueLen < sizeof(MacAddr))
71  return ERROR_BUFFER_OVERFLOW;
72 
73  //Initialize object value
74  bridgeAddr = MAC_UNSPECIFIED_ADDR;
75 
76 #if (STP_SUPPORT == ENABLED)
77  //Valid STP bridge context?
79  {
80  //Retrieve the MAC address assigned to the bridge
82  &bridgeAddr);
83  }
84  else
85 #endif
86 #if (RSTP_SUPPORT == ENABLED)
87  //Valid RSTP bridge context?
89  {
90  //Retrieve the MAC address assigned to the bridge
92  &bridgeAddr);
93  }
94  else
95 #endif
96  //Invalid bridge context?
97  {
98  //Report an error
99  error = ERROR_READ_FAILED;
100  }
101 
102  //Check status code
103  if(!error)
104  {
105  //Copy the bridge MAC address
106  macCopyAddr(value->octetString, &bridgeAddr);
107  //A MAC address shall be encoded as six octets
108  *valueLen = sizeof(MacAddr);
109  }
110 
111  //Return status code
112  return error;
113 }
114 
115 
116 /**
117  * @brief Get dot1dBaseNumPorts object value
118  * @param[in] object Pointer to the MIB object descriptor
119  * @param[in] oid Object identifier (object name and instance identifier)
120  * @param[in] oidLen Length of the OID, in bytes
121  * @param[out] value Object value
122  * @param[in,out] valueLen Length of the object value, in bytes
123  * @return Error code
124  **/
125 
126 error_t bridgeMibGetDot1dBaseNumPorts(const MibObject *object, const uint8_t *oid,
127  size_t oidLen, MibVariant *value, size_t *valueLen)
128 {
129  error_t error;
130  uint_t numPorts;
131 
132  //Initialize object value
133  numPorts = 0;
134 
135 #if (STP_SUPPORT == ENABLED)
136  //Valid STP bridge context?
137  if(bridgeMibBase.stpBridgeContext != NULL)
138  {
139  //Get the number of ports controlled by this bridging entity
141  }
142  else
143 #endif
144 #if (RSTP_SUPPORT == ENABLED)
145  //Valid RSTP bridge context?
146  if(bridgeMibBase.rstpBridgeContext != NULL)
147  {
148  //Get the number of ports controlled by this bridging entity
150  }
151  else
152 #endif
153  //Invalid bridge context?
154  {
155  //Report an error
156  error = ERROR_READ_FAILED;
157  }
158 
159  //Check status code
160  if(!error)
161  {
162  //Return the value of the object
163  value->integer = numPorts;
164  }
165 
166  //Return status code
167  return error;
168 }
169 
170 
171 /**
172  * @brief Get dot1dBaseType object value
173  * @param[in] object Pointer to the MIB object descriptor
174  * @param[in] oid Object identifier (object name and instance identifier)
175  * @param[in] oidLen Length of the OID, in bytes
176  * @param[out] value Object value
177  * @param[in,out] valueLen Length of the object value, in bytes
178  * @return Error code
179  **/
180 
181 error_t bridgeMibGetDot1dBaseType(const MibObject *object, const uint8_t *oid,
182  size_t oidLen, MibVariant *value, size_t *valueLen)
183 {
184  //This object indicates what type of bridging this bridge can perform
185  value->integer = bridgeMibBase.dot1dBaseType;
186 
187  //Successful processing
188  return NO_ERROR;
189 }
190 
191 
192 /**
193  * @brief Get dot1dBasePortEntry object value
194  * @param[in] object Pointer to the MIB object descriptor
195  * @param[in] oid Object identifier (object name and instance identifier)
196  * @param[in] oidLen Length of the OID, in bytes
197  * @param[out] value Object value
198  * @param[in,out] valueLen Length of the object value, in bytes
199  * @return Error code
200  **/
201 
202 error_t bridgeMibGetDot1dBasePortEntry(const MibObject *object, const uint8_t *oid,
203  size_t oidLen, MibVariant *value, size_t *valueLen)
204 {
205  error_t error;
206  size_t n;
207  uint_t portIndex;
208  uint16_t dot1dBasePort;
209 
210  //Point to the instance identifier
211  n = object->oidLen;
212 
213  //dot1dBasePort is used as instance identifier
214  error = mibDecodePort(oid, oidLen, &n, &dot1dBasePort);
215  //Invalid instance identifier?
216  if(error)
217  return error;
218 
219  //Sanity check
220  if(n != oidLen)
222 
223  //Retrieve the port that matches the specified port number
224  portIndex = bridgeMibGetPortIndex(dot1dBasePort);
225  //Invalid port number?
226  if(portIndex == 0)
228 
229  //dot1dBasePort object?
230  if(!strcmp(object->name, "dot1dBasePort"))
231  {
232  //This object specifies the port number of the port for which this entry
233  //contains bridge management information
234  value->integer = dot1dBasePort;
235  }
236  //dot1dBasePortIfIndex object?
237  else if(!strcmp(object->name, "dot1dBasePortIfIndex"))
238  {
239  //This object specifies the value of the instance of the ifIndex object,
240  //defined in IF-MIB, for the interface corresponding to this port
241  value->integer = portIndex;
242  }
243  //dot1dBasePortCircuit object?
244  else if(!strcmp(object->name, "dot1dBasePortCircuit"))
245  {
246  //Make sure the buffer is large enough to hold the entire object
247  if(*valueLen >= sizeof(uint8_t))
248  {
249  //This object contains the name of an object instance unique to this
250  //port. For a port which has a unique value of dot1dBasePortIfIndex,
251  //this object can have the value { 0 0 }
252  value->oid[0] = 0;
253 
254  //Return object length
255  *valueLen = sizeof(uint8_t);
256  }
257  else
258  {
259  //Report an error
260  error = ERROR_BUFFER_OVERFLOW;
261  }
262  }
263  //dot1dBasePortDelayExceededDiscards object?
264  else if(!strcmp(object->name, "dot1dBasePortDelayExceededDiscards"))
265  {
266  //The number of frames discarded by this port due to excessive transit
267  //delay through the bridge. It is incremented by both transparent and
268  //source route bridges
269  value->counter32 = 0;
270  }
271  //dot1dBasePortMtuExceededDiscards object?
272  else if(!strcmp(object->name, "dot1dBasePortMtuExceededDiscards"))
273  {
274  //The number of frames discarded by this port due to an excessive size.
275  //It is incremented by both transparent and source route bridges
276  value->counter32 = 0;
277  }
278  //Unknown object?
279  else
280  {
281  //The specified object does not exist
282  error = ERROR_OBJECT_NOT_FOUND;
283  }
284 
285  //Return status code
286  return error;
287 }
288 
289 
290 /**
291  * @brief Get next dot1dBasePortEntry object
292  * @param[in] object Pointer to the MIB object descriptor
293  * @param[in] oid Object identifier
294  * @param[in] oidLen Length of the OID, in bytes
295  * @param[out] nextOid OID of the next object in the MIB
296  * @param[out] nextOidLen Length of the next object identifier, in bytes
297  * @return Error code
298  **/
299 
301  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
302 {
303  error_t error;
304  uint_t i;
305  size_t n;
306  uint_t numPorts;
307  uint16_t portNum;
308  uint16_t curPortNum;
309 
310  //Initialize variable
311  portNum = 0;
312 
313  //Make sure the buffer is large enough to hold the OID prefix
314  if(*nextOidLen < object->oidLen)
315  return ERROR_BUFFER_OVERFLOW;
316 
317  //Copy OID prefix
318  osMemcpy(nextOid, object->oid, object->oidLen);
319 
320  //Retrieve the number of ports
321  numPorts = bridgeMibGetNumPorts();
322 
323  //Loop through the ports of the bridge
324  for(i = 1; i <= numPorts; i++)
325  {
326  //Retrieve the port number associated with the current port
327  curPortNum = bridgeMibGetPortNum(i);
328 
329  //Append the instance identifier to the OID prefix
330  n = object->oidLen;
331 
332  //dot1dBasePort is used as instance identifier
333  error = mibEncodeIndex(nextOid, *nextOidLen, &n, curPortNum);
334  //Any error to report?
335  if(error)
336  return error;
337 
338  //Check whether the resulting object identifier lexicographically
339  //follows the specified OID
340  if(oidComp(nextOid, n, oid, oidLen) > 0)
341  {
342  //Save the closest object identifier that follows the specified
343  //OID in lexicographic order
344  if(portNum == 0 || curPortNum < portNum)
345  {
346  portNum = curPortNum;
347  }
348  }
349  }
350 
351  //The specified OID does not lexicographically precede the name
352  //of some object?
353  if(portNum == 0)
354  return ERROR_OBJECT_NOT_FOUND;
355 
356  //Append the instance identifier to the OID prefix
357  n = object->oidLen;
358 
359  //dot1dBasePort is used as instance identifier
360  error = mibEncodeIndex(nextOid, *nextOidLen, &n, portNum);
361  //Any error to report?
362  if(error)
363  return error;
364 
365  //Save the length of the resulting object identifier
366  *nextOidLen = n;
367  //Next object found
368  return NO_ERROR;
369 }
370 
371 #endif
ASN.1 (Abstract Syntax Notation One)
uint16_t bridgeMibGetPortNum(uint16_t portIndex)
Get the port number that matches the specified port index.
uint_t bridgeMibGetNumPorts(void)
Get the number of ports.
uint_t bridgeMibGetPortIndex(uint16_t portNum)
Get the port index that matches the specified port number.
Bridge MIB module implementation.
error_t bridgeMibGetDot1dBaseNumPorts(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get dot1dBaseNumPorts object value.
error_t bridgeMibGetDot1dBasePortEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get dot1dBasePortEntry object value.
error_t bridgeMibGetNextDot1dBasePortEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next dot1dBasePortEntry object.
error_t bridgeMibGetDot1dBaseBridgeAddress(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get dot1dBaseBridgeAddress object value.
error_t bridgeMibGetDot1dBaseType(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get dot1dBaseType object value.
BridgeMibBase bridgeMibBase
Bridge MIB base.
Bridge MIB module.
unsigned int uint_t
Definition: compiler_port.h:50
General definitions for cryptographic algorithms.
Debugging facilities.
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_OBJECT_NOT_FOUND
Definition: error.h:255
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:256
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:142
@ ERROR_READ_FAILED
Definition: error.h:222
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:53
#define macCopyAddr(destMacAddr, srcMacAddr)
Definition: ethernet.h:127
MacAddr
Definition: ethernet.h:195
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
error_t mibDecodePort(const uint8_t *oid, size_t oidLen, size_t *pos, uint16_t *port)
Decode instance identifier (port number)
Definition: mib_common.c:495
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
MibVariant
Definition: mib_common.h:196
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
RSTP (Rapid Spanning Tree Protocol)
error_t rstpMgmtGetNumPorts(RstpBridgeContext *context, uint_t *value)
Get the number of ports.
Definition: rstp_mgmt.c:435
error_t rstpMgmtGetBridgeAddr(RstpBridgeContext *context, MacAddr *value)
Get the MAC address assigned to the bridge.
Definition: rstp_mgmt.c:478
Management of the RSTP bridge.
STP (Spanning Tree Protocol)
error_t stpMgmtGetNumPorts(StpBridgeContext *context, uint_t *value)
Get the number of ports.
Definition: stp_mgmt.c:356
error_t stpMgmtGetBridgeAddr(StpBridgeContext *context, MacAddr *value)
Get the MAC address assigned to the bridge.
Definition: stp_mgmt.c:376
Management of the STP bridge.
StpBridgeContext * stpBridgeContext
RstpBridgeContext * rstpBridgeContext
uint8_t value[]
Definition: tcp.h:369