raw_socket.c
Go to the documentation of this file.
1 /**
2  * @file raw_socket.c
3  * @brief TCP/IP raw sockets
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  * @section Description
28  *
29  * A raw socket is a type of socket that allows access to the
30  * underlying transport provider
31  *
32  * @author Oryx Embedded SARL (www.oryx-embedded.com)
33  * @version 1.9.6
34  **/
35 
36 //Switch to the appropriate trace level
37 #define TRACE_LEVEL RAW_SOCKET_TRACE_LEVEL
38 
39 //Dependencies
40 #include <string.h>
41 #include "core/net.h"
42 #include "core/socket.h"
43 #include "core/raw_socket.h"
44 #include "core/ethernet_misc.h"
45 #include "ipv4/ipv4.h"
46 #include "ipv4/ipv4_misc.h"
47 #include "ipv6/ipv6.h"
48 #include "ipv6/ipv6_misc.h"
49 #include "debug.h"
50 
51 //Check TCP/IP stack configuration
52 #if (RAW_SOCKET_SUPPORT == ENABLED)
53 
54 
55 /**
56  * @brief Process incoming IP packet
57  * @param[in] interface Underlying network interface
58  * @param[in] pseudoHeader IPv4 or IPv6 pseudo header
59  * @param[in] buffer Multi-part buffer containing the IP packet
60  * @param[in] offset Offset to the first byte of the IP packet
61  * @return Error code
62  **/
63 
65  IpPseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset)
66 {
67  uint_t i;
68  size_t length;
69  Socket *socket;
70  SocketQueueItem *queueItem;
71  NetBuffer *p;
72 
73  //Retrieve the length of the raw IP packet
74  length = netBufferGetLength(buffer) - offset;
75 
76  //Loop through opened sockets
77  for(i = 0; i < SOCKET_MAX_COUNT; i++)
78  {
79  //Point to the current socket
80  socket = socketTable + i;
81 
82  //Raw socket found?
83  if(socket->type != SOCKET_TYPE_RAW_IP)
84  continue;
85  //Check whether the socket is bound to a particular interface
86  if(socket->interface && socket->interface != interface)
87  continue;
88 
89 #if (IPV4_SUPPORT == ENABLED)
90  //IPv4 packet received?
91  if(pseudoHeader->length == sizeof(Ipv4PseudoHeader))
92  {
93  //Check protocol field
94  if(socket->protocol != pseudoHeader->ipv4Data.protocol)
95  continue;
96 
97  //Destination IP address filtering
98  if(socket->localIpAddr.length != 0)
99  {
100  //An IPv4 address is expected
101  if(socket->localIpAddr.length != sizeof(Ipv4Addr))
102  continue;
103  //Filter out non-matching addresses
104  if(socket->localIpAddr.ipv4Addr != pseudoHeader->ipv4Data.destAddr)
105  continue;
106  }
107 
108  //Source IP address filtering
109  if(socket->remoteIpAddr.length != 0)
110  {
111  //An IPv4 address is expected
112  if(socket->remoteIpAddr.length != sizeof(Ipv4Addr))
113  continue;
114  //Filter out non-matching addresses
115  if(socket->remoteIpAddr.ipv4Addr != pseudoHeader->ipv4Data.srcAddr)
116  continue;
117  }
118  }
119  else
120 #endif
121 #if (IPV6_SUPPORT == ENABLED)
122  //IPv6 packet received?
123  if(pseudoHeader->length == sizeof(Ipv6PseudoHeader))
124  {
125  //Check protocol field
126  if(socket->protocol != pseudoHeader->ipv6Data.nextHeader)
127  continue;
128 
129  //Destination IP address filtering
130  if(socket->localIpAddr.length != 0)
131  {
132  //An IPv6 address is expected
133  if(socket->localIpAddr.length != sizeof(Ipv6Addr))
134  continue;
135  //Filter out non-matching addresses
136  if(!ipv6CompAddr(&socket->localIpAddr.ipv6Addr, &pseudoHeader->ipv6Data.destAddr))
137  continue;
138  }
139 
140  //Source IP address filtering
141  if(socket->remoteIpAddr.length != 0)
142  {
143  //An IPv6 address is expected
144  if(socket->remoteIpAddr.length != sizeof(Ipv6Addr))
145  continue;
146  //Filter out non-matching addresses
147  if(!ipv6CompAddr(&socket->remoteIpAddr.ipv6Addr, &pseudoHeader->ipv6Data.srcAddr))
148  continue;
149  }
150  }
151  else
152 #endif
153  //Invalid packet received?
154  {
155  //This should never occur...
156  continue;
157  }
158 
159  //The current socket meets all the criteria
160  break;
161  }
162 
163  //Drop incoming packet if no matching socket was found
164  if(i >= SOCKET_MAX_COUNT)
166 
167  //Empty receive queue?
168  if(!socket->receiveQueue)
169  {
170  //Allocate a memory buffer to hold the data and the associated descriptor
171  p = netBufferAlloc(sizeof(SocketQueueItem) + length);
172 
173  //Successful memory allocation?
174  if(p != NULL)
175  {
176  //Point to the newly created item
177  queueItem = netBufferAt(p, 0);
178  queueItem->buffer = p;
179  //Add the newly created item to the queue
180  socket->receiveQueue = queueItem;
181  }
182  else
183  {
184  //Memory allocation failed
185  queueItem = NULL;
186  }
187  }
188  else
189  {
190  //Point to the very first item
191  queueItem = socket->receiveQueue;
192  //Reach the last item in the receive queue
193  for(i = 1; queueItem->next; i++)
194  queueItem = queueItem->next;
195 
196  //Make sure the receive queue is not full
197  if(i >= RAW_SOCKET_RX_QUEUE_SIZE)
199 
200  //Allocate a memory buffer to hold the data and the associated descriptor
201  p = netBufferAlloc(sizeof(SocketQueueItem) + length);
202 
203  //Successful memory allocation?
204  if(p != NULL)
205  {
206  //Add the newly created item to the queue
207  queueItem->next = netBufferAt(p, 0);
208  //Point to the newly created item
209  queueItem = queueItem->next;
210  queueItem->buffer = p;
211  }
212  else
213  {
214  //Memory allocation failed
215  queueItem = NULL;
216  }
217  }
218 
219  //Failed to allocate memory?
220  if(queueItem == NULL)
221  return ERROR_OUT_OF_MEMORY;
222 
223  //Initialize next field
224  queueItem->next = NULL;
225  //Port number is unused
226  queueItem->srcPort = 0;
227 
228 #if (IPV4_SUPPORT == ENABLED)
229  //IPv4 remote address?
230  if(pseudoHeader->length == sizeof(Ipv4PseudoHeader))
231  {
232  //Save the source IPv4 address
233  queueItem->srcIpAddr.length = sizeof(Ipv4Addr);
234  queueItem->srcIpAddr.ipv4Addr = pseudoHeader->ipv4Data.srcAddr;
235  //Save the destination IPv4 address
236  queueItem->destIpAddr.length = sizeof(Ipv4Addr);
237  queueItem->destIpAddr.ipv4Addr = pseudoHeader->ipv4Data.destAddr;
238  }
239 #endif
240 #if (IPV6_SUPPORT == ENABLED)
241  //IPv6 remote address?
242  if(pseudoHeader->length == sizeof(Ipv6PseudoHeader))
243  {
244  //Save the source IPv6 address
245  queueItem->srcIpAddr.length = sizeof(Ipv6Addr);
246  queueItem->srcIpAddr.ipv6Addr = pseudoHeader->ipv6Data.srcAddr;
247  //Save the destination IPv6 address
248  queueItem->destIpAddr.length = sizeof(Ipv6Addr);
249  queueItem->destIpAddr.ipv6Addr = pseudoHeader->ipv6Data.destAddr;
250  }
251 #endif
252 
253  //Offset to the raw IP packet
254  queueItem->offset = sizeof(SocketQueueItem);
255  //Copy the raw data
256  netBufferCopy(queueItem->buffer, queueItem->offset, buffer, offset, length);
257 
258  //Notify user that data is available
260 
261  //Successful processing
262  return NO_ERROR;
263 }
264 
265 
266 /**
267  * @brief Process incoming Ethernet packet
268  * @param[in] interface Underlying network interface
269  * @param[in] header Pointer to the Ethernet header
270  * @param[in] data Pointer to the payload data
271  * @param[in] length Length of the payload data, in bytes
272  **/
273 
275  const uint8_t *data, size_t length)
276 {
277  uint_t i;
278  Socket *socket;
279  SocketQueueItem *queueItem;
280  NetBuffer *p;
281 
282  //Loop through opened sockets
283  for(i = 0; i < SOCKET_MAX_COUNT; i++)
284  {
285  //Point to the current socket
286  socket = socketTable + i;
287 
288  //Raw socket found?
289  if(socket->type != SOCKET_TYPE_RAW_ETH)
290  continue;
291  //Check whether the socket is bound to a particular interface
292  if(socket->interface && socket->interface != interface)
293  continue;
294 
295  //Check protocol field
296  if(socket->protocol == SOCKET_ETH_PROTO_ALL)
297  {
298  //Accept all EtherType values
299  }
300  else if(socket->protocol == SOCKET_ETH_PROTO_LLC)
301  {
302  //Only accept LLC frames
303  if(ntohs(header->type) > ETH_MTU)
304  continue;
305  }
306  else
307  {
308  //Only accept frames with the correct EtherType value
309  if(ntohs(header->type) != socket->protocol)
310  continue;
311  }
312 
313  //The current socket meets all the criteria
314  break;
315  }
316 
317  //Drop incoming packet if no matching socket was found
318  if(i >= SOCKET_MAX_COUNT)
319  return;
320 
321  //Empty receive queue?
322  if(!socket->receiveQueue)
323  {
324  //Allocate a memory buffer to hold the data and the associated descriptor
325  p = netBufferAlloc(sizeof(SocketQueueItem) + sizeof(EthHeader) + length);
326 
327  //Successful memory allocation?
328  if(p != NULL)
329  {
330  //Point to the newly created item
331  queueItem = netBufferAt(p, 0);
332  queueItem->buffer = p;
333  //Add the newly created item to the queue
334  socket->receiveQueue = queueItem;
335  }
336  else
337  {
338  //Memory allocation failed
339  queueItem = NULL;
340  }
341  }
342  else
343  {
344  //Point to the very first item
345  queueItem = socket->receiveQueue;
346  //Reach the last item in the receive queue
347  for(i = 1; queueItem->next; i++)
348  queueItem = queueItem->next;
349 
350  //Make sure the receive queue is not full
351  if(i >= RAW_SOCKET_RX_QUEUE_SIZE)
352  return;
353 
354  //Allocate a memory buffer to hold the data and the associated descriptor
355  p = netBufferAlloc(sizeof(SocketQueueItem) + sizeof(EthHeader) + length);
356 
357  //Successful memory allocation?
358  if(p != NULL)
359  {
360  //Add the newly created item to the queue
361  queueItem->next = netBufferAt(p, 0);
362  //Point to the newly created item
363  queueItem = queueItem->next;
364  queueItem->buffer = p;
365  }
366  else
367  {
368  //Memory allocation failed
369  queueItem = NULL;
370  }
371  }
372 
373  //Failed to allocate memory?
374  if(queueItem == NULL)
375  return;
376 
377  //Initialize next field
378  queueItem->next = NULL;
379  //Other fields are meaningless
380  queueItem->srcPort = 0;
381  queueItem->srcIpAddr = IP_ADDR_ANY;
382  queueItem->destIpAddr = IP_ADDR_ANY;
383 
384  //Offset to the raw datagram
385  queueItem->offset = sizeof(SocketQueueItem);
386 
387  //Copy the Ethernet header
388  netBufferWrite(queueItem->buffer, queueItem->offset, header,
389  sizeof(EthHeader));
390 
391  //Copy the payload
392  netBufferWrite(queueItem->buffer, queueItem->offset + sizeof(EthHeader),
393  data, length);
394 
395  //Notify user that data is available
397 }
398 
399 
400 /**
401  * @brief Send an raw IP packet
402  * @param[in] socket Handle referencing the socket
403  * @param[in] destIpAddr IP address of the target host
404  * @param[in] data Pointer to raw data
405  * @param[in] length Length of the raw data
406  * @param[out] written Actual number of bytes written (optional parameter)
407  * @param[in] flags Set of flags that influences the behavior of this function
408  * @return Error code
409  **/
410 
412  const void *data, size_t length, size_t *written, uint_t flags)
413 {
414  error_t error;
415  size_t offset;
416  NetBuffer *buffer;
417  NetInterface *interface;
418  IpPseudoHeader pseudoHeader;
419 
420  //Ignore unused flags
422 
423  //The socket may be bound to a particular network interface
424  interface = socket->interface;
425 
426  //Allocate a buffer memory to hold the raw IP datagram
427  buffer = ipAllocBuffer(0, &offset);
428  //Failed to allocate memory?
429  if(buffer == NULL)
430  return ERROR_OUT_OF_MEMORY;
431 
432  //Start of exception handling block
433  do
434  {
435  //Copy the raw data
436  error = netBufferAppend(buffer, data, length);
437  //Any error to report?
438  if(error)
439  break;
440 
441 #if (IPV4_SUPPORT == ENABLED)
442  //Destination address is an IPv4 address?
443  if(destIpAddr->length == sizeof(Ipv4Addr))
444  {
446 
447  //Select the source IPv4 address and the relevant network interface
448  //to use when sending data to the specified destination host
449  error = ipv4SelectSourceAddr(&interface, destIpAddr->ipv4Addr,
450  &srcIpAddr);
451  //Any error to report?
452  if(error)
453  break;
454 
455  //Format IPv4 pseudo header
456  pseudoHeader.length = sizeof(Ipv4PseudoHeader);
457  pseudoHeader.ipv4Data.srcAddr = srcIpAddr;
458  pseudoHeader.ipv4Data.destAddr = destIpAddr->ipv4Addr;
459  pseudoHeader.ipv4Data.reserved = 0;
460  pseudoHeader.ipv4Data.protocol = socket->protocol;
461  pseudoHeader.ipv4Data.length = htons(length);
462  }
463  else
464 #endif
465 #if (IPV6_SUPPORT == ENABLED)
466  //Destination address is an IPv6 address?
467  if(destIpAddr->length == sizeof(Ipv6Addr))
468  {
469  //Select the source IPv6 address and the relevant network interface
470  //to use when sending data to the specified destination host
471  error = ipv6SelectSourceAddr(&interface, &destIpAddr->ipv6Addr,
472  &pseudoHeader.ipv6Data.srcAddr);
473  //Any error to report?
474  if(error)
475  break;
476 
477  //Format IPv6 pseudo header
478  pseudoHeader.length = sizeof(Ipv6PseudoHeader);
479  pseudoHeader.ipv6Data.destAddr = destIpAddr->ipv6Addr;
480  pseudoHeader.ipv6Data.length = htonl(length);
481  pseudoHeader.ipv6Data.reserved = 0;
482  pseudoHeader.ipv6Data.nextHeader = socket->protocol;
483  }
484  else
485 #endif
486  //Invalid destination address?
487  {
488  //An internal error has occurred
489  error = ERROR_FAILURE;
490  //Exit immediately
491  break;
492  }
493 
494  //Send raw IP datagram
495  error = ipSendDatagram(interface, &pseudoHeader, buffer, offset,
496  flags | socket->ttl);
497  //Failed to send data?
498  if(error)
499  break;
500 
501  //Total number of bytes successfully transmitted
502  if(written != NULL)
503  *written = length;
504 
505  //End of exception handling block
506  } while(0);
507 
508  //Free previously allocated memory block
509  netBufferFree(buffer);
510  //Return status code
511  return error;
512 }
513 
514 
515 /**
516  * @brief Send an raw Ethernet packet
517  * @param[in] socket Handle referencing the socket
518  * @param[in] data Pointer to raw data
519  * @param[in] length Length of the raw data
520  * @param[out] written Actual number of bytes written (optional parameter)
521  * @return Error code
522  **/
523 
525  size_t length, size_t *written)
526 {
527  error_t error;
528 
529 #if (ETH_SUPPORT == ENABLED)
530  NetBuffer *buffer;
531  NetInterface *interface;
532 
533  //Select the relevant network interface
534  if(!socket->interface)
535  interface = netGetDefaultInterface();
536  else
537  interface = socket->interface;
538 
539  //Forward the frame to the physical interface
540  interface = nicGetPhysicalInterface(interface);
541 
542  //Ethernet interface?
543  if(interface->nicDriver != NULL &&
544  interface->nicDriver->type == NIC_TYPE_ETHERNET)
545  {
546  //Allocate a buffer memory to hold the raw Ethernet packet
547  buffer = netBufferAlloc(0);
548  //Failed to allocate buffer?
549  if(buffer == NULL)
550  return ERROR_OUT_OF_MEMORY;
551 
552  //Copy the raw data
553  error = netBufferAppend(buffer, data, length);
554 
555  //Successful processing?
556  if(!error)
557  {
558  //Automatic padding not supported by hardware?
559  if(!interface->nicDriver->autoPadding)
560  {
561  //The host controller should manually add padding
562  //to the packet before transmitting it
564  {
565  size_t n;
566 
567  //Add padding as necessary
569 
570  //Append padding bytes
571  error = netBufferAppend(buffer, ethPadding, n);
572  //Any error to report?
573  if(error)
574  return error;
575 
576  //Adjust frame length
577  length += n;
578  }
579  }
580 
581  //CRC calculation not supported by hardware?
582  if(!interface->nicDriver->autoCrcCalc)
583  {
584  uint32_t crc;
585 
586  //Compute CRC over the header and payload
587  crc = ethCalcCrcEx(buffer, 0, length);
588  //Convert from host byte order to little-endian byte order
589  crc = htole32(crc);
590 
591  //Append the calculated CRC value
592  error = netBufferAppend(buffer, &crc, sizeof(crc));
593  //Any error to report?
594  if(error)
595  return error;
596 
597  //Adjust frame length
598  length += sizeof(crc);
599  }
600 
601  //Debug message
602  TRACE_DEBUG("Sending raw Ethernet frame (%" PRIuSIZE " bytes)...\r\n", length);
603 
604  //Send the resulting packet over the specified link
605  error = nicSendPacket(interface, buffer, 0);
606  }
607 
608  //Free previously allocated memory block
609  netBufferFree(buffer);
610  }
611  else
612 #endif
613  //Unknown interface type?
614  {
615  //Report an error
616  error = ERROR_INVALID_INTERFACE;
617  }
618 
619  //Successful processing?
620  if(!error)
621  {
622  //Total number of bytes successfully transmitted
623  if(written != NULL)
624  *written = length;
625  }
626 
627  //Return status code
628  return error;
629 }
630 
631 
632 /**
633  * @brief Receive an IP packet from a raw socket
634  * @param[in] socket Handle referencing the socket
635  * @param[out] srcIpAddr Source IP address (optional)
636  * @param[out] destIpAddr Destination IP address (optional)
637  * @param[out] data Buffer where to store the incoming data
638  * @param[in] size Maximum number of bytes that can be received
639  * @param[out] received Number of bytes that have been received
640  * @param[in] flags Set of flags that influences the behavior of this function
641  * @return Error code
642  **/
643 
645  IpAddr *destIpAddr, void *data, size_t size, size_t *received, uint_t flags)
646 {
647  SocketQueueItem *queueItem;
648 
649  //The SOCKET_FLAG_DONT_WAIT enables non-blocking operation
651  {
652  //The receive queue is empty?
653  if(!socket->receiveQueue)
654  {
655  //Set the events the application is interested in
656  socket->eventMask = SOCKET_EVENT_RX_READY;
657  //Reset the event object
658  osResetEvent(&socket->event);
659 
660  //Release exclusive access
662  //Wait until an event is triggered
663  osWaitForEvent(&socket->event, socket->timeout);
664  //Get exclusive access
666  }
667  }
668 
669  //Check whether the read operation timed out
670  if(!socket->receiveQueue)
671  {
672  //No data can be read
673  *received = 0;
674  //Report a timeout error
675  return ERROR_TIMEOUT;
676  }
677 
678  //Point to the first item in the receive queue
679  queueItem = socket->receiveQueue;
680  //Copy data to user buffer
681  *received = netBufferRead(data, queueItem->buffer, queueItem->offset, size);
682 
683  //Save the source IP address
684  if(srcIpAddr)
685  *srcIpAddr = queueItem->srcIpAddr;
686  //Save the destination IP address
687  if(destIpAddr)
688  *destIpAddr = queueItem->destIpAddr;
689 
690  //If the SOCKET_FLAG_PEEK flag is set, the data is copied
691  //into the buffer but is not removed from the input queue
692  if(!(flags & SOCKET_FLAG_PEEK))
693  {
694  //Remove the item from the receive queue
695  socket->receiveQueue = queueItem->next;
696  //Deallocate memory buffer
697  netBufferFree(queueItem->buffer);
698  }
699 
700  //Update the state of events
702 
703  //Successful read operation
704  return NO_ERROR;
705 }
706 
707 
708 /**
709  * @brief Receive an Ethernet packet from a raw socket
710  * @param[in] socket Handle referencing the socket
711  * @param[out] data Buffer where to store the incoming data
712  * @param[in] size Maximum number of bytes that can be received
713  * @param[out] received Number of bytes that have been received
714  * @param[in] flags Set of flags that influences the behavior of this function
715  * @return Error code
716  **/
717 
719  size_t *received, uint_t flags)
720 {
721  SocketQueueItem *queueItem;
722 
723  //The SOCKET_FLAG_DONT_WAIT enables non-blocking operation
725  {
726  //The receive queue is empty?
727  if(!socket->receiveQueue)
728  {
729  //Set the events the application is interested in
730  socket->eventMask = SOCKET_EVENT_RX_READY;
731  //Reset the event object
732  osResetEvent(&socket->event);
733 
734  //Release exclusive access
736  //Wait until an event is triggered
737  osWaitForEvent(&socket->event, socket->timeout);
738  //Get exclusive access
740  }
741  }
742 
743  //Check whether the read operation timed out
744  if(!socket->receiveQueue)
745  {
746  //No data can be read
747  *received = 0;
748  //Report a timeout error
749  return ERROR_TIMEOUT;
750  }
751 
752  //Point to the first item in the receive queue
753  queueItem = socket->receiveQueue;
754  //Copy data to user buffer
755  *received = netBufferRead(data, queueItem->buffer, queueItem->offset, size);
756 
757  //If the SOCKET_FLAG_PEEK flag is set, the data is copied
758  //into the buffer but is not removed from the input queue
759  if(!(flags & SOCKET_FLAG_PEEK))
760  {
761  //Remove the item from the receive queue
762  socket->receiveQueue = queueItem->next;
763  //Deallocate memory buffer
764  netBufferFree(queueItem->buffer);
765  }
766 
767  //Update the state of events
769 
770  //Successful read operation
771  return NO_ERROR;
772 }
773 
774 
775 /**
776  * @brief Update event state for raw sockets
777  * @param[in] socket Handle referencing the socket
778  **/
779 
781 {
782  //Clear event flags
783  socket->eventFlags = 0;
784 
785  //The socket is marked as readable if a datagram is pending in the queue
786  if(socket->receiveQueue)
787  socket->eventFlags |= SOCKET_EVENT_RX_READY;
788 
789  //Check whether the socket is bound to a particular network interface
790  if(socket->interface != NULL)
791  {
792  //Handle link up and link down events
793  if(socket->interface->linkState)
794  socket->eventFlags |= SOCKET_EVENT_LINK_UP;
795  else
796  socket->eventFlags |= SOCKET_EVENT_LINK_DOWN;
797  }
798 
799  //Mask unused events
800  socket->eventFlags &= socket->eventMask;
801 
802  //Any event to signal?
803  if(socket->eventFlags)
804  {
805  //Unblock I/O operations currently in waiting state
806  osSetEvent(&socket->event);
807 
808  //Set user event to signaled state if necessary
809  if(socket->userEvent != NULL)
810  osSetEvent(socket->userEvent);
811  }
812 }
813 
814 #endif
#define htons(value)
Definition: cpu_endian.h:392
IPv6 (Internet Protocol Version 6)
@ SOCKET_ETH_PROTO_LLC
Definition: socket.h:105
uint8_t length
Definition: dtls_misc.h:149
NetBuffer * ipAllocBuffer(size_t length, size_t *offset)
Allocate a buffer to hold an IP packet.
Definition: ip.c:637
Ipv6PseudoHeader ipv6Data
Definition: ip.h:99
struct _SocketQueueItem SocketQueueItem
Receive queue item.
IP network address.
Definition: ip.h:71
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:672
@ ERROR_INVALID_INTERFACE
Invalid interface.
Definition: error.h:53
uint8_t p
Definition: ndp.h:298
@ SOCKET_FLAG_DONT_ROUTE
Definition: socket.h:119
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
uint16_t srcPort
Definition: socket.h:201
error_t ipv4SelectSourceAddr(NetInterface **interface, Ipv4Addr destAddr, Ipv4Addr *srcAddr)
IPv4 source address selection.
Definition: ipv4_misc.c:163
IpAddr srcIpAddr
Definition: socket.h:200
error_t nicSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet to the network controller.
Definition: nic.c:278
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
#define ipv6CompAddr(ipAddr1, ipAddr2)
Definition: ipv6.h:121
#define ETH_MIN_FRAME_SIZE
Definition: ethernet.h:87
error_t ipSendDatagram(NetInterface *interface, IpPseudoHeader *pseudoHeader, NetBuffer *buffer, size_t offset, uint_t flags)
Send an IP datagram.
Definition: ip.c:59
Ipv4Addr srcIpAddr
Definition: ipcp.h:77
void rawSocketProcessEthPacket(NetInterface *interface, EthHeader *header, const uint8_t *data, size_t length)
Process incoming Ethernet packet.
Definition: raw_socket.c:274
struct _SocketQueueItem * next
Definition: socket.h:199
size_t length
Definition: ip.h:92
uint32_t Ipv4Addr
IPv4 network address.
Definition: ipv4.h:239
@ SOCKET_FLAG_PEEK
Definition: socket.h:118
uint32_t ethCalcCrcEx(const NetBuffer *buffer, size_t offset, size_t length)
Calculate CRC over a multi-part buffer.
IP pseudo header.
Definition: ip.h:90
const IpAddr IP_ADDR_ANY
Definition: ip.c:45
Helper functions for IPv4.
#define htonl(value)
Definition: cpu_endian.h:393
void osResetEvent(OsEvent *event)
Set the specified event object to the nonsignaled state.
error_t
Error codes.
Definition: error.h:42
@ ERROR_PROTOCOL_UNREACHABLE
Definition: error.h:83
#define htole32(value)
Definition: cpu_endian.h:406
#define Ipv6PseudoHeader
Definition: ipv6.h:42
error_t ipv6SelectSourceAddr(NetInterface **interface, const Ipv6Addr *destAddr, Ipv6Addr *srcAddr)
IPv6 source address selection.
Definition: ipv6_misc.c:882
void * netBufferAt(const NetBuffer *buffer, size_t offset)
Returns a pointer to the data at the specified position.
Definition: net_mem.c:413
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
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ SOCKET_EVENT_LINK_DOWN
Definition: socket.h:163
#define NetInterface
Definition: net.h:36
void netBufferFree(NetBuffer *buffer)
Dispose a multi-part buffer.
Definition: net_mem.c:282
NetInterface * netGetDefaultInterface(void)
Get default network interface.
Definition: net.c:1782
Helper functions for IPv6.
OsMutex netMutex
Definition: net.c:75
@ SOCKET_TYPE_RAW_IP
Definition: socket.h:79
__start_packed struct @179 Ipv6Addr
IPv6 network address.
IpAddr destIpAddr
Definition: socket.h:202
#define RAW_SOCKET_RX_QUEUE_SIZE
Definition: raw_socket.h:48
error_t netBufferCopy(NetBuffer *dest, size_t destOffset, const NetBuffer *src, size_t srcOffset, size_t length)
Copy data between multi-part buffers.
Definition: net_mem.c:504
#define Ipv4PseudoHeader
Definition: ipv4.h:39
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
size_t length
Definition: ip.h:73
Socket socketTable[SOCKET_MAX_COUNT]
Definition: socket.c:49
void rawSocketUpdateEvents(Socket *socket)
Update event state for raw sockets.
Definition: raw_socket.c:780
@ SOCKET_EVENT_LINK_UP
Definition: socket.h:162
TCP/IP raw sockets.
NetBuffer * netBufferAlloc(size_t length)
Allocate a multi-part buffer.
Definition: net_mem.c:243
error_t rawSocketSendIpPacket(Socket *socket, const IpAddr *destIpAddr, const void *data, size_t length, size_t *written, uint_t flags)
Send an raw IP packet.
Definition: raw_socket.c:411
#define ntohs(value)
Definition: cpu_endian.h:398
Receive queue item.
Definition: socket.h:197
uint8_t flags
Definition: tcp.h:314
#define TRACE_DEBUG(...)
Definition: debug.h:106
@ ERROR_TIMEOUT
Definition: error.h:94
const uint8_t ethPadding[64]
Definition: ethernet_misc.c:56
Ipv4Addr ipv4Addr
Definition: ip.h:77
error_t rawSocketReceiveIpPacket(Socket *socket, IpAddr *srcIpAddr, IpAddr *destIpAddr, void *data, size_t size, size_t *received, uint_t flags)
Receive an IP packet from a raw socket.
Definition: raw_socket.c:644
error_t rawSocketSendEthPacket(Socket *socket, const void *data, size_t length, size_t *written)
Send an raw Ethernet packet.
Definition: raw_socket.c:524
error_t rawSocketReceiveEthPacket(Socket *socket, void *data, size_t size, size_t *received, uint_t flags)
Receive an Ethernet packet from a raw socket.
Definition: raw_socket.c:718
#define ETH_MTU
Definition: ethernet.h:91
@ SOCKET_EVENT_RX_READY
Definition: socket.h:160
#define ETH_CRC_SIZE
Definition: ethernet.h:93
uint8_t n
bool_t osWaitForEvent(OsEvent *event, systime_t timeout)
Wait until the specified event is in the signaled state.
error_t netBufferAppend(NetBuffer *dest, const void *src, size_t length)
Append data a multi-part buffer.
Definition: net_mem.c:586
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
#define Socket
Definition: socket.h:36
size_t netBufferWrite(NetBuffer *dest, size_t destOffset, const void *src, size_t length)
Write data to a multi-part buffer.
Definition: net_mem.c:619
Socket API.
@ SOCKET_TYPE_RAW_ETH
Definition: socket.h:80
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
@ ERROR_RECEIVE_QUEUE_FULL
Definition: error.h:93
error_t rawSocketProcessIpPacket(NetInterface *interface, IpPseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset)
Process incoming IP packet.
Definition: raw_socket.c:64
IPv4 (Internet Protocol Version 4)
Ipv6Addr ipv6Addr
Definition: ip.h:80
#define PRIuSIZE
Definition: compiler_port.h:78
unsigned int uint_t
Definition: compiler_port.h:45
@ SOCKET_FLAG_DONT_WAIT
Definition: socket.h:121
__start_packed struct @110 EthHeader
Ethernet frame header.
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
#define SOCKET_MAX_COUNT
Definition: socket.h:45
@ SOCKET_ETH_PROTO_ALL
Definition: socket.h:104
Helper functions for Ethernet.
Ipv4PseudoHeader ipv4Data
Definition: ip.h:96
NetBuffer * buffer
Definition: socket.h:203
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
size_t offset
Definition: socket.h:204
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:79
Ipv4Addr destIpAddr
Definition: ipcp.h:78