socket.c
Go to the documentation of this file.
1 /**
2  * @file socket.c
3  * @brief Socket API
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2020 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.8
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL SOCKET_TRACE_LEVEL
33 
34 //Dependencies
35 #include <string.h>
36 #include "core/net.h"
37 #include "core/socket.h"
38 #include "core/raw_socket.h"
39 #include "core/udp.h"
40 #include "core/tcp.h"
41 #include "core/tcp_misc.h"
42 #include "dns/dns_client.h"
43 #include "mdns/mdns_client.h"
44 #include "netbios/nbns_client.h"
45 #include "llmnr/llmnr_client.h"
46 #include "debug.h"
47 
48 //Socket table
50 
51 //Default socket message
53 {
54  NULL, //Pointer to the payload
55  0, //Size of the payload, in bytes
56  0, //Actual length of the payload, in bytes
57  0, //Time-to-live value
58  {0}, //Source IP address
59  0, //Source port
60  {0}, //Destination IP address
61  0, //Destination port
62 #if (ETH_SUPPORT == ENABLED)
63  {0}, //Source MAC address
64  {0}, //Destination MAC address
65 #endif
66 #if (ETH_PORT_TAGGING_SUPPORT == ENABLED)
67  0, //Switch port identifier
68 #endif
69 #if (ETH_TIMESTAMP_SUPPORT == ENABLED)
70  -1, //Unique identifier for hardware time stamping
71  {0}, //Captured time stamp
72 #endif
73 };
74 
75 
76 /**
77  * @brief Socket related initialization
78  * @return Error code
79  **/
80 
82 {
83  uint_t i;
84  uint_t j;
85 
86  //Initialize socket descriptors
87  osMemset(socketTable, 0, sizeof(socketTable));
88 
89  //Loop through socket descriptors
90  for(i = 0; i < SOCKET_MAX_COUNT; i++)
91  {
92  //Set socket identifier
93  socketTable[i].descriptor = i;
94 
95  //Create an event object to track socket events
96  if(!osCreateEvent(&socketTable[i].event))
97  {
98  //Clean up side effects
99  for(j = 0; j < i; j++)
100  osDeleteEvent(&socketTable[j].event);
101 
102  //Report an error
103  return ERROR_OUT_OF_RESOURCES;
104  }
105  }
106 
107  //Successful initialization
108  return NO_ERROR;
109 }
110 
111 
112 /**
113  * @brief Create a socket (UDP or TCP)
114  * @param[in] type Type specification for the new socket
115  * @param[in] protocol Protocol to be used
116  * @return Handle referencing the new socket
117  **/
118 
120 {
121  error_t error;
122  uint_t i;
123  uint16_t port;
124  Socket *socket;
125  OsEvent event;
126 
127  //Initialize socket handle
128  socket = NULL;
129 
130  //Get exclusive access
132 
133 #if (TCP_SUPPORT == ENABLED)
134  //Connection-oriented socket?
135  if(type == SOCKET_TYPE_STREAM)
136  {
137  //Always use TCP as underlying transport protocol
139  //Get an ephemeral port number
141  //Continue processing
142  error = NO_ERROR;
143  }
144  else
145 #endif
146 #if (UDP_SUPPORT == ENABLED)
147  //Connectionless socket?
148  if(type == SOCKET_TYPE_DGRAM)
149  {
150  //Always use UDP as underlying transport protocol
152  //Get an ephemeral port number
154  //Continue processing
155  error = NO_ERROR;
156  }
157  else
158 #endif
159 #if (RAW_SOCKET_SUPPORT == ENABLED)
160  //Raw socket?
162  {
163  //Port numbers are not relevant for raw sockets
164  port = 0;
165  //Continue processing
166  error = NO_ERROR;
167  }
168  else
169 #endif
170  {
171  //The socket type is not supported
172  error = ERROR_INVALID_PARAMETER;
173  }
174 
175  //Check status code
176  if(!error)
177  {
178  //Loop through socket descriptors
179  for(i = 0; i < SOCKET_MAX_COUNT; i++)
180  {
181  //Unused socket found?
183  {
184  //Save socket handle
185  socket = &socketTable[i];
186  //We are done
187  break;
188  }
189  }
190 
191 #if (TCP_SUPPORT == ENABLED)
192  //No more sockets available?
193  if(socket == NULL)
194  {
195  //Kill the oldest connection in the TIME-WAIT state
196  //whenever the socket table runs out of space
198  }
199 #endif
200 
201  //Check whether the current entry is free
202  if(socket != NULL)
203  {
204  //Save socket descriptor
205  i = socket->descriptor;
206  //Save event object instance
207  osMemcpy(&event, &socket->event, sizeof(OsEvent));
208 
209  //Clear associated structure
210  osMemset(socket, 0, sizeof(Socket));
211  //Reuse event objects and avoid recreating them whenever possible
212  osMemcpy(&socket->event, &event, sizeof(OsEvent));
213 
214  //Save socket characteristics
215  socket->descriptor = i;
216  socket->type = type;
217  socket->protocol = protocol;
218  socket->localPort = port;
219  socket->timeout = INFINITE_DELAY;
220 
221 #if (ETH_VLAN_SUPPORT == ENABLED)
222  //Default VLAN PCP and DEI fields
223  socket->vlanPcp = -1;
224  socket->vlanDei = -1;
225 #endif
226 
227 #if (ETH_VMAN_SUPPORT == ENABLED)
228  //Default VMAN PCP and DEI fields
229  socket->vmanPcp = -1;
230  socket->vmanDei = -1;
231 #endif
232 
233 #if (TCP_SUPPORT == ENABLED)
234  //Default TX and RX buffer size
237 #endif
238  }
239  }
240 
241  //Release exclusive access
243 
244  //Return a handle to the freshly created socket
245  return socket;
246 }
247 
248 
249 /**
250  * @brief Set timeout value for blocking operations
251  * @param[in] socket Handle to a socket
252  * @param[in] timeout Maximum time to wait
253  * @return Error code
254  **/
255 
257 {
258  //Make sure the socket handle is valid
259  if(socket == NULL)
261 
262  //Get exclusive access
264  //Record timeout value
265  socket->timeout = timeout;
266  //Release exclusive access
268 
269  //No error to report
270  return NO_ERROR;
271 }
272 
273 
274 /**
275  * @brief Set TTL value for unicast datagrams
276  * @param[in] socket Handle to a socket
277  * @param[in] ttl Time-to-live value
278  * @return Error code
279  **/
280 
282 {
283  //Make sure the socket handle is valid
284  if(socket == NULL)
286 
287  //Get exclusive access
289  //Set TTL value
290  socket->ttl = ttl;
291  //Release exclusive access
293 
294  //No error to report
295  return NO_ERROR;
296 }
297 
298 
299 /**
300  * @brief Set TTL value for multicast datagrams
301  * @param[in] socket Handle to a socket
302  * @param[in] ttl Time-to-live value
303  * @return Error code
304  **/
305 
307 {
308  //Make sure the socket handle is valid
309  if(socket == NULL)
311 
312  //Get exclusive access
314  //Set TTL value
315  socket->multicastTtl = ttl;
316  //Release exclusive access
318 
319  //No error to report
320  return NO_ERROR;
321 }
322 
323 
324 /**
325  * @brief Set DSCP field
326  * @param[in] socket Handle to a socket
327  * @param[in] dscp Differentiated services codepoint
328  * @return Error code
329  **/
330 
332 {
333 #if (IP_DIFF_SERV_SUPPORT == ENABLED)
334  //Make sure the socket handle is valid
335  if(socket == NULL)
337 
338  //The DSCP field is 6 bits wide
339  if(dscp >= 64)
341 
342  //Get exclusive access
344  //Set differentiated services codepoint
345  socket->dscp = dscp;
346  //Release exclusive access
348 
349  //No error to report
350  return NO_ERROR;
351 #else
352  //Not implemented
353  return ERROR_NOT_IMPLEMENTED;
354 #endif
355 }
356 
357 
358 /**
359  * @brief Set VLAN priority
360  * @param[in] socket Handle to a socket
361  * @param[in] pcp VLAN priority value
362  * @return Error code
363  **/
364 
366 {
367 #if (ETH_VLAN_SUPPORT == ENABLED)
368  //Make sure the socket handle is valid
369  if(socket == NULL)
371 
372  //The PCP field is 3 bits wide
373  if(pcp >= 8)
375 
376  //Get exclusive access
378 
379  //The PCP field specifies the frame priority level. Different PCP values
380  //can be used to prioritize different classes of traffic
381  socket->vlanPcp = pcp;
382 
383  //Release exclusive access
385 
386  //No error to report
387  return NO_ERROR;
388 #else
389  //Not implemented
390  return ERROR_NOT_IMPLEMENTED;
391 #endif
392 }
393 
394 
395 /**
396  * @brief Set VLAN DEI flag
397  * @param[in] socket Handle to a socket
398  * @param[in] dei Drop eligible indicator
399  * @return Error code
400  **/
401 
403 {
404 #if (ETH_VLAN_SUPPORT == ENABLED)
405  //Make sure the socket handle is valid
406  if(socket == NULL)
408 
409  //Get exclusive access
411 
412  //The DEI flag may be used to indicate frames eligible to be dropped in
413  //the presence of congestion
414  socket->vlanDei = dei;
415 
416  //Release exclusive access
418 
419  //No error to report
420  return NO_ERROR;
421 #else
422  //Not implemented
423  return ERROR_NOT_IMPLEMENTED;
424 #endif
425 }
426 
427 
428 /**
429  * @brief Set VMAN priority
430  * @param[in] socket Handle to a socket
431  * @param[in] pcp VLAN priority value
432  * @return Error code
433  **/
434 
436 {
437 #if (ETH_VMAN_SUPPORT == ENABLED)
438  //Make sure the socket handle is valid
439  if(socket == NULL)
441 
442  //The PCP field is 3 bits wide
443  if(pcp >= 8)
445 
446  //Get exclusive access
448 
449  //The PCP field specifies the frame priority level. Different PCP values
450  //can be used to prioritize different classes of traffic
451  socket->vmanPcp = pcp;
452 
453  //Release exclusive access
455 
456  //No error to report
457  return NO_ERROR;
458 #else
459  //Not implemented
460  return ERROR_NOT_IMPLEMENTED;
461 #endif
462 }
463 
464 
465 /**
466  * @brief Set VMAN DEI flag
467  * @param[in] socket Handle to a socket
468  * @param[in] dei Drop eligible indicator
469  * @return Error code
470  **/
471 
473 {
474 #if (ETH_VMAN_SUPPORT == ENABLED)
475  //Make sure the socket handle is valid
476  if(socket == NULL)
478 
479  //Get exclusive access
481 
482  //The DEI flag may be used to indicate frames eligible to be dropped in
483  //the presence of congestion
484  socket->vmanDei = dei;
485 
486  //Release exclusive access
488 
489  //No error to report
490  return NO_ERROR;
491 #else
492  //Not implemented
493  return ERROR_NOT_IMPLEMENTED;
494 #endif
495 }
496 
497 
498 /**
499  * @brief Specify the size of the send buffer
500  * @param[in] socket Handle to a socket
501  * @param[in] size Desired buffer size in bytes
502  * @return Error code
503  **/
504 
506 {
507 #if (TCP_SUPPORT == ENABLED)
508  //Make sure the socket handle is valid
509  if(socket == NULL)
511  //Check parameter value
512  if(size < 1 || size > TCP_MAX_TX_BUFFER_SIZE)
514 
515  //This function shall be used with connection-oriented socket types
516  if(socket->type != SOCKET_TYPE_STREAM)
517  return ERROR_INVALID_SOCKET;
518  //The buffer size cannot be changed when the connection is established
520  return ERROR_INVALID_SOCKET;
521 
522  //Use the specified buffer size
523  socket->txBufferSize = size;
524  //No error to report
525  return NO_ERROR;
526 #else
527  return ERROR_NOT_IMPLEMENTED;
528 #endif
529 }
530 
531 
532 /**
533  * @brief Specify the size of the receive buffer
534  * @param[in] socket Handle to a socket
535  * @param[in] size Desired buffer size in bytes
536  * @return Error code
537  **/
538 
540 {
541 #if (TCP_SUPPORT == ENABLED)
542  //Make sure the socket handle is valid
543  if(socket == NULL)
545  //Check parameter value
546  if(size < 1 || size > TCP_MAX_RX_BUFFER_SIZE)
548 
549  //This function shall be used with connection-oriented socket types
550  if(socket->type != SOCKET_TYPE_STREAM)
551  return ERROR_INVALID_SOCKET;
552  //The buffer size cannot be changed when the connection is established
554  return ERROR_INVALID_SOCKET;
555 
556  //Use the specified buffer size
557  socket->rxBufferSize = size;
558  //No error to report
559  return NO_ERROR;
560 #else
561  return ERROR_NOT_IMPLEMENTED;
562 #endif
563 }
564 
565 
566 /**
567  * @brief Bind a socket to a particular network interface
568  * @param[in] socket Handle to a socket
569  * @param[in] interface Network interface to be used
570  * @return Error code
571  **/
572 
574 {
575  //Make sure the socket handle is valid
576  if(socket == NULL)
578 
579  //Explicitly associate the socket with the specified interface
580  socket->interface = interface;
581 
582  //No error to report
583  return NO_ERROR;
584 }
585 
586 
587 /**
588  * @brief Retrieve the underlying interface
589  * @param[in] socket Handle to a socket
590  * @return Pointer to the underlying network interface
591  **/
592 
594 {
595  NetInterface *interface = NULL;
596 
597  //Make sure the socket handle is valid
598  if(socket != NULL)
599  {
600  interface = socket->interface;
601  }
602 
603  //Return a pointer to the underlying network interface
604  return interface;
605 }
606 
607 
608 /**
609  * @brief Associate a local address with a socket
610  * @param[in] socket Handle to a socket
611  * @param[in] localIpAddr Local address to assign to the bound socket
612  * @param[in] localPort Local port number to assign to the bound socket
613  * @return Error code
614  **/
615 
616 error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
617 {
618  //Check input parameters
619  if(!socket || !localIpAddr)
621  //Make sure the socket type is correct
622  if(socket->type != SOCKET_TYPE_STREAM && socket->type != SOCKET_TYPE_DGRAM)
623  return ERROR_INVALID_SOCKET;
624 
625  //Associate the specified IP address and port number
626  socket->localIpAddr = *localIpAddr;
627  socket->localPort = localPort;
628 
629  //No error to report
630  return NO_ERROR;
631 }
632 
633 
634 /**
635  * @brief Establish a connection to a specified socket
636  * @param[in] socket Handle to an unconnected socket
637  * @param[in] remoteIpAddr IP address of the remote host
638  * @param[in] remotePort Remote port number that will be used to establish the connection
639  * @return Error code
640  **/
641 
642 error_t socketConnect(Socket *socket, const IpAddr *remoteIpAddr, uint16_t remotePort)
643 {
644  error_t error;
645 
646  //Check input parameters
647  if(!socket || !remoteIpAddr)
649 
650 #if (TCP_SUPPORT == ENABLED)
651  //Connection-oriented socket?
652  if(socket->type == SOCKET_TYPE_STREAM)
653  {
654  //Get exclusive access
656 
657  //Establish TCP connection
658  error = tcpConnect(socket, remoteIpAddr, remotePort);
659 
660  //Release exclusive access
662  }
663  else
664 #endif
665  //Connectionless socket?
666  if(socket->type == SOCKET_TYPE_DGRAM)
667  {
668  //Save port number and IP address of the remote host
669  socket->remoteIpAddr = *remoteIpAddr;
670  socket->remotePort = remotePort;
671  //No error to report
672  error = NO_ERROR;
673  }
674  //Raw socket?
675  else if(socket->type == SOCKET_TYPE_RAW_IP)
676  {
677  //Save the IP address of the remote host
678  socket->remoteIpAddr = *remoteIpAddr;
679  //No error to report
680  error = NO_ERROR;
681  }
682  //Invalid socket type?
683  else
684  {
685  //Report an error
686  error = ERROR_INVALID_SOCKET;
687  }
688 
689  //Return status code
690  return error;
691 }
692 
693 
694 /**
695  * @brief Place a socket in the listening state
696  *
697  * Place a socket in a state in which it is listening for an incoming connection
698  *
699  * @param[in] socket Socket to place in the listening state
700  * @param[in] backlog backlog The maximum length of the pending connection queue.
701  * If this parameter is zero, then the default backlog value is used instead
702  * @return Error code
703  **/
704 
706 {
707 #if (TCP_SUPPORT == ENABLED)
708  error_t error;
709 
710  //Make sure the socket handle is valid
711  if(socket == NULL)
713  //This function shall be used with connection-oriented socket types
714  if(socket->type != SOCKET_TYPE_STREAM)
715  return ERROR_INVALID_SOCKET;
716 
717  //Get exclusive access
719 
720  //Start listening for an incoming connection
721  error = tcpListen(socket, backlog);
722 
723  //Release exclusive access
725 
726  //Return status code
727  return error;
728 #else
729  return ERROR_NOT_IMPLEMENTED;
730 #endif
731 }
732 
733 
734 /**
735  * @brief Permit an incoming connection attempt on a socket
736  * @param[in] socket Handle to a socket previously placed in a listening state
737  * @param[out] clientIpAddr IP address of the client
738  * @param[out] clientPort Port number used by the client
739  * @return Handle to the socket in which the actual connection is made
740  **/
741 
742 Socket *socketAccept(Socket *socket, IpAddr *clientIpAddr, uint16_t *clientPort)
743 {
744 #if (TCP_SUPPORT == ENABLED)
745  Socket *newSocket;
746 
747  //Make sure the socket handle is valid
748  if(socket == NULL)
749  return NULL;
750  //This function shall be used with connection-oriented socket types
751  if(socket->type != SOCKET_TYPE_STREAM)
752  return NULL;
753 
754  //Accept an incoming connection attempt
755  newSocket = tcpAccept(socket, clientIpAddr, clientPort);
756 
757  //Return a handle to the newly created socket
758  return newSocket;
759 #else
760  return NULL;
761 #endif
762 }
763 
764 
765 /**
766  * @brief Send data to a connected socket
767  * @param[in] socket Handle that identifies a connected socket
768  * @param[in] data Pointer to a buffer containing the data to be transmitted
769  * @param[in] length Number of data bytes to send
770  * @param[out] written Actual number of bytes written (optional parameter)
771  * @param[in] flags Set of flags that influences the behavior of this function
772  * @return Error code
773  **/
774 
775 error_t socketSend(Socket *socket, const void *data, size_t length,
776  size_t *written, uint_t flags)
777 {
778  //Use default remote IP address for connectionless or raw sockets
779  return socketSendTo(socket, &socket->remoteIpAddr, socket->remotePort,
780  data, length, written, flags);
781 }
782 
783 
784 /**
785  * @brief Send a datagram to a specific destination
786  * @param[in] socket Handle that identifies a socket
787  * @param[in] destIpAddr IP address of the target host
788  * @param[in] destPort Target port number
789  * @param[in] data Pointer to a buffer containing the data to be transmitted
790  * @param[in] length Number of data bytes to send
791  * @param[out] written Actual number of bytes written (optional parameter)
792  * @param[in] flags Set of flags that influences the behavior of this function
793  * @return Error code
794  **/
795 
797  const void *data, size_t length, size_t *written, uint_t flags)
798 {
799  error_t error;
800 
801  //No data has been transmitted yet
802  if(written != NULL)
803  *written = 0;
804 
805  //Make sure the socket handle is valid
806  if(socket == NULL)
808 
809  //Get exclusive access
811 
812 #if (TCP_SUPPORT == ENABLED)
813  //Connection-oriented socket?
814  if(socket->type == SOCKET_TYPE_STREAM)
815  {
816  //For connection-oriented sockets, target address is ignored
817  error = tcpSend(socket, data, length, written, flags);
818  }
819  else
820 #endif
821  {
823 
824  //Initialize structure
826 
827  //Copy data payload
828  message.data = (void *) data;
829  message.length = length;
830 
831  //Set destination IP address
832  if(destIpAddr != NULL)
833  message.destIpAddr = *destIpAddr;
834 
835  //Set destination port
836  message.destPort = destPort;
837 
838 #if (UDP_SUPPORT == ENABLED)
839  //Connectionless socket?
840  if(socket->type == SOCKET_TYPE_DGRAM)
841  {
842  //Send UDP datagram
843  error = udpSendDatagram(socket, &message, flags);
844  }
845  else
846 #endif
847 #if (RAW_SOCKET_SUPPORT == ENABLED)
848  //Raw socket?
849  if(socket->type == SOCKET_TYPE_RAW_IP)
850  {
851  //Send a raw IP packet
853  }
854  else if(socket->type == SOCKET_TYPE_RAW_ETH)
855  {
856  //Send a raw Ethernet packet
858  }
859  else
860 #endif
861  //Invalid socket type?
862  {
863  //Report an error
864  error = ERROR_INVALID_SOCKET;
865  }
866 
867  //Check status code
868  if(!error)
869  {
870  //Total number of data bytes successfully transmitted
871  if(written != NULL)
872  *written = message.length;
873  }
874  }
875 
876  //Release exclusive access
878 
879  //Return status code
880  return error;
881 }
882 
883 
884 /**
885  * @brief Send a message to a connectionless socket
886  * @param[in] socket Handle that identifies a socket
887  * @param[in] message Pointer to the structure describing the message
888  * @param[in] flags Set of flags that influences the behavior of this function
889  * @return Error code
890  **/
891 
893 {
894  error_t error;
895 
896  //Make sure the socket handle is valid
897  if(socket == NULL)
899 
900  //Get exclusive access
902 
903 #if (UDP_SUPPORT == ENABLED)
904  //Connectionless socket?
905  if(socket->type == SOCKET_TYPE_DGRAM)
906  {
907  //Send UDP datagram
908  error = udpSendDatagram(socket, message, flags);
909  }
910  else
911 #endif
912 #if (RAW_SOCKET_SUPPORT == ENABLED)
913  //Raw socket?
914  if(socket->type == SOCKET_TYPE_RAW_IP)
915  {
916  //Send a raw IP packet
918  }
919  else if(socket->type == SOCKET_TYPE_RAW_ETH)
920  {
921  //Send a raw Ethernet packet
923  }
924  else
925 #endif
926  //Invalid socket type?
927  {
928  //Report an error
929  error = ERROR_INVALID_SOCKET;
930  }
931 
932  //Release exclusive access
934 
935  //Return status code
936  return error;
937 }
938 
939 
940 /**
941  * @brief Receive data from a connected socket
942  * @param[in] socket Handle that identifies a connected socket
943  * @param[out] data Buffer where to store the incoming data
944  * @param[in] size Maximum number of bytes that can be received
945  * @param[out] received Number of bytes that have been received
946  * @param[in] flags Set of flags that influences the behavior of this function
947  * @return Error code
948  **/
949 
951  size_t size, size_t *received, uint_t flags)
952 {
953  //For connection-oriented sockets, source and destination addresses are
954  //no use
955  return socketReceiveEx(socket, NULL, NULL, NULL, data, size, received,
956  flags);
957 }
958 
959 
960 /**
961  * @brief Receive a datagram from a connectionless socket
962  * @param[in] socket Handle that identifies a socket
963  * @param[out] srcIpAddr Source IP address (optional)
964  * @param[out] srcPort Source port number (optional)
965  * @param[out] data Buffer where to store the incoming data
966  * @param[in] size Maximum number of bytes that can be received
967  * @param[out] received Number of bytes that have been received
968  * @param[in] flags Set of flags that influences the behavior of this function
969  * @return Error code
970  **/
971 
973  void *data, size_t size, size_t *received, uint_t flags)
974 {
975  //Destination address is no use
976  return socketReceiveEx(socket, srcIpAddr, srcPort, NULL, data, size,
977  received, flags);
978 }
979 
980 
981 /**
982  * @brief Receive a datagram
983  * @param[in] socket Handle that identifies a socket
984  * @param[out] srcIpAddr Source IP address (optional)
985  * @param[out] srcPort Source port number (optional)
986  * @param[out] destIpAddr Destination IP address (optional)
987  * @param[out] data Buffer where to store the incoming data
988  * @param[in] size Maximum number of bytes that can be received
989  * @param[out] received Number of bytes that have been received
990  * @param[in] flags Set of flags that influences the behavior of this function
991  * @return Error code
992  **/
993 
995  IpAddr *destIpAddr, void *data, size_t size, size_t *received, uint_t flags)
996 {
997  error_t error;
998 
999  //No data has been received yet
1000  if(received != NULL)
1001  *received = 0;
1002 
1003  //Make sure the socket handle is valid
1004  if(socket == NULL)
1005  return ERROR_INVALID_PARAMETER;
1006 
1007  //Get exclusive access
1009 
1010 #if (TCP_SUPPORT == ENABLED)
1011  //Connection-oriented socket?
1012  if(socket->type == SOCKET_TYPE_STREAM)
1013  {
1014  //Receive data
1015  error = tcpReceive(socket, data, size, received, flags);
1016 
1017  //Save the source IP address
1018  if(srcIpAddr != NULL)
1019  *srcIpAddr = socket->remoteIpAddr;
1020 
1021  //Save the source port number
1022  if(srcPort != NULL)
1023  *srcPort = socket->remotePort;
1024 
1025  //Save the destination IP address
1026  if(destIpAddr != NULL)
1027  *destIpAddr = socket->localIpAddr;
1028  }
1029  else
1030 #endif
1031  {
1033 
1034  //Initialize structure
1036 
1037  //Set data buffer
1038  message.data = (void *) data;
1039  message.size = size;
1040 
1041 #if (UDP_SUPPORT == ENABLED)
1042  //Connectionless socket?
1043  if(socket->type == SOCKET_TYPE_DGRAM)
1044  {
1045  //Receive UDP datagram
1046  error = udpReceiveDatagram(socket, &message, flags);
1047  }
1048  else
1049 #endif
1050 #if (RAW_SOCKET_SUPPORT == ENABLED)
1051  //Raw socket?
1052  if(socket->type == SOCKET_TYPE_RAW_IP)
1053  {
1054  //Receive a raw IP packet
1056  }
1057  else if(socket->type == SOCKET_TYPE_RAW_ETH)
1058  {
1059  //Receive a raw Ethernet packet
1061  }
1062  else
1063 #endif
1064  //Invalid socket type?
1065  {
1066  //Report an error
1067  error = ERROR_INVALID_SOCKET;
1068  }
1069 
1070  //Check status code
1071  if(!error)
1072  {
1073  //Save the source IP address
1074  if(srcIpAddr != NULL)
1075  *srcIpAddr = message.srcIpAddr;
1076 
1077  //Save the source port number
1078  if(srcPort != NULL)
1079  *srcPort = message.srcPort;
1080 
1081  //Save the destination IP address
1082  if(destIpAddr != NULL)
1083  *destIpAddr = message.destIpAddr;
1084 
1085  //Total number of data that have been received
1086  *received = message.length;
1087  }
1088  }
1089 
1090  //Release exclusive access
1092 
1093  //Return status code
1094  return error;
1095 }
1096 
1097 
1098 /**
1099  * @brief Receive a message from a connectionless socket
1100  * @param[in] socket Handle that identifies a socket
1101  * @param[in,out] message Pointer to the structure describing the message
1102  * @param[in] flags Set of flags that influences the behavior of this function
1103  * @return Error code
1104  **/
1105 
1107 {
1108  error_t error;
1109 
1110  //No data has been received yet
1111  message->length = 0;
1112 
1113  //Make sure the socket handle is valid
1114  if(socket == NULL)
1115  return ERROR_INVALID_PARAMETER;
1116 
1117  //Get exclusive access
1119 
1120 #if (UDP_SUPPORT == ENABLED)
1121  //Connectionless socket?
1122  if(socket->type == SOCKET_TYPE_DGRAM)
1123  {
1124  //Receive UDP datagram
1126  }
1127  else
1128 #endif
1129 #if (RAW_SOCKET_SUPPORT == ENABLED)
1130  //Raw socket?
1131  if(socket->type == SOCKET_TYPE_RAW_IP)
1132  {
1133  //Receive a raw IP packet
1135  }
1136  else if(socket->type == SOCKET_TYPE_RAW_ETH)
1137  {
1138  //Receive a raw Ethernet packet
1140  }
1141  else
1142 #endif
1143  //Invalid socket type?
1144  {
1145  //Report an error
1146  error = ERROR_INVALID_SOCKET;
1147  }
1148 
1149  //Release exclusive access
1151 
1152  //Return status code
1153  return error;
1154 }
1155 
1156 
1157 /**
1158  * @brief Retrieve the local address for a given socket
1159  * @param[in] socket Handle that identifies a socket
1160  * @param[out] localIpAddr Local IP address (optional)
1161  * @param[out] localPort Local port number (optional)
1162  * @return Error code
1163  **/
1164 
1165 error_t socketGetLocalAddr(Socket *socket, IpAddr *localIpAddr, uint16_t *localPort)
1166 {
1167  //Make sure the socket handle is valid
1168  if(socket == NULL)
1169  return ERROR_INVALID_PARAMETER;
1170 
1171  //Retrieve local IP address
1172  if(localIpAddr != NULL)
1173  *localIpAddr = socket->localIpAddr;
1174 
1175  //Retrieve local port number
1176  if(localPort != NULL)
1177  *localPort = socket->localPort;
1178 
1179  //Successful processing
1180  return NO_ERROR;
1181 }
1182 
1183 
1184 /**
1185  * @brief Retrieve the address of the peer to which a socket is connected
1186  * @param[in] socket Handle that identifies a socket
1187  * @param[out] remoteIpAddr IP address of the remote host (optional)
1188  * @param[out] remotePort Remote port number (optional)
1189  * @return Error code
1190  **/
1191 
1192 error_t socketGetRemoteAddr(Socket *socket, IpAddr *remoteIpAddr, uint16_t *remotePort)
1193 {
1194  //Make sure the socket handle is valid
1195  if(socket == NULL)
1196  return ERROR_INVALID_PARAMETER;
1197 
1198  //Retrieve local IP address
1199  if(remoteIpAddr != NULL)
1200  *remoteIpAddr = socket->remoteIpAddr;
1201 
1202  //Retrieve local port number
1203  if(remotePort != NULL)
1204  *remotePort = socket->remotePort;
1205 
1206  //Successful processing
1207  return NO_ERROR;
1208 }
1209 
1210 
1211 /**
1212  * @brief Disable reception, transmission, or both
1213  *
1214  * Note that socketShutdown() does not close the socket, and resources attached
1215  * to the socket will not be freed until socketClose() is invoked
1216  *
1217  * @param[in] socket Handle to a socket
1218  * @param[in] how Flag that describes what types of operation will no longer be allowed
1219  * @return Error code
1220  **/
1221 
1223 {
1224 #if (TCP_SUPPORT == ENABLED)
1225  error_t error;
1226 
1227  //Make sure the socket handle is valid
1228  if(socket == NULL)
1229  return ERROR_INVALID_PARAMETER;
1230  //Make sure the socket type is correct
1231  if(socket->type != SOCKET_TYPE_STREAM)
1232  return ERROR_INVALID_SOCKET;
1233  //Check flags
1234  if((how != SOCKET_SD_SEND) && (how != SOCKET_SD_RECEIVE) && (how != SOCKET_SD_BOTH))
1235  return ERROR_INVALID_PARAMETER;
1236 
1237  //Get exclusive access
1239 
1240  //Graceful shutdown
1241  error = tcpShutdown(socket, how);
1242 
1243  //Release exclusive access
1245 
1246  //Return status code
1247  return error;
1248 #else
1249  return ERROR_NOT_IMPLEMENTED;
1250 #endif
1251 }
1252 
1253 
1254 /**
1255  * @brief Close an existing socket
1256  * @param[in] socket Handle identifying the socket to close
1257  **/
1258 
1260 {
1261  //Make sure the socket handle is valid
1262  if(socket == NULL)
1263  return;
1264 
1265  //Get exclusive access
1267 
1268 #if (TCP_SUPPORT == ENABLED)
1269  //Connection-oriented socket?
1270  if(socket->type == SOCKET_TYPE_STREAM)
1271  {
1272  //Abort the current TCP connection
1273  tcpAbort(socket);
1274  }
1275 #endif
1276 #if (UDP_SUPPORT == ENABLED || RAW_SOCKET_SUPPORT == ENABLED)
1277  //Connectionless socket or raw socket?
1278  if(socket->type == SOCKET_TYPE_DGRAM ||
1279  socket->type == SOCKET_TYPE_RAW_IP ||
1280  socket->type == SOCKET_TYPE_RAW_ETH)
1281  {
1282  //Point to the first item in the receive queue
1283  SocketQueueItem *queueItem = socket->receiveQueue;
1284 
1285  //Purge the receive queue
1286  while(queueItem)
1287  {
1288  //Keep track of the next item in the queue
1289  SocketQueueItem *nextQueueItem = queueItem->next;
1290  //Free previously allocated memory
1291  memPoolFree(queueItem->buffer);
1292  //Point to the next item
1293  queueItem = nextQueueItem;
1294  }
1295 
1296  //Mark the socket as closed
1297  socket->type = SOCKET_TYPE_UNUSED;
1298  }
1299 #endif
1300 
1301  //Release exclusive access
1303 }
1304 
1305 
1306 /**
1307  * @brief Wait for one of a set of sockets to become ready to perform I/O
1308  *
1309  * The socketPoll function determines the status of one or more sockets,
1310  * waiting if necessary, to perform synchronous I/O
1311  *
1312  * @param[in,out] eventDesc Set of entries specifying the events the user is interested in
1313  * @param[in] size Number of entries in the descriptor set
1314  * @param[in] extEvent External event that can abort the wait if necessary (optional)
1315  * @param[in] timeout Maximum time to wait before returning
1316  * @return Error code
1317  **/
1318 
1319 error_t socketPoll(SocketEventDesc *eventDesc, uint_t size, OsEvent *extEvent,
1320  systime_t timeout)
1321 {
1322  uint_t i;
1323  bool_t status;
1324  OsEvent *event;
1325  OsEvent eventObject;
1326 
1327  //Check parameters
1328  if(eventDesc == NULL || size == 0)
1329  return ERROR_INVALID_PARAMETER;
1330 
1331  //Try to use the supplied event object to receive notifications
1332  if(!extEvent)
1333  {
1334  //Create an event object only if necessary
1335  if(!osCreateEvent(&eventObject))
1336  {
1337  //Report an error
1338  return ERROR_OUT_OF_RESOURCES;
1339  }
1340 
1341  //Reference to the newly created event
1342  event = &eventObject;
1343  }
1344  else
1345  {
1346  //Reference to the external event
1347  event = extEvent;
1348  }
1349 
1350  //Loop through descriptors
1351  for(i = 0; i < size; i++)
1352  {
1353  //Valid socket handle?
1354  if(eventDesc[i].socket != NULL)
1355  {
1356  //Clear event flags
1357  eventDesc[i].eventFlags = 0;
1358  //Subscribe to the requested events
1359  socketRegisterEvents(eventDesc[i].socket, event, eventDesc[i].eventMask);
1360  }
1361  }
1362 
1363  //Block the current task until an event occurs
1364  status = osWaitForEvent(event, timeout);
1365 
1366  //Loop through descriptors
1367  for(i = 0; i < size; i++)
1368  {
1369  //Valid socket handle?
1370  if(eventDesc[i].socket != NULL)
1371  {
1372  //Any socket event in the signaled state?
1373  if(status)
1374  {
1375  //Retrieve event flags for the current socket
1376  eventDesc[i].eventFlags = socketGetEvents(eventDesc[i].socket);
1377  //Clear unnecessary flags
1378  eventDesc[i].eventFlags &= eventDesc[i].eventMask;
1379  }
1380 
1381  //Unsubscribe previously registered events
1382  socketUnregisterEvents(eventDesc[i].socket);
1383  }
1384  }
1385 
1386  //Reset event object
1387  osResetEvent(event);
1388 
1389  //Release previously allocated resources
1390  if(!extEvent)
1391  osDeleteEvent(&eventObject);
1392 
1393  //Return status code
1394  return status ? NO_ERROR : ERROR_TIMEOUT;
1395 }
1396 
1397 
1398 /**
1399  * @brief Subscribe to the specified socket events
1400  * @param[in] socket Handle that identifies a socket
1401  * @param[in] event Event object used to receive notifications
1402  * @param[in] eventMask Logic OR of the requested socket events
1403  **/
1404 
1406 {
1407  //Valid socket handle?
1408  if(socket != NULL)
1409  {
1410  //Get exclusive access
1412 
1413  //An user event may have been previously registered...
1414  if(socket->userEvent != NULL)
1415  socket->eventMask |= eventMask;
1416  else
1417  socket->eventMask = eventMask;
1418 
1419  //Suscribe to get notified of events
1420  socket->userEvent = event;
1421 
1422 #if (TCP_SUPPORT == ENABLED)
1423  //Handle TCP specific events
1424  if(socket->type == SOCKET_TYPE_STREAM)
1425  {
1427  }
1428 #endif
1429 #if (UDP_SUPPORT == ENABLED)
1430  //Handle UDP specific events
1431  if(socket->type == SOCKET_TYPE_DGRAM)
1432  {
1434  }
1435 #endif
1436 #if (RAW_SOCKET_SUPPORT == ENABLED)
1437  //Handle events that are specific to raw sockets
1438  if(socket->type == SOCKET_TYPE_RAW_IP ||
1439  socket->type == SOCKET_TYPE_RAW_ETH)
1440  {
1442  }
1443 #endif
1444 
1445  //Release exclusive access
1447  }
1448 }
1449 
1450 
1451 /**
1452  * @brief Unsubscribe previously registered events
1453  * @param[in] socket Handle that identifies a socket
1454  **/
1455 
1457 {
1458  //Valid socket handle?
1459  if(socket != NULL)
1460  {
1461  //Get exclusive access
1463 
1464  //Unsuscribe socket events
1465  socket->userEvent = NULL;
1466 
1467  //Release exclusive access
1469  }
1470 }
1471 
1472 
1473 /**
1474  * @brief Retrieve event flags for a specified socket
1475  * @param[in] socket Handle that identifies a socket
1476  * @return Logic OR of events in the signaled state
1477  **/
1478 
1480 {
1481  uint_t eventFlags;
1482 
1483  //Valid socket handle?
1484  if(socket != NULL)
1485  {
1486  //Get exclusive access
1488 
1489  //Read event flags for the specified socket
1490  eventFlags = socket->eventFlags;
1491 
1492  //Release exclusive access
1494  }
1495  else
1496  {
1497  //The socket handle is not valid
1498  eventFlags = 0;
1499  }
1500 
1501  //Return the events in the signaled state
1502  return eventFlags;
1503 }
1504 
1505 
1506 /**
1507  * @brief Resolve a host name into an IP address
1508  * @param[in] interface Underlying network interface (optional parameter)
1509  * @param[in] name Name of the host to be resolved
1510  * @param[out] ipAddr IP address corresponding to the specified host name
1511  * @param[in] flags Set of flags that influences the behavior of this function
1512  * @return Error code
1513  **/
1514 
1516  const char_t *name, IpAddr *ipAddr, uint_t flags)
1517 {
1518  error_t error;
1519  HostType type;
1521 
1522  //Default address type depends on TCP/IP stack configuration
1523 #if (IPV4_SUPPORT == ENABLED)
1524  type = HOST_TYPE_IPV4;
1525 #elif (IPV6_SUPPORT == ENABLED)
1526  type = HOST_TYPE_IPV6;
1527 #else
1528  type = HOST_TYPE_ANY;
1529 #endif
1530 
1531  //Default name resolution protocol depends on TCP/IP stack configuration
1532 #if (DNS_CLIENT_SUPPORT == ENABLED)
1534 #elif (MDNS_CLIENT_SUPPORT == ENABLED)
1536 #elif (NBNS_CLIENT_SUPPORT == ENABLED)
1538 #elif (LLMNR_CLIENT_SUPPORT == ENABLED)
1540 #else
1542 #endif
1543 
1544  //Check parameters
1545  if(name == NULL || ipAddr == NULL)
1546  return ERROR_INVALID_PARAMETER;
1547 
1548  //Use default network interface?
1549  if(interface == NULL)
1550  interface = netGetDefaultInterface();
1551 
1552  //The specified name can be either an IP or a host name
1553  error = ipStringToAddr(name, ipAddr);
1554 
1555  //Perform name resolution if necessary
1556  if(error)
1557  {
1558  //The user may provide a hint to choose between IPv4 and IPv6
1559  if(flags & HOST_TYPE_IPV4)
1560  type = HOST_TYPE_IPV4;
1561  else if(flags & HOST_TYPE_IPV6)
1562  type = HOST_TYPE_IPV6;
1563 
1564  //The user may provide a hint to to select the desired protocol to be used
1566  {
1567  //Use DNS to resolve the specified host name
1569  }
1570  else if(flags & HOST_NAME_RESOLVER_MDNS)
1571  {
1572  //Use mDNS to resolve the specified host name
1574  }
1575  else if(flags & HOST_NAME_RESOLVER_NBNS)
1576  {
1577  //Use NBNS to resolve the specified host name
1579  }
1580  else if(flags & HOST_NAME_RESOLVER_LLMNR)
1581  {
1582  //Use LLMNR to resolve the specified host name
1584  }
1585  else
1586  {
1587  //Retrieve the length of the host name to be resolved
1588  size_t n = osStrlen(name);
1589 
1590  //Select the most suitable protocol
1591  if(n >= 6 && !osStrcasecmp(name + n - 6, ".local"))
1592  {
1593 #if (MDNS_CLIENT_SUPPORT == ENABLED)
1594  //Use mDNS to resolve the specified host name
1596 #endif
1597  }
1598  else if(n <= 15 && !strchr(name, '.') && type == HOST_TYPE_IPV4)
1599  {
1600 #if (NBNS_CLIENT_SUPPORT == ENABLED)
1601  //Use NetBIOS Name Service to resolve the specified host name
1603 #endif
1604  }
1605  else if(!strchr(name, '.'))
1606  {
1607 #if (LLMNR_CLIENT_SUPPORT == ENABLED)
1608  //Use LLMNR to resolve the specified host name
1610 #endif
1611  }
1612  }
1613 
1614 #if (DNS_CLIENT_SUPPORT == ENABLED)
1615  //Use DNS protocol?
1617  {
1618  //Perform host name resolution
1619  error = dnsResolve(interface, name, type, ipAddr);
1620  }
1621  else
1622 #endif
1623 #if (MDNS_CLIENT_SUPPORT == ENABLED)
1624  //Use mDNS protocol?
1626  {
1627  //Perform host name resolution
1628  error = mdnsClientResolve(interface, name, type, ipAddr);
1629  }
1630  else
1631 #endif
1632 #if (NBNS_CLIENT_SUPPORT == ENABLED && IPV4_SUPPORT == ENABLED)
1633  //Use NetBIOS Name Service protocol?
1635  {
1636  //Perform host name resolution
1637  error = nbnsResolve(interface, name, ipAddr);
1638  }
1639  else
1640 #endif
1641 #if (LLMNR_CLIENT_SUPPORT == ENABLED)
1642  //Use LLMNR protocol?
1644  {
1645  //Perform host name resolution
1646  error = llmnrResolve(interface, name, type, ipAddr);
1647  }
1648  else
1649 #endif
1650  //Invalid protocol?
1651  {
1652  //Report an error
1653  error = ERROR_INVALID_PARAMETER;
1654  }
1655  }
1656 
1657  //Return status code
1658  return error;
1659 }
error_t socketSend(Socket *socket, const void *data, size_t length, size_t *written, uint_t flags)
Send data to a connected socket.
Definition: socket.c:775
uint8_t length
Definition: coap_common.h:190
error_t rawSocketSendEthPacket(Socket *socket, const SocketMsg *message, uint_t flags)
Send an raw Ethernet packet.
Definition: raw_socket.c:591
HostType
Host types.
Definition: socket.h:172
error_t socketBind(Socket *socket, const IpAddr *localIpAddr, uint16_t localPort)
Associate a local address with a socket.
Definition: socket.c:616
error_t socketSetDscp(Socket *socket, uint8_t dscp)
Set DSCP field.
Definition: socket.c:331
HostnameResolver
Name resolution protocols.
Definition: socket.h:184
int bool_t
Definition: compiler_port.h:49
void memPoolFree(void *p)
Release a memory block.
Definition: net_mem.c:166
uint8_t data[]
Definition: ethernet.h:209
#define netMutex
Definition: net_legacy.h:266
void udpUpdateEvents(Socket *socket)
Update UDP related events.
Definition: udp.c:796
IP network address.
Definition: ip.h:78
error_t tcpReceive(Socket *socket, uint8_t *data, size_t size, size_t *received, uint_t flags)
Receive data from a connected socket.
Definition: tcp.c:574
Message and ancillary data.
Definition: socket.h:198
void socketClose(Socket *socket)
Close an existing socket.
Definition: socket.c:1259
Event object.
char_t name[]
uint16_t destPort
Definition: tcp.h:303
#define osStrlen(s)
Definition: os_port.h:152
Ipv4Addr srcIpAddr
Definition: ipcp.h:77
struct _SocketQueueItem * next
Definition: socket.h:228
error_t tcpListen(Socket *socket, uint_t backlog)
Place a socket in the listening state.
Definition: tcp.c:236
error_t socketGetRemoteAddr(Socket *socket, IpAddr *remoteIpAddr, uint16_t *remotePort)
Retrieve the address of the peer to which a socket is connected.
Definition: socket.c:1192
error_t udpReceiveDatagram(Socket *socket, SocketMsg *message, uint_t flags)
Receive data from a UDP socket.
Definition: udp.c:672
Structure describing socket events.
Definition: socket.h:348
error_t socketSetVmanDei(Socket *socket, bool_t dei)
Set VMAN DEI flag.
Definition: socket.c:472
uint_t socketGetEvents(Socket *socket)
Retrieve event flags for a specified socket.
Definition: socket.c:1479
error_t rawSocketSendIpPacket(Socket *socket, const SocketMsg *message, uint_t flags)
Send an raw IP packet.
Definition: raw_socket.c:427
error_t socketSetTxBufferSize(Socket *socket, size_t size)
Specify the size of the send buffer.
Definition: socket.c:505
#define TCP_DEFAULT_TX_BUFFER_SIZE
Definition: tcp.h:68
error_t ipStringToAddr(const char_t *str, IpAddr *ipAddr)
Convert a string representation of an IP address to a binary IP address.
Definition: ip.c:683
error_t socketSendMsg(Socket *socket, const SocketMsg *message, uint_t flags)
Send a message to a connectionless socket.
Definition: socket.c:892
const SocketMsg SOCKET_DEFAULT_MSG
Definition: socket.c:52
error_t socketSetRxBufferSize(Socket *socket, size_t size)
Specify the size of the receive buffer.
Definition: socket.c:539
Helper functions for TCP.
Invalid parameter.
Definition: error.h:47
void osResetEvent(OsEvent *event)
Set the specified event object to the nonsignaled state.
#define osMemcpy(dest, src, length)
Definition: os_port.h:134
error_t dnsResolve(NetInterface *interface, const char_t *name, HostType type, IpAddr *ipAddr)
Resolve a host name using DNS.
Definition: dns_client.c:54
char_t type
error_t
Error codes.
Definition: error.h:42
Socket * tcpKillOldestConnection(void)
Kill the oldest socket in the TIME-WAIT state.
Definition: tcp.c:961
#define TCP_MAX_RX_BUFFER_SIZE
Definition: tcp.h:89
error_t socketReceive(Socket *socket, void *data, size_t size, size_t *received, uint_t flags)
Receive data from a connected socket.
Definition: socket.c:950
error_t tcpSend(Socket *socket, const uint8_t *data, size_t length, size_t *written, uint_t flags)
Send data to a connected socket.
Definition: tcp.c:449
uint8_t protocol
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
NBNS client (NetBIOS Name Service)
TcpState tcpGetState(Socket *socket)
Get the current state of the TCP FSM.
Definition: tcp.c:937
error_t socketSetVmanPcp(Socket *socket, uint8_t pcp)
Set VMAN priority.
Definition: socket.c:435
void osDeleteEvent(OsEvent *event)
Delete an event object.
#define NetInterface
Definition: net.h:36
NetInterface * netGetDefaultInterface(void)
Get default network interface.
Definition: net.c:1373
#define osStrcasecmp(s1, s2)
Definition: os_port.h:170
error_t socketReceiveFrom(Socket *socket, IpAddr *srcIpAddr, uint16_t *srcPort, void *data, size_t size, size_t *received, uint_t flags)
Receive a datagram from a connectionless socket.
Definition: socket.c:972
error_t socketReceiveMsg(Socket *socket, SocketMsg *message, uint_t flags)
Receive a message from a connectionless socket.
Definition: socket.c:1106
error_t getHostByName(NetInterface *interface, const char_t *name, IpAddr *ipAddr, uint_t flags)
Resolve a host name into an IP address.
Definition: socket.c:1515
error_t socketSetTtl(Socket *socket, uint8_t ttl)
Set TTL value for unicast datagrams.
Definition: socket.c:281
mDNS client (Multicast DNS)
error_t socketConnect(Socket *socket, const IpAddr *remoteIpAddr, uint16_t remotePort)
Establish a connection to a specified socket.
Definition: socket.c:642
void tcpUpdateEvents(Socket *socket)
Update TCP related events.
Definition: tcp_misc.c:1799
error_t llmnrResolve(NetInterface *interface, const char_t *name, HostType type, IpAddr *ipAddr)
Resolve a host name using LLMNR.
Definition: llmnr_client.c:54
error_t socketShutdown(Socket *socket, uint_t how)
Disable reception, transmission, or both.
Definition: socket.c:1222
error_t udpSendDatagram(Socket *socket, const SocketMsg *message, uint_t flags)
Send a UDP datagram.
Definition: udp.c:408
Socket * socketOpen(uint_t type, uint_t protocol)
Create a socket (UDP or TCP)
Definition: socket.c:119
#define MIN(a, b)
Definition: os_port.h:62
uint_t eventFlags
Returned events.
Definition: socket.h:352
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:49
error_t socketPoll(SocketEventDesc *eventDesc, uint_t size, OsEvent *extEvent, systime_t timeout)
Wait for one of a set of sockets to become ready to perform I/O.
Definition: socket.c:1319
void rawSocketUpdateEvents(Socket *socket)
Update event state for raw sockets.
Definition: raw_socket.c:920
#define TCP_MAX_TX_BUFFER_SIZE
Definition: tcp.h:75
error_t socketSetVlanDei(Socket *socket, bool_t dei)
Set VLAN DEI flag.
Definition: socket.c:402
uint16_t udpGetDynamicPort(void)
Get an ephemeral port number.
Definition: udp.c:89
void socketUnregisterEvents(Socket *socket)
Unsubscribe previously registered events.
Definition: socket.c:1456
Socket * socketAccept(Socket *socket, IpAddr *clientIpAddr, uint16_t *clientPort)
Permit an incoming connection attempt on a socket.
Definition: socket.c:742
DNS client (Domain Name System)
TCP/IP raw sockets.
error_t socketSetVlanPcp(Socket *socket, uint8_t pcp)
Set VLAN priority.
Definition: socket.c:365
uint16_t port
Definition: dns_common.h:223
Receive queue item.
Definition: socket.h:226
uint8_t flags
Definition: tcp.h:314
char char_t
Definition: compiler_port.h:43
LLMNR client (Link-Local Multicast Name Resolution)
void socketRegisterEvents(Socket *socket, OsEvent *event, uint_t eventMask)
Subscribe to the specified socket events.
Definition: socket.c:1405
uint16_t tcpGetDynamicPort(void)
Get an ephemeral port number.
Definition: tcp.c:75
error_t socketSetInterface(Socket *socket, NetInterface *interface)
Bind a socket to a particular network interface.
Definition: socket.c:573
uint8_t n
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
TCP (Transmission Control Protocol)
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
error_t socketGetLocalAddr(Socket *socket, IpAddr *localIpAddr, uint16_t *localPort)
Retrieve the local address for a given socket.
Definition: socket.c:1165
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
error_t tcpAbort(Socket *socket)
Abort an existing TCP connection.
Definition: tcp.c:873
error_t rawSocketReceiveEthPacket(Socket *socket, SocketMsg *message, uint_t flags)
Receive an Ethernet packet from a raw socket.
Definition: raw_socket.c:831
error_t mdnsClientResolve(NetInterface *interface, const char_t *name, HostType type, IpAddr *ipAddr)
Resolve a host name using mDNS.
Definition: mdns_client.c:56
UDP (User Datagram Protocol)
#define Socket
Definition: socket.h:36
NetInterface * socketGetInterface(Socket *socket)
Retrieve the underlying interface.
Definition: socket.c:593
bool_t osCreateEvent(OsEvent *event)
Create an event object.
uint8_t message[]
Definition: chap.h:152
Socket API.
error_t socketSendTo(Socket *socket, const IpAddr *destIpAddr, uint16_t destPort, const void *data, size_t length, size_t *written, uint_t flags)
Send a datagram to a specific destination.
Definition: socket.c:796
error_t socketSetMulticastTtl(Socket *socket, uint8_t ttl)
Set TTL value for multicast datagrams.
Definition: socket.c:306
error_t tcpConnect(Socket *socket, const IpAddr *remoteIpAddr, uint16_t remotePort)
Establish a TCP connection.
Definition: tcp.c:115
error_t socketReceiveEx(Socket *socket, IpAddr *srcIpAddr, uint16_t *srcPort, IpAddr *destIpAddr, void *data, size_t size, size_t *received, uint_t flags)
Receive a datagram.
Definition: socket.c:994
error_t tcpShutdown(Socket *socket, uint_t how)
Shutdown gracefully reception, transmission, or both.
Definition: tcp.c:722
uint32_t ttl
Definition: dns_common.h:205
uint16_t srcPort
Definition: tcp.h:302
Socket * tcpAccept(Socket *socket, IpAddr *clientIpAddr, uint16_t *clientPort)
Permit an incoming connection attempt on a TCP socket.
Definition: tcp.c:263
#define TCP_DEFAULT_RX_BUFFER_SIZE
Definition: tcp.h:82
unsigned int uint_t
Definition: compiler_port.h:45
#define osMemset(p, value, length)
Definition: os_port.h:128
TCP/IP stack core.
error_t rawSocketReceiveIpPacket(Socket *socket, SocketMsg *message, uint_t flags)
Receive an IP packet from a raw socket.
Definition: raw_socket.c:727
#define SOCKET_MAX_COUNT
Definition: socket.h:46
error_t socketSetTimeout(Socket *socket, systime_t timeout)
Set timeout value for blocking operations.
Definition: socket.c:256
uint32_t systime_t
Definition: compiler_port.h:46
uint8_t ipAddr[4]
Definition: mib_common.h:187
NetBuffer * buffer
Definition: socket.h:232
uint_t eventMask
Requested events.
Definition: socket.h:351
error_t socketInit(void)
Socket related initialization.
Definition: socket.c:81
Success.
Definition: error.h:44
Debugging facilities.
#define INFINITE_DELAY
Definition: os_port.h:74
error_t nbnsResolve(NetInterface *interface, const char_t *name, IpAddr *ipAddr)
Resolve a host name using NBNS.
Definition: nbns_client.c:53
Ipv4Addr destIpAddr
Definition: ipcp.h:78
error_t socketListen(Socket *socket, uint_t backlog)
Place a socket in the listening state.
Definition: socket.c:705