tcp_mib_impl.c
Go to the documentation of this file.
1 /**
2  * @file tcp_mib_impl.c
3  * @brief TCP 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/tcp_mib_module.h"
36 #include "mibs/tcp_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 (TCP_MIB_SUPPORT == ENABLED && TCP_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief TCP MIB module initialization
48  * @return Error code
49  **/
50 
52 {
53  //Debug message
54  TRACE_INFO("Initializing TCP-MIB base...\r\n");
55 
56  //Clear TCP MIB base
57  memset(&tcpMibBase, 0, sizeof(tcpMibBase));
58 
59  //tcpRtoAlgorithm object
61  //tcpRtoMin object
63  //tcpRtoMax object
65  //tcpMaxConn object
67 
68  //Successful processing
69  return NO_ERROR;
70 }
71 
72 
73 /**
74  * @brief Get tcpCurrEstab object value
75  * @param[in] object Pointer to the MIB object descriptor
76  * @param[in] oid Object identifier (object name and instance identifier)
77  * @param[in] oidLen Length of the OID, in bytes
78  * @param[out] value Object value
79  * @param[in,out] valueLen Length of the object value, in bytes
80  * @return Error code
81  **/
82 
83 error_t tcpMibGetTcpCurrEstab(const MibObject *object, const uint8_t *oid,
84  size_t oidLen, MibVariant *value, size_t *valueLen)
85 {
86  uint_t i;
87  Socket *socket;
88 
89  //Initialize object value
90  value->gauge32 = 0;
91 
92  //Loop through socket descriptors
93  for(i = 0; i < SOCKET_MAX_COUNT; i++)
94  {
95  //Point to current socket
96  socket = &socketTable[i];
97 
98  //TCP socket?
99  if(socket->type == SOCKET_TYPE_STREAM)
100  {
101  //Check current state
102  if(socket->state == TCP_STATE_ESTABLISHED ||
103  socket->state == TCP_STATE_CLOSE_WAIT)
104  {
105  //Number of TCP connections for which the current state
106  //is either ESTABLISHED or CLOSE-WAIT
107  value->gauge32++;
108  }
109  }
110  }
111 
112  //Return status code
113  return NO_ERROR;
114 }
115 
116 
117 /**
118  * @brief Set tcpConnectionEntry object value
119  * @param[in] object Pointer to the MIB object descriptor
120  * @param[in] oid Object identifier (object name and instance identifier)
121  * @param[in] oidLen Length of the OID, in bytes
122  * @param[in] value Object value
123  * @param[in] valueLen Length of the object value, in bytes
124  * @param[in] commit This flag tells whether the changes shall be committed
125  * to the MIB base
126  * @return Error code
127  **/
128 
129 error_t tcpMibSetTcpConnectionEntry(const MibObject *object, const uint8_t *oid,
130  size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
131 {
132  //Not implemented
133  return ERROR_WRITE_FAILED;
134 }
135 
136 
137 /**
138  * @brief Get tcpConnectionEntry object value
139  * @param[in] object Pointer to the MIB object descriptor
140  * @param[in] oid Object identifier (object name and instance identifier)
141  * @param[in] oidLen Length of the OID, in bytes
142  * @param[out] value Object value
143  * @param[in,out] valueLen Length of the object value, in bytes
144  * @return Error code
145  **/
146 
147 error_t tcpMibGetTcpConnectionEntry(const MibObject *object, const uint8_t *oid,
148  size_t oidLen, MibVariant *value, size_t *valueLen)
149 {
150  error_t error;
151  uint_t i;
152  size_t n;
153  IpAddr localIpAddr;
154  uint16_t localPort;
155  IpAddr remoteIpAddr;
156  uint16_t remotePort;
157  Socket *socket;
158 
159  //Point to the instance identifier
160  n = object->oidLen;
161 
162  //tcpConnectionLocalAddressType and tcpConnectionLocalAddress are used
163  //as 1st and 2nd instance identifiers
164  error = mibDecodeIpAddr(oid, oidLen, &n, &localIpAddr);
165  //Invalid instance identifier?
166  if(error)
167  return error;
168 
169  //tcpConnectionLocalPort is used as 3rd instance identifier
170  error = mibDecodePort(oid, oidLen, &n, &localPort);
171  //Invalid instance identifier?
172  if(error)
173  return error;
174 
175  //tcpConnectionRemAddressType and tcpConnectionRemAddress are used
176  //as 4th and 5th instance identifiers
177  error = mibDecodeIpAddr(oid, oidLen, &n, &remoteIpAddr);
178  //Invalid instance identifier?
179  if(error)
180  return error;
181 
182  //tcpConnectionRemPort is used as 6th instance identifier
183  error = mibDecodePort(oid, oidLen, &n, &remotePort);
184  //Invalid instance identifier?
185  if(error)
186  return error;
187 
188  //Sanity check
189  if(n != oidLen)
191 
192  //Loop through socket descriptors
193  for(i = 0; i < SOCKET_MAX_COUNT; i++)
194  {
195  //Point to current socket
196  socket = &socketTable[i];
197 
198  //TCP socket?
199  if(socket->type == SOCKET_TYPE_STREAM)
200  {
201  //Check local IP address
202  if(!ipCompAddr(&socket->localIpAddr, &localIpAddr))
203  continue;
204  //Check local port number
205  if(socket->localPort != localPort)
206  continue;
207  //Check remote IP address
208  if(!ipCompAddr(&socket->remoteIpAddr, &remoteIpAddr))
209  continue;
210  //Check local port number
211  if(socket->remotePort != remotePort)
212  continue;
213  //Check current state
214  if(socket->state == TCP_STATE_LISTEN)
215  continue;
216 
217  //A matching socket has been found
218  break;
219  }
220  }
221 
222  //No matching connection found in socket table?
223  if(i >= SOCKET_MAX_COUNT)
225 
226  //tcpConnectionState object?
227  if(!strcmp(object->name, "tcpConnectionState"))
228  {
229  //Get object value
230  switch(socket->state)
231  {
232  case TCP_STATE_CLOSED:
233  value->integer = TCP_MIB_CONN_STATE_CLOSED;
234  break;
235  case TCP_STATE_LISTEN:
236  value->integer = TCP_MIB_CONN_STATE_LISTEN;
237  break;
238  case TCP_STATE_SYN_SENT:
240  break;
243  break;
246  break;
249  break;
252  break;
255  break;
256  case TCP_STATE_LAST_ACK:
258  break;
259  case TCP_STATE_CLOSING:
261  break;
262  case TCP_STATE_TIME_WAIT:
264  break;
265  default:
266  value->integer = 0;
267  break;
268  }
269  }
270  //tcpConnectionProcess object?
271  else if(!strcmp(object->name, "tcpConnectionProcess"))
272  {
273  //ID of the process associated with this connection
274  value->unsigned32 = 0;
275  }
276  //Unknown object?
277  else
278  {
279  //The specified object does not exist
280  error = ERROR_OBJECT_NOT_FOUND;
281  }
282 
283  //Return status code
284  return error;
285 }
286 
287 
288 /**
289  * @brief Get next tcpConnectionEntry object
290  * @param[in] object Pointer to the MIB object descriptor
291  * @param[in] oid Object identifier
292  * @param[in] oidLen Length of the OID, in bytes
293  * @param[out] nextOid OID of the next object in the MIB
294  * @param[out] nextOidLen Length of the next object identifier, in bytes
295  * @return Error code
296  **/
297 
298 error_t tcpMibGetNextTcpConnectionEntry(const MibObject *object, const uint8_t *oid,
299  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
300 {
301  error_t error;
302  uint_t i;
303  size_t n;
304  bool_t acceptable;
305  IpAddr localIpAddr;
306  uint16_t localPort;
307  IpAddr remoteIpAddr;
308  uint16_t remotePort;
309  Socket *socket;
310 
311  //Initialize variables
312  localIpAddr = IP_ADDR_ANY;
313  localPort = 0;
314  remoteIpAddr = IP_ADDR_ANY;
315  remotePort = 0;
316 
317  //Make sure the buffer is large enough to hold the OID prefix
318  if(*nextOidLen < object->oidLen)
319  return ERROR_BUFFER_OVERFLOW;
320 
321  //Copy OID prefix
322  memcpy(nextOid, object->oid, object->oidLen);
323 
324  //Loop through socket descriptors
325  for(i = 0; i < SOCKET_MAX_COUNT; i++)
326  {
327  //Point to current socket
328  socket = &socketTable[i];
329 
330  //TCP socket?
331  if(socket->type == SOCKET_TYPE_STREAM)
332  {
333  //Check current state
334  if(socket->state != TCP_STATE_LISTEN)
335  {
336  //Append the instance identifier to the OID prefix
337  n = object->oidLen;
338 
339  //tcpConnectionLocalAddressType and tcpConnectionLocalAddress are used
340  //as 1st and 2nd instance identifiers
341  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &socket->localIpAddr);
342  //Any error to report?
343  if(error)
344  return error;
345 
346  //tcpConnectionLocalPort is used as 3rd instance identifier
347  error = mibEncodePort(nextOid, *nextOidLen, &n, socket->localPort);
348  //Any error to report?
349  if(error)
350  return error;
351 
352  //tcpConnectionRemAddressType and tcpConnectionRemAddress are used
353  //as 4th and 5th instance identifiers
354  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &socket->remoteIpAddr);
355  //Any error to report?
356  if(error)
357  return error;
358 
359  //tcpConnectionRemPort is used as 6th instance identifier
360  error = mibEncodePort(nextOid, *nextOidLen, &n, socket->remotePort);
361  //Any error to report?
362  if(error)
363  return error;
364 
365  //Check whether the resulting object identifier lexicographically
366  //follows the specified OID
367  if(oidComp(nextOid, n, oid, oidLen) > 0)
368  {
369  //Perform lexicographic comparison
370  if(localPort == 0 && remotePort == 0)
371  acceptable = TRUE;
372  else if(mibCompIpAddr(&socket->localIpAddr, &localIpAddr) < 0)
373  acceptable = TRUE;
374  else if(mibCompIpAddr(&socket->localIpAddr, &localIpAddr) > 0)
375  acceptable = FALSE;
376  else if(socket->localPort < localPort)
377  acceptable = TRUE;
378  else if(socket->localPort > localPort)
379  acceptable = FALSE;
380  else if(mibCompIpAddr(&socket->remoteIpAddr, &remoteIpAddr) < 0)
381  acceptable = TRUE;
382  else if(mibCompIpAddr(&socket->remoteIpAddr, &remoteIpAddr) > 0)
383  acceptable = FALSE;
384  else if(socket->remotePort < remotePort)
385  acceptable = TRUE;
386  else
387  acceptable = FALSE;
388 
389  //Save the closest object identifier that follows the specified
390  //OID in lexicographic order
391  if(acceptable)
392  {
393  localIpAddr = socket->localIpAddr;
394  localPort = socket->localPort;
395  remoteIpAddr = socket->remoteIpAddr;
396  remotePort = socket->remotePort;
397  }
398  }
399  }
400  }
401  }
402 
403  //The specified OID does not lexicographically precede the name
404  //of some object?
405  if(localPort == 0 && remotePort == 0)
406  return ERROR_OBJECT_NOT_FOUND;
407 
408  //Append the instance identifier to the OID prefix
409  n = object->oidLen;
410 
411  //tcpConnectionLocalAddressType and tcpConnectionLocalAddress are used
412  //as 1st and 2nd instance identifiers
413  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &localIpAddr);
414  //Any error to report?
415  if(error)
416  return error;
417 
418  //tcpConnectionLocalPort is used as 3rd instance identifier
419  error = mibEncodePort(nextOid, *nextOidLen, &n, localPort);
420  //Any error to report?
421  if(error)
422  return error;
423 
424  //tcpConnectionRemAddressType and tcpConnectionRemAddress are used
425  //as 4th and 5th instance identifiers
426  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &remoteIpAddr);
427  //Any error to report?
428  if(error)
429  return error;
430 
431  //tcpConnectionRemPort is used as 6th instance identifier
432  error = mibEncodePort(nextOid, *nextOidLen, &n, remotePort);
433  //Any error to report?
434  if(error)
435  return error;
436 
437  //Save the length of the resulting object identifier
438  *nextOidLen = n;
439  //Next object found
440  return NO_ERROR;
441 }
442 
443 
444 /**
445  * @brief Get tcpListenerEntry object value
446  * @param[in] object Pointer to the MIB object descriptor
447  * @param[in] oid Object identifier (object name and instance identifier)
448  * @param[in] oidLen Length of the OID, in bytes
449  * @param[out] value Object value
450  * @param[in,out] valueLen Length of the object value, in bytes
451  * @return Error code
452  **/
453 
454 error_t tcpMibGetTcpListenerEntry(const MibObject *object, const uint8_t *oid,
455  size_t oidLen, MibVariant *value, size_t *valueLen)
456 {
457  error_t error;
458  uint_t i;
459  size_t n;
460  IpAddr localIpAddr;
461  uint16_t localPort;
462  Socket *socket;
463 
464  //Point to the instance identifier
465  n = object->oidLen;
466 
467  //tcpListenerLocalAddressType and tcpListenerLocalAddress are used
468  //as 1st and 2nd instance identifiers
469  error = mibDecodeIpAddr(oid, oidLen, &n, &localIpAddr);
470  //Invalid instance identifier?
471  if(error)
472  return error;
473 
474  //tcpListenerLocalPort is used as 3rd instance identifier
475  error = mibDecodePort(oid, oidLen, &n, &localPort);
476  //Invalid instance identifier?
477  if(error)
478  return error;
479 
480  //Sanity check
481  if(n != oidLen)
483 
484  //Loop through socket descriptors
485  for(i = 0; i < SOCKET_MAX_COUNT; i++)
486  {
487  //Point to current socket
488  socket = &socketTable[i];
489 
490  //TCP socket?
491  if(socket->type == SOCKET_TYPE_STREAM)
492  {
493  //Check local IP address
494  if(!ipCompAddr(&socket->localIpAddr, &localIpAddr))
495  continue;
496  //Check local port number
497  if(socket->localPort != localPort)
498  continue;
499  //Check current state
500  if(socket->state != TCP_STATE_LISTEN)
501  continue;
502 
503  //A matching socket has been found
504  break;
505  }
506  }
507 
508  //No matching connection found in socket table?
509  if(i >= SOCKET_MAX_COUNT)
511 
512  //tcpListenerProcess object?
513  if(!strcmp(object->name, "tcpListenerProcess"))
514  {
515  //ID of the process associated with this listener
516  value->unsigned32 = 0;
517  }
518  //Unknown object?
519  else
520  {
521  //The specified object does not exist
522  error = ERROR_OBJECT_NOT_FOUND;
523  }
524 
525  //Return status code
526  return error;
527 }
528 
529 
530 /**
531  * @brief Get next tcpListenerEntry object
532  * @param[in] object Pointer to the MIB object descriptor
533  * @param[in] oid Object identifier
534  * @param[in] oidLen Length of the OID, in bytes
535  * @param[out] nextOid OID of the next object in the MIB
536  * @param[out] nextOidLen Length of the next object identifier, in bytes
537  * @return Error code
538  **/
539 
540 error_t tcpMibGetNextTcpListenerEntry(const MibObject *object, const uint8_t *oid,
541  size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
542 {
543  error_t error;
544  uint_t i;
545  size_t n;
546  bool_t acceptable;
547  IpAddr localIpAddr;
548  uint16_t localPort;
549  Socket *socket;
550 
551  //Initialize variables
552  localIpAddr = IP_ADDR_ANY;
553  localPort = 0;
554 
555  //Make sure the buffer is large enough to hold the OID prefix
556  if(*nextOidLen < object->oidLen)
557  return ERROR_BUFFER_OVERFLOW;
558 
559  //Copy OID prefix
560  memcpy(nextOid, object->oid, object->oidLen);
561 
562  //Loop through socket descriptors
563  for(i = 0; i < SOCKET_MAX_COUNT; i++)
564  {
565  //Point to current socket
566  socket = &socketTable[i];
567 
568  //TCP socket?
569  if(socket->type == SOCKET_TYPE_STREAM)
570  {
571  //Check current state
572  if(socket->state == TCP_STATE_LISTEN)
573  {
574  //Append the instance identifier to the OID prefix
575  n = object->oidLen;
576 
577  //tcpListenerLocalAddressType and tcpListenerLocalAddress are used
578  //as 1st and 2nd instance identifiers
579  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &socket->localIpAddr);
580  //Any error to report?
581  if(error)
582  return error;
583 
584  //tcpListenerLocalPort is used as 3rd instance identifier
585  error = mibEncodePort(nextOid, *nextOidLen, &n, socket->localPort);
586  //Any error to report?
587  if(error)
588  return error;
589 
590  //Check whether the resulting object identifier lexicographically
591  //follows the specified OID
592  if(oidComp(nextOid, n, oid, oidLen) > 0)
593  {
594  //Perform lexicographic comparison
595  if(localPort == 0)
596  acceptable = TRUE;
597  else if(mibCompIpAddr(&socket->localIpAddr, &localIpAddr) < 0)
598  acceptable = TRUE;
599  else if(mibCompIpAddr(&socket->localIpAddr, &localIpAddr) > 0)
600  acceptable = FALSE;
601  else if(socket->localPort < localPort)
602  acceptable = TRUE;
603  else
604  acceptable = FALSE;
605 
606  //Save the closest object identifier that follows the specified
607  //OID in lexicographic order
608  if(acceptable)
609  {
610  localIpAddr = socket->localIpAddr;
611  localPort = socket->localPort;
612  }
613  }
614  }
615  }
616  }
617 
618  //The specified OID does not lexicographically precede the name
619  //of some object?
620  if(localPort == 0)
621  return ERROR_OBJECT_NOT_FOUND;
622 
623  //Append the instance identifier to the OID prefix
624  n = object->oidLen;
625 
626  //tcpListenerLocalAddressType and tcpListenerLocalAddress are used
627  //as 1st and 2nd instance identifiers
628  error = mibEncodeIpAddr(nextOid, *nextOidLen, &n, &localIpAddr);
629  //Any error to report?
630  if(error)
631  return error;
632 
633  //tcpListenerLocalPort is used as 3rd instance identifier
634  error = mibEncodePort(nextOid, *nextOidLen, &n, localPort);
635  //Any error to report?
636  if(error)
637  return error;
638 
639  //Save the length of the resulting object identifier
640  *nextOidLen = n;
641  //Next object found
642  return NO_ERROR;
643 }
644 
645 #endif
bool_t ipCompAddr(const IpAddr *ipAddr1, const IpAddr *ipAddr2)
Compare IP addresses.
Definition: ip.c:155
TCP MIB module implementation.
TCP/IP stack core.
Debugging facilities.
error_t tcpMibGetNextTcpConnectionEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next tcpConnectionEntry object.
Definition: tcp_mib_impl.c:298
int32_t tcpRtoMin
#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
error_t tcpMibInit(void)
TCP MIB module initialization.
Definition: tcp_mib_impl.c:51
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
error_t tcpMibGetNextTcpListenerEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, uint8_t *nextOid, size_t *nextOidLen)
Get next tcpListenerEntry object.
Definition: tcp_mib_impl.c:540
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 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
error_t tcpMibGetTcpCurrEstab(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get tcpCurrEstab object value.
Definition: tcp_mib_impl.c:83
ASN.1 (Abstract Syntax Notation One)
int32_t tcpRtoMax
TcpMibBase tcpMibBase
TCP MIB base.
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
int32_t tcpRtoAlgorithm
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 tcpMibSetTcpConnectionEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, const MibVariant *value, size_t valueLen, bool_t commit)
Set tcpConnectionEntry object value.
Definition: tcp_mib_impl.c:129
#define TRACE_INFO(...)
Definition: debug.h:86
error_t tcpMibGetTcpConnectionEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get tcpConnectionEntry object value.
Definition: tcp_mib_impl.c:147
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
#define TCP_MAX_RTO
Definition: tcp.h:129
error_t
Error codes.
Definition: error.h:40
__start_packed struct @208 MibVariant
Variant data type.
unsigned int uint_t
Definition: compiler_port.h:43
int32_t tcpMaxConn
uint8_t value[]
Definition: dtls_misc.h:141
Common definitions for MIB modules.
error_t tcpMibGetTcpListenerEntry(const MibObject *object, const uint8_t *oid, size_t oidLen, MibVariant *value, size_t *valueLen)
Get tcpListenerEntry object value.
Definition: tcp_mib_impl.c:454
#define TCP_MIN_RTO
Definition: tcp.h:122
uint8_t n
uint8_t oid[1]
Definition: mib_common.h:184
TCP MIB module.
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47