Exemple #1
0
error_t ipv4SelectSourceAddr(NetInterface **interface,
   Ipv4Addr destAddr, Ipv4Addr *srcAddr)
{
   //Use default network interface?
   if(*interface == NULL)
      *interface = netGetDefaultInterface();

   //Select the most appropriate source address
   *srcAddr = (*interface)->ipv4Config.addr;

   //Successful processing
   return NO_ERROR;
}
Exemple #2
0
error_t getHostByName(NetInterface *interface,
   const char_t *name, IpAddr *ipAddr, uint_t flags)
{
   error_t error;

   //Default address type depends on TCP/IP stack configuration
#if (IPV4_SUPPORT == ENABLED)
   HostType type = HOST_TYPE_IPV4;
#elif (IPV6_SUPPORT == ENABLED)
   HostType type = HOST_TYPE_IPV6;
#else
   HostType type = HOST_TYPE_ANY;
#endif

   //Default name resolution protocol depends on TCP/IP stack configuration
#if (DNS_CLIENT_SUPPORT == ENABLED)
   HostnameResolver protocol = HOST_NAME_RESOLVER_DNS;
#elif (MDNS_CLIENT_SUPPORT == ENABLED)
   HostnameResolver protocol = HOST_NAME_RESOLVER_MDNS;
#elif (NBNS_CLIENT_SUPPORT == ENABLED)
   HostnameResolver protocol = HOST_NAME_RESOLVER_NBNS;
#else
   HostnameResolver protocol = HOST_NAME_RESOLVER_ANY;
#endif

   //Check parameters
   if(name == NULL || ipAddr == NULL)
      return ERROR_INVALID_PARAMETER;

   //Use default network interface?
   if(interface == NULL)
      interface = netGetDefaultInterface();

   //The specified name can be either an IP or a host name
   error = ipStringToAddr(name, ipAddr);

   //Perform name resolution if necessary
   if(error)
   {
      //The user may provide a hint to choose between IPv4 and IPv6
      if(flags & HOST_TYPE_IPV4)
         type = HOST_TYPE_IPV4;
      else if(flags & HOST_TYPE_IPV6)
         type = HOST_TYPE_IPV6;

      //The user may provide a hint to to select the desired protocol to be used
      if(flags & HOST_NAME_RESOLVER_DNS)
      {
         //Use DNS to resolve the specified host name
         protocol = HOST_NAME_RESOLVER_DNS;
      }
      else if(flags & HOST_NAME_RESOLVER_MDNS)
      {
         //Use mDNS to resolve the specified host name
         protocol = HOST_NAME_RESOLVER_MDNS;
      }
      else if(flags & HOST_NAME_RESOLVER_NBNS)
      {
         //Use NBNS to resolve the specified host name
         protocol = HOST_NAME_RESOLVER_NBNS;
      }
      else
      {
         //Retrieve the length of the host name to be resolved
         size_t n = strlen(name);

         //Select the most suitable protocol
         if(n >= 6 && !strcasecmp(name + n - 6, ".local"))
         {
#if (MDNS_CLIENT_SUPPORT == ENABLED)
            //Use mDNS to resolve the specified host name
            protocol = HOST_NAME_RESOLVER_MDNS;
#endif
         }
         else if(n <= 15 && !strchr(name, '.') && type == HOST_TYPE_IPV4)
         {
#if (NBNS_CLIENT_SUPPORT == ENABLED)
            //Use NetBIOS Name Service to resolve the specified host name
            protocol = HOST_NAME_RESOLVER_NBNS;
#endif
         }
      }

#if (DNS_CLIENT_SUPPORT == ENABLED)
      //Use DNS protocol?
      if(protocol == HOST_NAME_RESOLVER_DNS)
      {
         //Perform host name resolution
         error = dnsResolve(interface, name, type, ipAddr);
      }
      else
#endif
#if (MDNS_CLIENT_SUPPORT == ENABLED)
      //Use mDNS protocol?
      if(protocol == HOST_NAME_RESOLVER_MDNS)
      {
         //Perform host name resolution
         error = mdnsResolve(interface, name, type, ipAddr);
      }
      else
#endif
#if (NBNS_CLIENT_SUPPORT == ENABLED && IPV4_SUPPORT == ENABLED)
      //Use NetBIOS Name Service protocol?
      if(protocol == HOST_NAME_RESOLVER_NBNS)
      {
         //Perform host name resolution
         error = nbnsResolve(interface, name, ipAddr);
      }
      else
#endif
      //Invalid protocol?
      {
         //Report an error
         error = ERROR_INVALID_PARAMETER;
      }
   }

   //Return status code
   return error;
}
Exemple #3
0
error_t rawSocketSendEthPacket(Socket *socket,
   const void *data, size_t length, size_t *written)
{
   error_t error;
   uint32_t crc;
   NetBuffer *buffer;
   NetInterface *interface;

   //Select the relevant network interface
   if(!socket->interface)
      interface = netGetDefaultInterface();
   else
      interface = socket->interface;

   //Allocate a buffer memory to hold the raw Ethernet packet
   buffer = netBufferAlloc(0);
   //Failed to allocate buffer?
   if(!buffer) return ERROR_OUT_OF_MEMORY;

   //Copy the raw data
   error = netBufferAppend(buffer, data, length);

   //Successful processing?
   if(!error)
   {
      //Automatic padding not supported by hardware?
      if(!interface->nicDriver->autoPadding)
      {
         //The host controller should manually add padding
         //to the packet before transmitting it
         if(length < (ETH_MIN_FRAME_SIZE - ETH_CRC_SIZE))
         {
            //Add padding as necessary
            size_t n = (ETH_MIN_FRAME_SIZE - ETH_CRC_SIZE) - length;

            //Append padding bytes
            error = netBufferAppend(buffer, ethPadding, n);
            //Any error to report?
            if(error) return error;

            //Adjust frame length
            length += n;
         }
      }
      //CRC generation not supported by hardware?
      if(!interface->nicDriver->autoCrcGen)
      {
         //Compute CRC over the header and payload
         crc = ethCalcCrcEx(buffer, 0, length);
         //Convert from host byte order to little-endian byte order
         crc = htole32(crc);

         //Append the calculated CRC value
         error = netBufferAppend(buffer, &crc, sizeof(crc));
         //Any error to report?
         if(error) return error;

         //Adjust frame length
         length += sizeof(crc);
      }

      //Debug message
      TRACE_DEBUG("Sending raw Ethernet frame (%" PRIuSIZE " bytes)...\r\n", length);

      //Send the resulting packet over the specified link
      error = nicSendPacket(interface, buffer, 0);
   }

   //Successful processing?
   if(!error)
   {
      //Total number of bytes successfully transmitted
      if(written != NULL)
         *written = length;
   }

   //Free previously allocated memory block
   netBufferFree(buffer);
   //Return status code
   return error;
}
 error_t sntpClientGetTimestamp(NetInterface *interface,
   const IpAddr *serverIpAddr, NtpTimestamp *timestamp)
{
   error_t error;
   uint_t i;
   systime_t timeout;
   SntpClientContext context;

   //Check parameters
   if(serverIpAddr == NULL || timestamp == NULL)
      return ERROR_INVALID_PARAMETER;

   //Use default network interface?
   if(!interface)
      interface = netGetDefaultInterface();

   //Open a UDP socket
   context.socket = socketOpen(SOCKET_TYPE_DGRAM, SOCKET_IP_PROTO_UDP);
   //Failed to open socket?
   if(!context.socket)
      return ERROR_OPEN_FAILED;

   //Associate the socket with the relevant interface
   error = socketBindToInterface(context.socket, interface);
   //Any error to report?
   if(error)
   {
      //Close socket
      socketClose(context.socket);
      //Return status code
      return error;
   }

   //Only accept datagrams from the specified NTP server
   error = socketConnect(context.socket, serverIpAddr, NTP_PORT);
   //Any error to report?
   if(error)
   {
      //Close socket
      socketClose(context.socket);
      //Return status code
      return error;
   }

   //Initial timeout value
   timeout = SNTP_CLIENT_INIT_TIMEOUT;

   //Retransmission loop
   for(i = 0; i < SNTP_CLIENT_MAX_RETRIES; i++)
   {
      //Send NTP request message
      error = sntpSendRequest(&context);
      //Failed to send message ?
      if(error) break;

      //Wait for a valid NTP response message
      error = sntpWaitForResponse(&context, timeout);
      //Valid NTP response received?
      if(!error) break;

      //The timeout value is doubled for each subsequent retransmission
      timeout = MIN(timeout * 2, SNTP_CLIENT_MAX_TIMEOUT);
   }

   //Successful processing?
   if(!error)
   {
      //Save server timestamp
      timestamp->seconds = ntohl(context.message.transmitTimestamp.seconds);
      timestamp->fraction = ntohl(context.message.transmitTimestamp.fraction);
   }

   //Close socket
   socketClose(context.socket);
   //Return status code
   return error;
}