Ejemplo n.º 1
0
error_t rawSocketReceiveIpPacket(Socket *socket, IpAddr *srcIpAddr,
   IpAddr *destIpAddr, void *data, size_t size, size_t *received, uint_t flags)
{
   SocketQueueItem *queueItem;

   //The receive queue is empty?
   if(!socket->receiveQueue)
   {
      //Set the events the application is interested in
      socket->eventMask = SOCKET_EVENT_RX_READY;
      //Reset the event object
      osResetEvent(&socket->event);
      //Leave critical section
      osReleaseMutex(&socketMutex);
      //Wait until an event is triggered
      osWaitForEvent(&socket->event, socket->timeout);
      //Enter critical section
      osAcquireMutex(&socketMutex);
   }

   //Check whether the read operation timed out
   if(!socket->receiveQueue)
   {
      //No data can be read
      *received = 0;
      //Report a timeout error
      return ERROR_TIMEOUT;
   }

   //Point to the first item in the receive queue
   queueItem = socket->receiveQueue;
   //Copy data to user buffer
   *received = chunkedBufferRead(data, queueItem->buffer, queueItem->offset, size);

   //Save the source IP address
   if(srcIpAddr)
      *srcIpAddr = queueItem->srcIpAddr;
   //Save the destination IP address
   if(destIpAddr)
      *destIpAddr = queueItem->destIpAddr;

   //If the SOCKET_FLAG_PEEK flag is set, the data is copied
   //into the buffer but is not removed from the input queue
   if(!(flags & SOCKET_FLAG_PEEK))
   {
      //Remove the item from the receive queue
      socket->receiveQueue = queueItem->next;
      //Deallocate memory buffer
      chunkedBufferFree(queueItem->buffer);
   }

   //Update the state of events
   rawSocketUpdateEvents(socket);

   //Successful read operation
   return NO_ERROR;
}
Ejemplo n.º 2
0
error_t socketRegisterEvents(Socket *socket, OsEvent *event, uint_t eventMask)
{
   //Make sure the socket handle is valid
   if(!socket)
      return ERROR_INVALID_PARAMETER;

   //Enter critical section
   osAcquireMutex(&socketMutex);

   //An user event may have been previously registered...
   if(socket->userEvent != NULL)
      socket->eventMask |= eventMask;
   else
      socket->eventMask = eventMask;

   //Suscribe to get notified of events
   socket->userEvent = event;

#if (TCP_SUPPORT == ENABLED)
   //Handle TCP specific events
   if(socket->type == SOCKET_TYPE_STREAM)
   {
      tcpUpdateEvents(socket);
   }
#endif
#if (UDP_SUPPORT == ENABLED)
   //Handle UDP specific events
   if(socket->type == SOCKET_TYPE_DGRAM)
   {
      udpUpdateEvents(socket);
   }
#endif
#if (RAW_SOCKET_SUPPORT == ENABLED)
   //Handle events that are specific to raw sockets
   if(socket->type == SOCKET_TYPE_RAW_IP ||
      socket->type == SOCKET_TYPE_RAW_ETH)
   {
      rawSocketUpdateEvents(socket);
   }
#endif

   //Leave critical section
   osReleaseMutex(&socketMutex);
   //Successful processing
   return NO_ERROR;
}
Ejemplo n.º 3
0
error_t rawSocketProcessIpPacket(NetInterface *interface,
   IpPseudoHeader *pseudoHeader, const NetBuffer *buffer, size_t offset)
{
   uint_t i;
   size_t length;
   Socket *socket;
   SocketQueueItem *queueItem;
   NetBuffer *p;

   //Retrieve the length of the raw IP packet
   length = netBufferGetLength(buffer) - offset;

   //Enter critical section
   osAcquireMutex(&socketMutex);

   //Loop through opened sockets
   for(i = 0; i < SOCKET_MAX_COUNT; i++)
   {
      //Point to the current socket
      socket = socketTable + i;

      //Raw socket found?
      if(socket->type != SOCKET_TYPE_RAW_IP)
         continue;
      //Check whether the socket is bound to a particular interface
      if(socket->interface && socket->interface != interface)
         continue;

#if (IPV4_SUPPORT == ENABLED)
      //An IPv4 packet was received?
      if(pseudoHeader->length == sizeof(Ipv4PseudoHeader))
      {
         //Check protocol field
         if(socket->protocol != pseudoHeader->ipv4Data.protocol)
            continue;
         //Destination IP address filtering
         if(socket->localIpAddr.length)
         {
            //An IPv4 address is expected
            if(socket->localIpAddr.length != sizeof(Ipv4Addr))
               continue;
            //Filter out non-matching addresses
            if(socket->localIpAddr.ipv4Addr != pseudoHeader->ipv4Data.destAddr)
               continue;
         }
         //Source IP address filtering
         if(socket->remoteIpAddr.length)
         {
            //An IPv4 address is expected
            if(socket->remoteIpAddr.length != sizeof(Ipv4Addr))
               continue;
            //Filter out non-matching addresses
            if(socket->remoteIpAddr.ipv4Addr != pseudoHeader->ipv4Data.srcAddr)
               continue;
         }
      }
      else
#endif
#if (IPV6_SUPPORT == ENABLED)
      //An IPv6 packet was received?
      if(pseudoHeader->length == sizeof(Ipv6PseudoHeader))
      {
         //Check protocol field
         if(socket->protocol != pseudoHeader->ipv6Data.nextHeader)
            continue;
         //Destination IP address filtering
         if(socket->localIpAddr.length)
         {
            //An IPv6 address is expected
            if(socket->localIpAddr.length != sizeof(Ipv6Addr))
               continue;
            //Filter out non-matching addresses
            if(!ipv6CompAddr(&socket->localIpAddr.ipv6Addr, &pseudoHeader->ipv6Data.destAddr))
               continue;
         }
         //Source IP address filtering
         if(socket->remoteIpAddr.length)
         {
            //An IPv6 address is expected
            if(socket->remoteIpAddr.length != sizeof(Ipv6Addr))
               continue;
            //Filter out non-matching addresses
            if(!ipv6CompAddr(&socket->remoteIpAddr.ipv6Addr, &pseudoHeader->ipv6Data.srcAddr))
               continue;
         }
      }
      else
#endif
      //An invalid packet was received?
      {
         //This should never occur...
         continue;
      }

      //The current socket meets all the criteria
      break;
   }

   //Drop incoming packet if no matching socket was found
   if(i >= SOCKET_MAX_COUNT)
   {
      //Leave critical section
      osReleaseMutex(&socketMutex);
      //Unreachable protocol...
      return ERROR_PROTOCOL_UNREACHABLE;
   }

   //Empty receive queue?
   if(!socket->receiveQueue)
   {
      //Allocate a memory buffer to hold the data and the associated descriptor
      p = netBufferAlloc(sizeof(SocketQueueItem) + length);

      //Successful memory allocation?
      if(p != NULL)
      {
         //Point to the newly created item
         queueItem = netBufferAt(p, 0);
         queueItem->buffer = p;
         //Add the newly created item to the queue
         socket->receiveQueue = queueItem;
      }
      else
      {
         //Memory allocation failed
         queueItem = NULL;
      }
   }
   else
   {
      //Point to the very first item
      queueItem = socket->receiveQueue;
      //Reach the last item in the receive queue
      for(i = 1; queueItem->next; i++)
         queueItem = queueItem->next;

      //Make sure the receive queue is not full
      if(i >= RAW_SOCKET_RX_QUEUE_SIZE)
      {
         //Leave critical section
         osReleaseMutex(&socketMutex);
         //Notify the calling function that the queue is full
         return ERROR_RECEIVE_QUEUE_FULL;
      }

      //Allocate a memory buffer to hold the data and the associated descriptor
      p = netBufferAlloc(sizeof(SocketQueueItem) + length);

      //Successful memory allocation?
      if(p != NULL)
      {
         //Add the newly created item to the queue
         queueItem->next = netBufferAt(p, 0);
         //Point to the newly created item
         queueItem = queueItem->next;
         queueItem->buffer = p;
      }
      else
      {
         //Memory allocation failed
         queueItem = NULL;
      }
   }

   //Failed to allocate memory?
   if(!queueItem)
   {
      //Leave critical section
      osReleaseMutex(&socketMutex);
      //Return error code
      return ERROR_OUT_OF_MEMORY;
   }

   //Initialize next field
   queueItem->next = NULL;
   //Port number is unused
   queueItem->srcPort = 0;

#if (IPV4_SUPPORT == ENABLED)
   //IPv4 remote address?
   if(pseudoHeader->length == sizeof(Ipv4PseudoHeader))
   {
      //Save the source IPv4 address
      queueItem->srcIpAddr.length = sizeof(Ipv4Addr);
      queueItem->srcIpAddr.ipv4Addr = pseudoHeader->ipv4Data.srcAddr;
      //Save the destination IPv4 address
      queueItem->destIpAddr.length = sizeof(Ipv4Addr);
      queueItem->destIpAddr.ipv4Addr = pseudoHeader->ipv4Data.destAddr;
   }
#endif
#if (IPV6_SUPPORT == ENABLED)
   //IPv6 remote address?
   if(pseudoHeader->length == sizeof(Ipv6PseudoHeader))
   {
      //Save the source IPv6 address
      queueItem->srcIpAddr.length = sizeof(Ipv6Addr);
      queueItem->srcIpAddr.ipv6Addr = pseudoHeader->ipv6Data.srcAddr;
      //Save the destination IPv6 address
      queueItem->destIpAddr.length = sizeof(Ipv6Addr);
      queueItem->destIpAddr.ipv6Addr = pseudoHeader->ipv6Data.destAddr;
   }
#endif

   //Offset to the raw IP packet
   queueItem->offset = sizeof(SocketQueueItem);
   //Copy the raw data
   netBufferCopy(queueItem->buffer, queueItem->offset, buffer, offset, length);

   //Notify user that data is available
   rawSocketUpdateEvents(socket);

   //Leave critical section
   osReleaseMutex(&socketMutex);
   //Successful processing
   return NO_ERROR;
}
Ejemplo n.º 4
0
void rawSocketProcessEthPacket(NetInterface *interface,
   EthHeader *ethFrame, size_t length)
{
   uint_t i;
   Socket *socket;
   SocketQueueItem *queueItem;
   NetBuffer *p;

   //Enter critical section
   osAcquireMutex(&socketMutex);

   //Loop through opened sockets
   for(i = 0; i < SOCKET_MAX_COUNT; i++)
   {
      //Point to the current socket
      socket = socketTable + i;

      //Raw socket found?
      if(socket->type != SOCKET_TYPE_RAW_ETH)
         continue;
      //Check whether the socket is bound to a particular interface
      if(socket->interface && socket->interface != interface)
         continue;
      //Check protocol field
      if(socket->protocol != SOCKET_ETH_PROTO_ALL && socket->protocol != ntohs(ethFrame->type))
         continue;

      //The current socket meets all the criteria
      break;
   }

   //Drop incoming packet if no matching socket was found
   if(i >= SOCKET_MAX_COUNT)
   {
      //Leave critical section
      osReleaseMutex(&socketMutex);
      //Return immediately
      return;
   }

   //Empty receive queue?
   if(!socket->receiveQueue)
   {
      //Allocate a memory buffer to hold the data and the associated descriptor
      p = netBufferAlloc(sizeof(SocketQueueItem) + length);

      //Successful memory allocation?
      if(p != NULL)
      {
         //Point to the newly created item
         queueItem = netBufferAt(p, 0);
         queueItem->buffer = p;
         //Add the newly created item to the queue
         socket->receiveQueue = queueItem;
      }
      else
      {
         //Memory allocation failed
         queueItem = NULL;
      }
   }
   else
   {
      //Point to the very first item
      queueItem = socket->receiveQueue;
      //Reach the last item in the receive queue
      for(i = 1; queueItem->next; i++)
         queueItem = queueItem->next;

      //Make sure the receive queue is not full
      if(i >= RAW_SOCKET_RX_QUEUE_SIZE)
      {
         //Leave critical section
         osReleaseMutex(&socketMutex);
         //Return immediately
         return;
      }

      //Allocate a memory buffer to hold the data and the associated descriptor
      p = netBufferAlloc(sizeof(SocketQueueItem) + length);

      //Successful memory allocation?
      if(p != NULL)
      {
         //Add the newly created item to the queue
         queueItem->next = netBufferAt(p, 0);
         //Point to the newly created item
         queueItem = queueItem->next;
         queueItem->buffer = p;
      }
      else
      {
         //Memory allocation failed
         queueItem = NULL;
      }
   }

   //Failed to allocate memory?
   if(!queueItem)
   {
      //Leave critical section
      osReleaseMutex(&socketMutex);
      //Return immediately
      return;
   }

   //Initialize next field
   queueItem->next = NULL;
   //Other fields are meaningless
   queueItem->srcPort = 0;
   queueItem->srcIpAddr = IP_ADDR_ANY;
   queueItem->destIpAddr = IP_ADDR_ANY;

   //Offset to the raw datagram
   queueItem->offset = sizeof(SocketQueueItem);
   //Copy the raw data
   netBufferWrite(queueItem->buffer, queueItem->offset, ethFrame, length);

   //Notify user that data is available
   rawSocketUpdateEvents(socket);

   //Leave critical section
   osReleaseMutex(&socketMutex);
}