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