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