mib2_impl_udp.c
Go to the documentation of this file.
1 /**
2  * @file mib2_impl_udp.c
3  * @brief MIB-II module implementation (UDP group)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL SNMP_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "mibs/mib_common.h"
37 #include "mibs/mib2_module.h"
38 #include "mibs/mib2_impl.h"
39 #include "mibs/mib2_impl_udp.h"
40 #include "core/crypto.h"
41 #include "encoding/asn1.h"
42 #include "encoding/oid.h"
43 #include "debug.h"
44 
45 //Check TCP/IP stack configuration
46 #if (MIB2_SUPPORT == ENABLED && MIB2_UDP_GROUP_SUPPORT == ENABLED)
47 
48 
49 /**
50  * @brief Get udpEntry object value
51  * @param[in] object Pointer to the MIB object descriptor
52  * @param[in] oid Object identifier (object name and instance identifier)
53  * @param[in] oidLen Length of the OID, in bytes
54  * @param[out] value Object value
55  * @param[in,out] valueLen Length of the object value, in bytes
56  * @return Error code
57  **/
58 
59 error_t mib2GetUdpEntry(const MibObject *object, const uint8_t *oid,
60  size_t oidLen, MibVariant *value, size_t *valueLen)
61 {
62  error_t error;
63  uint_t i;
64  size_t n;
65  Ipv4Addr localIpAddr;
66  uint16_t localPort;
67 
68  //Point to the instance identifier
69  n = object->oidLen;
70 
71  //udpLocalAddress is used as 1st instance identifier
72  error = mibDecodeIpv4Addr(oid, oidLen, &n, &localIpAddr);
73  //Invalid instance identifier?
74  if(error)
75  return error;
76 
77  //udpLocalPort is used as 2nd instance identifier
78  error = mibDecodePort(oid, oidLen, &n, &localPort);
79  //Invalid instance identifier?
80  if(error)
81  return error;
82 
83  //Sanity check
84  if(n != oidLen)
86 
87  //Loop through socket descriptors
88  for(i = 0; i < SOCKET_MAX_COUNT; i++)
89  {
90  //Point to current socket
91  Socket *socket = &socketTable[i];
92 
93  //UDP socket?
94  if(socket->type == SOCKET_TYPE_DGRAM)
95  {
96  //Check local IP address
97  if(socket->localIpAddr.length == sizeof(Ipv6Addr))
98  continue;
99  if(socket->localIpAddr.ipv4Addr != localIpAddr)
100  continue;
101  //Check local port number
102  if(socket->localPort != localPort)
103  continue;
104 
105  //A matching socket has been found
106  break;
107  }
108  }
109 
110  //No matching connection found in socket table?
111  if(i >= SOCKET_MAX_COUNT)
112  {
113  //Loop through the UDP callback table
114  for(i = 0; i < UDP_CALLBACK_TABLE_SIZE; i++)
115  {
116  //Point to the current entry
118 
119  //Check whether the entry is currently in use
120  if(entry->callback != NULL)
121  {
122  //Check local port number
123  if(entry->port == localPort)
124  break;
125  }
126  }
127 
128  //No matching connection found in UDP callback table?
129  if(i >= UDP_CALLBACK_TABLE_SIZE)
131  }
132 
133  //udpLocalAddress object?
134  if(!osStrcmp(object->name, "udpLocalAddress"))
135  {
136  //Get object value
137  ipv4CopyAddr(value->ipAddr, &localIpAddr);
138  }
139  //udpLocalPort object?
140  else if(!osStrcmp(object->name, "udpLocalPort"))
141  {
142  //Get object value
143  value->integer = localPort;
144  }
145  //Unknown object?
146  else
147  {
148  //The specified object does not exist
149  error = ERROR_OBJECT_NOT_FOUND;
150  }
151 
152  //Return status code
153  return error;
154 }
155 
156 
157 /**
158  * @brief Get next udpEntry object
159  * @param[in] object Pointer to the MIB object descriptor
160  * @param[in] oid Object identifier
161  * @param[in] oidLen Length of the OID, in bytes
162  * @param[out] nextOid OID of the next object in the MIB
163  * @param[out] nextOidLen Length of the next object identifier, in bytes
164  * @return Error code
165  **/
166 
167 error_t mib2GetNextUdpEntry(const MibObject *object, const uint8_t *oid,
168  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
169 {
170  error_t error;
171  uint_t i;
172  size_t n;
173  bool_t acceptable;
174  Ipv4Addr localIpAddr;
175  uint16_t localPort;
176 
177  //Initialize variables
178  localIpAddr = IPV4_UNSPECIFIED_ADDR;
179  localPort = 0;
180 
181  //Make sure the buffer is large enough to hold the OID prefix
182  if(*nextOidLen < object->oidLen)
183  return ERROR_BUFFER_OVERFLOW;
184 
185  //Copy OID prefix
186  osMemcpy(nextOid, object->oid, object->oidLen);
187 
188  //Loop through socket descriptors
189  for(i = 0; i < SOCKET_MAX_COUNT; i++)
190  {
191  //Point to current socket
192  Socket *socket = &socketTable[i];
193 
194  //UDP socket?
195  if(socket->type == SOCKET_TYPE_DGRAM)
196  {
197  //Filter out IPv6 connections
198  if(socket->localIpAddr.length != sizeof(Ipv6Addr) &&
199  socket->remoteIpAddr.length != sizeof(Ipv6Addr))
200  {
201  //Append the instance identifier to the OID prefix
202  n = object->oidLen;
203 
204  //udpLocalAddress is used as 1st instance identifier
205  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, socket->localIpAddr.ipv4Addr);
206  //Any error to report?
207  if(error)
208  return error;
209 
210  //udpLocalPort is used as 2nd instance identifier
211  error = mibEncodePort(nextOid, *nextOidLen, &n, socket->localPort);
212  //Any error to report?
213  if(error)
214  return error;
215 
216  //Check whether the resulting object identifier lexicographically
217  //follows the specified OID
218  if(oidComp(nextOid, n, oid, oidLen) > 0)
219  {
220  //Perform lexicographic comparison
221  if(localPort == 0)
222  {
223  acceptable = TRUE;
224  }
225  else if(ntohl(socket->localIpAddr.ipv4Addr) < ntohl(localIpAddr))
226  {
227  acceptable = TRUE;
228  }
229  else if(ntohl(socket->localIpAddr.ipv4Addr) > ntohl(localIpAddr))
230  {
231  acceptable = FALSE;
232  }
233  else if(socket->localPort < localPort)
234  {
235  acceptable = TRUE;
236  }
237  else
238  {
239  acceptable = FALSE;
240  }
241 
242  //Save the closest object identifier that follows the specified
243  //OID in lexicographic order
244  if(acceptable)
245  {
246  localIpAddr = socket->localIpAddr.ipv4Addr;
247  localPort = socket->localPort;
248  }
249  }
250  }
251  }
252  }
253 
254  //Loop through the UDP callback table
255  for(i = 0; i < UDP_CALLBACK_TABLE_SIZE; i++)
256  {
257  //Point to the current entry
259 
260  //Check whether the entry is currently in use
261  if(entry->callback != NULL)
262  {
263  //Append the instance identifier to the OID prefix
264  n = object->oidLen;
265 
266  //udpLocalAddress is used as 1st instance identifier
267  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, IPV4_UNSPECIFIED_ADDR);
268  //Any error to report?
269  if(error)
270  return error;
271 
272  //udpLocalPort is used as 2nd instance identifier
273  error = mibEncodePort(nextOid, *nextOidLen, &n, entry->port);
274  //Any error to report?
275  if(error)
276  return error;
277 
278  //Check whether the resulting object identifier lexicographically
279  //follows the specified OID
280  if(oidComp(nextOid, n, oid, oidLen) > 0)
281  {
282  //Perform lexicographic comparison
283  if(localPort == 0)
284  {
285  acceptable = TRUE;
286  }
287  else if(ntohl(IPV4_UNSPECIFIED_ADDR) < ntohl(localIpAddr))
288  {
289  acceptable = TRUE;
290  }
291  else if(ntohl(IPV4_UNSPECIFIED_ADDR) > ntohl(localIpAddr))
292  {
293  acceptable = FALSE;
294  }
295  else if(entry->port < localPort)
296  {
297  acceptable = TRUE;
298  }
299  else
300  {
301  acceptable = FALSE;
302  }
303 
304  //Save the closest object identifier that follows the specified
305  //OID in lexicographic order
306  if(acceptable)
307  {
308  localIpAddr = IPV4_UNSPECIFIED_ADDR;
309  localPort = entry->port;
310  }
311  }
312  }
313  }
314 
315  //The specified OID does not lexicographically precede the name
316  //of some object?
317  if(localPort == 0)
318  return ERROR_OBJECT_NOT_FOUND;
319 
320  //Append the instance identifier to the OID prefix
321  n = object->oidLen;
322 
323  //udpLocalAddress is used as 1st instance identifier
324  error = mibEncodeIpv4Addr(nextOid, *nextOidLen, &n, localIpAddr);
325  //Any error to report?
326  if(error)
327  return error;
328 
329  //udpLocalPort is used as 2nd instance identifier
330  error = mibEncodePort(nextOid, *nextOidLen, &n, localPort);
331  //Any error to report?
332  if(error)
333  return error;
334 
335  //Save the length of the resulting object identifier
336  *nextOidLen = n;
337  //Next object found
338  return NO_ERROR;
339 }
340 
341 #endif
ASN.1 (Abstract Syntax Notation One)
int_t socket(int_t family, int_t type, int_t protocol)
Create a socket that is bound to a specific transport service provider.
Definition: bsd_socket.c:65
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
#define ntohl(value)
Definition: cpu_endian.h:422
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
#define ipv4CopyAddr(destIpAddr, srcIpAddr)
Definition: ipv4.h:148
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:267
#define IPV4_UNSPECIFIED_ADDR
Definition: ipv4.h:110
Ipv6Addr
Definition: ipv6.h:251
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
MIB-II module implementation.
error_t mib2GetNextUdpEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next udpEntry object.
error_t mib2GetUdpEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get udpEntry object value.
Definition: mib2_impl_udp.c:59
MIB-II module implementation (UDP group)
MIB-II module.
error_t mibEncodePort(uint8_t *oid, size_t maxOidLen, size_t *pos, uint16_t port)
Encode instance identifier (port number)
Definition: mib_common.c:478
error_t mibDecodeIpv4Addr(const uint8_t *oid, size_t oidLen, size_t *pos, Ipv4Addr *ipAddr)
Decode instance identifier (IPv4 address)
Definition: mib_common.c:698
error_t mibEncodeIpv4Addr(uint8_t *oid, size_t maxOidLen, size_t *pos, Ipv4Addr ipAddr)
Encode instance identifier (IPv4 address)
Definition: mib_common.c:664
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
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 osStrcmp(s1, s2)
Definition: os_port.h:171
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:49
@ SOCKET_TYPE_DGRAM
Definition: socket.h:86
#define Socket
Definition: socket.h:36
#define SOCKET_MAX_COUNT
Definition: socket.h:46
UDP receive callback entry.
Definition: udp.h:111
uint16_t port
Definition: udp.h:113
UdpRxCallback callback
Definition: udp.h:114
uint8_t value[]
Definition: tcp.h:369
UdpRxCallbackEntry udpCallbackTable[UDP_CALLBACK_TABLE_SIZE]
Definition: udp.c:54
#define UDP_CALLBACK_TABLE_SIZE
Definition: udp.h:48