udp_mib_impl.c
Go to the documentation of this file.
1 /**
2  * @file udp_mib_impl.c
3  * @brief UDP MIB module implementation
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 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 1.9.6
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/udp_mib_module.h"
38 #include "mibs/udp_mib_impl.h"
39 #include "core/crypto.h"
40 #include "encoding/asn1.h"
41 #include "encoding/oid.h"
42 #include "debug.h"
43 
44 //Check TCP/IP stack configuration
45 #if (UDP_MIB_SUPPORT == ENABLED && UDP_SUPPORT == ENABLED)
46 
47 
48 /**
49  * @brief UDP MIB module initialization
50  * @return Error code
51  **/
52 
54 {
55  //Debug message
56  TRACE_INFO("Initializing UDP-MIB base...\r\n");
57 
58  //Clear UDP MIB base
59  memset(&udpMibBase, 0, sizeof(udpMibBase));
60 
61  //Successful processing
62  return NO_ERROR;
63 }
64 
65 
66 /**
67  * @brief Get udpEndpointEntry object value
68  * @param[in] object Pointer to the MIB object descriptor
69  * @param[in] oid Object identifier (object name and instance identifier)
70  * @param[in] oidLen Length of the OID, in bytes
71  * @param[out] value Object value
72  * @param[in,out] valueLen Length of the object value, in bytes
73  * @return Error code
74  **/
75 
76 error_t udpMibGetUdpEndpointEntry(const MibObject *object, const uint8_t *oid,
77  size_t oidLen, MibVariant *value, size_t *valueLen)
78 {
79  error_t error;
80  uint_t i;
81  size_t n;
82  IpAddr localIpAddr;
83  uint16_t localPort;
84  IpAddr remoteIpAddr;
85  uint16_t remotePort;
86  uint32_t instance;
87 
88  //Point to the instance identifier
89  n = object->oidLen;
90 
91  //udpEndpointLocalAddressType and udpEndpointLocalAddress are used
92  //as 1st and 2nd instance identifiers
93  error = mibDecodeIpAddr(oid, oidLen, &n, &localIpAddr);
94  //Invalid instance identifier?
95  if(error)
96  return error;
97 
98  //udpEndpointLocalPort is used as 3rd instance identifier
99  error = mibDecodePort(oid, oidLen, &n, &localPort);
100  //Invalid instance identifier?
101  if(error)
102  return error;
103 
104  //udpEndpointRemoteAddressType and udpEndpointRemoteAddress are used
105  //as 4th and 5th instance identifiers
106  error = mibDecodeIpAddr(oid, oidLen, &n, &remoteIpAddr);
107  //Invalid instance identifier?
108  if(error)
109  return error;
110 
111  //udpEndpointRemotePort is used as 6th instance identifier
112  error = mibDecodePort(oid, oidLen, &n, &remotePort);
113  //Invalid instance identifier?
114  if(error)
115  return error;
116 
117  //udpEndpointInstance is used as 7th instance identifier
118  error = mibDecodeUnsigned32(oid, oidLen, &n, &instance);
119  //Invalid instance identifier?
120  if(error)
121  return error;
122 
123  //Sanity check
124  if(n != oidLen)
126 
127  //Loop through socket descriptors
128  for(i = 0; i < SOCKET_MAX_COUNT; i++)
129  {
130  //Point to current socket
131  Socket *socket = &socketTable[i];
132 
133  //UDP socket?
134  if(socket->type == SOCKET_TYPE_DGRAM)
135  {
136  //Check local IP address
137  if(!ipCompAddr(&socket->localIpAddr, &localIpAddr))
138  continue;
139  //Check local port number
140  if(socket->localPort != localPort)
141  continue;
142  //Check remote IP address
143  if(!ipCompAddr(&socket->remoteIpAddr, &remoteIpAddr))
144  continue;
145  //Check local port number
146  if(socket->remotePort != remotePort)
147  continue;
148 
149  //A matching socket has been found
150  break;
151  }
152  }
153 
154  //No matching connection found in socket table?
155  if(i >= SOCKET_MAX_COUNT)
156  {
157  //Loop through the UDP callback table
158  for(i = 0; i < UDP_CALLBACK_TABLE_SIZE; i++)
159  {
160  //Point to the current entry
161  UdpRxCallbackDesc *entry = &udpCallbackTable[i];
162 
163  //Check whether the entry is currently in used
164  if(entry->callback != NULL)
165  {
166  //Check local port number
167  if(entry->port == localPort)
168  break;
169  }
170  }
171 
172  //No matching connection found in UDP callback table?
173  if(i >= UDP_CALLBACK_TABLE_SIZE)
175  }
176 
177  //udpEndpointProcess object?
178  if(!strcmp(object->name, "udpEndpointProcess"))
179  {
180  //ID of the process associated with this endpoint
181  value->unsigned32 = 0;
182  }
183  //Unknown object?
184  else
185  {
186  //The specified object does not exist
187  error = ERROR_OBJECT_NOT_FOUND;
188  }
189 
190  //Return status code
191  return error;
192 }
193 
194 
195 /**
196  * @brief Get next udpEndpointEntry object
197  * @param[in] object Pointer to the MIB object descriptor
198  * @param[in] oid Object identifier
199  * @param[in] oidLen Length of the OID, in bytes
200  * @param[out] nextOid OID of the next object in the MIB
201  * @param[out] nextOidLen Length of the next object identifier, in bytes
202  * @return Error code
203  **/
204 
205 error_t udpMibGetNextUdpEndpointEntry(const MibObject *object, const uint8_t *oid,
206  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
207 {
208  error_t error;
209  uint_t i;
210  size_t n;
211  bool_t acceptable;
212  IpAddr localIpAddr;
213  uint16_t localPort;
214  IpAddr remoteIpAddr;
215  uint16_t remotePort;
216  uint32_t instance;
217 
218  //Initialize variables
219  localIpAddr = IP_ADDR_ANY;
220  localPort = 0;
221  remoteIpAddr = IP_ADDR_ANY;
222  remotePort = 0;
223  instance = 1;
224 
225  //Make sure the buffer is large enough to hold the OID prefix
226  if(*nextOidLen < object->oidLen)
227  return ERROR_BUFFER_OVERFLOW;
228 
229  //Copy OID prefix
230  memcpy(nextOid, object->oid, object->oidLen);
231 
232  //Loop through socket descriptors
233  for(i = 0; i < SOCKET_MAX_COUNT; i++)
234  {
235  //Point to current socket
236  Socket *socket = &socketTable[i];
237 
238  //UDP socket?
239  if(socket->type == SOCKET_TYPE_DGRAM)
240  {
241  //Append the instance identifier to the OID prefix
242  n = object->oidLen;
243 
244  //udpEndpointLocalAddressType and udpEndpointLocalAddress are used
245  //as 1st and 2nd instance identifiers
246  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &socket->localIpAddr);
247  //Any error to report?
248  if(error)
249  return error;
250 
251  //udpEndpointLocalPort is used as 3rd instance identifier
252  error = mibEncodePort(nextOid, *nextOidLen, &n, socket->localPort);
253  //Any error to report?
254  if(error)
255  return error;
256 
257  //udpEndpointRemoteAddressType and udpEndpointRemoteAddress are used
258  //as 4th and 5th instance identifiers
259  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &socket->remoteIpAddr);
260  //Any error to report?
261  if(error)
262  return error;
263 
264  //udpEndpointRemotePort is used as 6th instance identifier
265  error = mibEncodePort(nextOid, *nextOidLen, &n, socket->remotePort);
266  //Any error to report?
267  if(error)
268  return error;
269 
270  //udpEndpointInstance is used as 7th instance identifier
271  error = mibEncodeUnsigned32(nextOid, *nextOidLen, &n, instance);
272  //Any error to report?
273  if(error)
274  return error;
275 
276  //Check whether the resulting object identifier lexicographically
277  //follows the specified OID
278  if(oidComp(nextOid, n, oid, oidLen) > 0)
279  {
280  //Perform lexicographic comparison
281  if(localPort == 0 && remotePort == 0)
282  acceptable = TRUE;
283  else if(mibCompIpAddr(&socket->localIpAddr, &localIpAddr) < 0)
284  acceptable = TRUE;
285  else if(mibCompIpAddr(&socket->localIpAddr, &localIpAddr) > 0)
286  acceptable = FALSE;
287  else if(socket->localPort < localPort)
288  acceptable = TRUE;
289  else if(socket->localPort > localPort)
290  acceptable = FALSE;
291  else if(mibCompIpAddr(&socket->remoteIpAddr, &remoteIpAddr) < 0)
292  acceptable = TRUE;
293  else if(mibCompIpAddr(&socket->remoteIpAddr, &remoteIpAddr) > 0)
294  acceptable = FALSE;
295  else if(socket->remotePort < remotePort)
296  acceptable = TRUE;
297  else
298  acceptable = FALSE;
299 
300  //Save the closest object identifier that follows the specified
301  //OID in lexicographic order
302  if(acceptable)
303  {
304  localIpAddr = socket->localIpAddr;
305  localPort = socket->localPort;
306  remoteIpAddr = socket->remoteIpAddr;
307  remotePort = socket->remotePort;
308  }
309  }
310  }
311  }
312 
313  //Loop through the UDP callback table
314  for(i = 0; i < UDP_CALLBACK_TABLE_SIZE; i++)
315  {
316  //Point to the current entry
317  UdpRxCallbackDesc *entry = &udpCallbackTable[i];
318 
319  //Check whether the entry is currently in used
320  if(entry->callback != NULL)
321  {
322  //Append the instance identifier to the OID prefix
323  n = object->oidLen;
324 
325  //udpEndpointLocalAddressType and udpEndpointLocalAddress are used
326  //as 1st and 2nd instance identifiers
327  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &IP_ADDR_ANY);
328  //Any error to report?
329  if(error)
330  return error;
331 
332  //udpEndpointLocalPort is used as 3rd instance identifier
333  error = mibEncodePort(nextOid, *nextOidLen, &n, entry->port);
334  //Any error to report?
335  if(error)
336  return error;
337 
338  //udpEndpointRemoteAddressType and udpEndpointRemoteAddress are used
339  //as 4th and 5th instance identifiers
340  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &IP_ADDR_ANY);
341  //Any error to report?
342  if(error)
343  return error;
344 
345  //udpEndpointRemotePort is used as 6th instance identifier
346  error = mibEncodePort(nextOid, *nextOidLen, &n, 0);
347  //Any error to report?
348  if(error)
349  return error;
350 
351  //udpEndpointInstance is used as 7th instance identifier
352  error = mibEncodeUnsigned32(nextOid, *nextOidLen, &n, instance);
353  //Any error to report?
354  if(error)
355  return error;
356 
357  //Check whether the resulting object identifier lexicographically
358  //follows the specified OID
359  if(oidComp(nextOid, n, oid, oidLen) > 0)
360  {
361  //Perform lexicographic comparison
362  if(localPort == 0 && remotePort == 0)
363  acceptable = TRUE;
364  else if(mibCompIpAddr(&IP_ADDR_ANY, &localIpAddr) < 0)
365  acceptable = TRUE;
366  else if(mibCompIpAddr(&IP_ADDR_ANY, &localIpAddr) > 0)
367  acceptable = FALSE;
368  else if(entry->port < localPort)
369  acceptable = TRUE;
370  else if(entry->port > localPort)
371  acceptable = FALSE;
372  else if(mibCompIpAddr(&IP_ADDR_ANY, &remoteIpAddr) < 0)
373  acceptable = TRUE;
374  else if(mibCompIpAddr(&IP_ADDR_ANY, &remoteIpAddr) > 0)
375  acceptable = FALSE;
376  else if(0 < remotePort)
377  acceptable = TRUE;
378  else
379  acceptable = FALSE;
380 
381  //Save the closest object identifier that follows the specified
382  //OID in lexicographic order
383  if(acceptable)
384  {
385  localIpAddr = IP_ADDR_ANY;
386  localPort = entry->port;
387  remoteIpAddr = IP_ADDR_ANY;
388  remotePort = 0;
389  }
390  }
391  }
392  }
393 
394  //The specified OID does not lexicographically precede the name
395  //of some object?
396  if(localPort == 0 && remotePort == 0)
397  return ERROR_OBJECT_NOT_FOUND;
398 
399  //Append the instance identifier to the OID prefix
400  n = object->oidLen;
401 
402  //udpEndpointLocalAddressType and udpEndpointLocalAddress are used
403  //as 1st and 2nd instance identifiers
404  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &localIpAddr);
405  //Any error to report?
406  if(error)
407  return error;
408 
409  //udpEndpointLocalPort is used as 3rd instance identifier
410  error = mibEncodePort(nextOid, *nextOidLen, &n, localPort);
411  //Any error to report?
412  if(error)
413  return error;
414 
415  //udpEndpointRemoteAddressType and udpEndpointRemoteAddress are used
416  //as 4th and 5th instance identifiers
417  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &remoteIpAddr);
418  //Any error to report?
419  if(error)
420  return error;
421 
422  //udpEndpointRemotePort is used as 6th instance identifier
423  error = mibEncodePort(nextOid, *nextOidLen, &n, remotePort);
424  //Any error to report?
425  if(error)
426  return error;
427 
428  //udpEndpointInstance is used as 7th instance identifier
429  error = mibEncodeUnsigned32(nextOid, *nextOidLen, &n, instance);
430  //Any error to report?
431  if(error)
432  return error;
433 
434  //Save the length of the resulting object identifier
435  *nextOidLen = n;
436  //Next object found
437  return NO_ERROR;
438 }
439 
440 #endif
error_t mibEncodeIpAddr(uint8_t *oid, size_t maxOidLen, size_t *pos, const IpAddr *ipAddr)
Encode instance identifier (IP address)
Definition: mib_common.c:757
int bool_t
Definition: compiler_port.h:49
IP network address.
Definition: ip.h:71
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:140
OID (Object Identifier)
#define TRUE
Definition: os_port.h:50
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
Entry describing a user callback.
Definition: udp.h:104
@ SOCKET_TYPE_DGRAM
Definition: socket.h:78
__start_packed struct @205 MibVariant
Variant data type.
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 udpMibGetNextUdpEndpointEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next udpEndpointEntry object.
Definition: udp_mib_impl.c:205
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:101
UdpMibBase udpMibBase
UDP MIB base.
const IpAddr IP_ADDR_ANY
Definition: ip.c:45
int_t mibCompIpAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
Compare IP addresses.
Definition: mib_common.c:903
#define FALSE
Definition: os_port.h:46
UDP MIB module.
UdpRxCallbackDesc udpCallbackTable[UDP_CALLBACK_TABLE_SIZE]
Definition: udp.c:56
error_t
Error codes.
Definition: error.h:42
bool_t ipCompAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
Compare IP addresses.
Definition: ip.c:158
@ ERROR_INSTANCE_NOT_FOUND
Definition: error.h:251
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:108
General definitions for cryptographic algorithms.
uint8_t oid[1]
Definition: mib_common.h:186
UdpRxCallback callback
Definition: udp.h:108
#define TRACE_INFO(...)
Definition: debug.h:94
error_t udpMibInit(void)
UDP MIB module initialization.
Definition: udp_mib_impl.c:53
#define UDP_CALLBACK_TABLE_SIZE
Definition: udp.h:48
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:49
uint16_t port
Definition: udp.h:107
Common definitions for MIB modules.
uint8_t n
@ ERROR_OBJECT_NOT_FOUND
Definition: error.h:250
#define Socket
Definition: socket.h:36
#define MibObject
Definition: mib_common.h:46
error_t mibDecodeIpAddr(const uint8_t *oid, size_t oidLen, size_t *pos, IpAddr *ipAddr)
Decode instance identifier (IP address)
Definition: mib_common.c:835
error_t mibDecodeUnsigned32(const uint8_t *oid, size_t oidLen, size_t *pos, uint32_t *value)
Decode instance identifier (unsigned 32-bit integer)
Definition: mib_common.c:111
UDP MIB module implementation.
error_t mibEncodeUnsigned32(uint8_t *oid, size_t maxOidLen, size_t *pos, uint32_t value)
Encode instance identifier (unsigned 32-bit integer)
Definition: mib_common.c:94
uint8_t value[]
Definition: dtls_misc.h:150
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
#define SOCKET_MAX_COUNT
Definition: socket.h:45
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
ASN.1 (Abstract Syntax Notation One)
error_t udpMibGetUdpEndpointEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get udpEndpointEntry object value.
Definition: udp_mib_impl.c:76