Exemple #1
0
void arpDumpPacket(const ArpPacket *arpPacket)
{
   //Dump ARP packet contents
   TRACE_DEBUG("  Hardware Type (hrd) = 0x%04X\r\n", ntohs(arpPacket->hrd));
   TRACE_DEBUG("  Protocol Type (pro) = 0x%04X\r\n", ntohs(arpPacket->pro));
   TRACE_DEBUG("  Hardware Address Length (hln) = %u\r\n", arpPacket->hln);
   TRACE_DEBUG("  Protocol Address Length (pln) = %u\r\n", arpPacket->pln);
   TRACE_DEBUG("  Opcode (op) = %u\r\n", ntohs(arpPacket->op));
   TRACE_DEBUG("  Sender Hardware Address (sha)= %s\r\n", macAddrToString(&arpPacket->sha, NULL));
   TRACE_DEBUG("  Sender Protocol Address (spa) = %s\r\n", ipv4AddrToString(arpPacket->spa, NULL));
   TRACE_DEBUG("  Target Hardware Address (tha)= %s\r\n", macAddrToString(&arpPacket->tha, NULL));
   TRACE_DEBUG("  Target Protocol Address (tpa) = %s\r\n", ipv4AddrToString(arpPacket->tpa, NULL));
}
Exemple #2
0
error_t rza1EthSetMacFilter(NetInterface *interface)
{
   uint_t i;
   volatile uint32_t *addressHigh;
   volatile uint32_t *addressLow;

   //Debug message
   TRACE_INFO("Updating RZ/A1 CAM entry table...\r\n");

   //Disable all CAM entries
   ETHER.TSU_TEN = 0;

   //The MAC filter table contains the multicast MAC addresses
   //to accept when receiving an Ethernet frame
   for(i = 0; i < interface->macFilterSize && i < 32; i++)
   {
      //Point to the current MAC address
      MacAddr *macAddr = &interface->macFilter[i].addr;

      //Debug message
      TRACE_INFO("  %s\r\n", macAddrToString(macAddr, NULL));

      //Point to the CAM entry registers
      addressHigh = &ETHER.TSU_ADRH0 + 2 * i;
      addressLow = &ETHER.TSU_ADRL0 + 2 * i;

      //The contents of the CAM entry table registers cannot be
      //modified while the ADSBSY flag is set
      while(ETHER.TSU_ADSBSY & ETHER_TSU_ADSBSY_ADSBSY);

      //Set the upper 32 bits of the MAC address
      *addressHigh = (macAddr->b[0] << 24) | (macAddr->b[1] << 16) |
         (macAddr->b[2] << 8) | macAddr->b[3];

      //Wait for the ADSBSY flag to be cleared
      while(ETHER.TSU_ADSBSY & ETHER_TSU_ADSBSY_ADSBSY);

      //Set the lower 16 bits of the MAC address
      *addressLow = (macAddr->b[4] << 8) | macAddr->b[5];

      //Enable the CAM entry
      ETHER.TSU_TEN |= 1 << (31 - i);
   }

   //Successful processing
   return NO_ERROR;
}
Exemple #3
0
void ndpProcessNeighborAdv(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader,
   const ChunkedBuffer *buffer, size_t offset, uint8_t hopLimit)
{
   size_t length;
   NdpNeighborAdvMessage *message;
   NdpLinkLayerAddrOption *option;
   NdpCacheEntry *entry;

   //Retrieve the length of the message
   length = chunkedBufferGetLength(buffer) - offset;

   //Check the length of the Neighbor Advertisement message
   if(length < sizeof(NdpNeighborAdvMessage))
      return;

   //Point to the beginning of the message
   message = chunkedBufferAt(buffer, offset);
   //Sanity check
   if(!message) return;

   //Debug message
   TRACE_INFO("Neighbor Advertisement message received (%" PRIuSIZE " bytes)...\r\n", length);
   //Dump message contents for debugging purpose
   ndpDumpNeighborAdvMessage(message);

   //The IPv6 Hop Limit field must have a value of 255 to ensure
   //that the packet has not been forwarded by a router
   if(hopLimit != NDP_HOP_LIMIT)
      return;

   //ICMPv6 Code must be 0
   if(message->code)
      return;

   //Check whether the target address is tentative or matches
   //a unicast address assigned to the interface
   if(ipv6CompAddr(&message->targetAddr, &interface->ipv6Config.linkLocalAddr) &&
      interface->ipv6Config.linkLocalAddrState != IPV6_ADDR_STATE_INVALID)
   {
      //Debug message
      TRACE_WARNING("The address %s is a duplicate!\r\n",
         ipv6AddrToString(&interface->ipv6Config.linkLocalAddr, NULL));

      //The address is a duplicate and should not be used
      interface->ipv6Config.linkLocalAddrDup = TRUE;
      //Exit immediately
      return;
   }
   else if(ipv6CompAddr(&message->targetAddr, &interface->ipv6Config.globalAddr) &&
      interface->ipv6Config.globalAddrState != IPV6_ADDR_STATE_INVALID)
   {
      //Debug message
      TRACE_WARNING("The address %s is a duplicate!\r\n",
         ipv6AddrToString(&interface->ipv6Config.globalAddr, NULL));

      //The address is a duplicate and should not be used
      interface->ipv6Config.globalAddrDup = TRUE;
      //Exit immediately
      return;
   }

   //The target address must not be a multicast address
   if(ipv6IsMulticastAddr(&message->targetAddr))
   {
      //Debug message
      TRACE_WARNING("Target address must not be a multicast address!\r\n");
      //Exit immediately
      return;
   }

   //If the destination address is a multicast address
   //then the Solicited flag must be zero
   if(ipv6IsMulticastAddr(&pseudoHeader->destAddr) && message->s)
   {
      //Debug message
      TRACE_WARNING("Solicited flag must be zero!\r\n");
      //Exit immediately
      return;
   }

   //Calculate the length of the Options field
   length -= sizeof(NdpNeighborSolMessage);
   //Search for the Target Link-Layer Address option
   option = ndpGetOption(message->options, length, NDP_OPT_TARGET_LINK_LAYER_ADDR);

   //Source Link-Layer Address option found?
   if(option && option->length == 1)
   {
      //Debug message
      TRACE_DEBUG("  Target Link-Layer Address = %s\r\n",
         macAddrToString(&option->linkLayerAddr, NULL));

      //Acquire exclusive access to Neighbor cache
      osAcquireMutex(&interface->ndpCacheMutex);

      //Search the Neighbor cache for the specified target address
      entry = ndpFindEntry(interface, &message->targetAddr);

      //If no entry exists, the advertisement should be silently discarded
      if(entry)
      {
         //INCOMPLETE state?
         if(entry->state == NDP_STATE_INCOMPLETE)
         {
            //Record link-layer address
            entry->macAddr = option->linkLayerAddr;
            //Send all the packets that are pending for transmission
            ndpSendQueuedPackets(interface, entry);
            //Save current time
            entry->timestamp = osGetSystemTime();

            //Solicited flag is set?
            if(message->s)
            {
               //Computing the random ReachableTime value
               entry->timeout = NDP_REACHABLE_TIME;
               //Switch to the REACHABLE state
               entry->state = NDP_STATE_REACHABLE;
            }
            //Solicited flag is cleared?
            else
            {
               //Enter the STALE state
               entry->state = NDP_STATE_STALE;
            }
         }
         //REACHABLE, STALE, DELAY or PROBE state?
         else
         {
            //Solicited flag is set and Override flag is cleared?
            if(message->s && !message->o)
            {
               //Same link-layer address than cached?
               if(macCompAddr(&entry->macAddr, &option->linkLayerAddr))
               {
                  //Save current time
                  entry->timestamp = osGetSystemTime();
                  //Computing the random ReachableTime value
                  entry->timeout = NDP_REACHABLE_TIME;
                  //Switch to the REACHABLE state
                  entry->state = NDP_STATE_REACHABLE;
               }
               //Different link-layer address than cached?
               else
               {
                  //REACHABLE state?
                  if(entry->state == NDP_STATE_REACHABLE)
                  {
                     //Save current time
                     entry->timestamp = osGetSystemTime();
                     //Enter the STALE state
                     entry->state = NDP_STATE_STALE;
                  }
               }
            }
            //Both Solicited and Override flags are set?
            else if(message->s && message->o)
            {
               //Record link-layer address (if different)
               entry->macAddr = option->linkLayerAddr;
               //Save current time
               entry->timestamp = osGetSystemTime();
               //Computing the random ReachableTime value
               entry->timeout = NDP_REACHABLE_TIME;
               //Switch to the REACHABLE state
               entry->state = NDP_STATE_REACHABLE;
            }
            //Solicited flag is cleared and Override flag is set?
            else if(!message->s && message->o)
            {
               //Different link-layer address than cached?
               if(!macCompAddr(&entry->macAddr, &option->linkLayerAddr))
               {
                  //Record link-layer address
                  entry->macAddr = option->linkLayerAddr;
                  //Save current time
                  entry->timestamp = osGetSystemTime();
                  //Enter the STALE state
                  entry->state = NDP_STATE_STALE;
               }
            }
         }
      }
   }
   //Source Link-Layer Address option not found?
   else
   {
      //Update content of IsRouter flag
   }

   //Release exclusive access to Neighbor cache
   osReleaseMutex(&interface->ndpCacheMutex);
}
Exemple #4
0
void ndpProcessNeighborSol(NetInterface *interface, Ipv6PseudoHeader *pseudoHeader,
   const ChunkedBuffer *buffer, size_t offset, uint8_t hopLimit)
{
   size_t length;
   NdpNeighborSolMessage *message;
   NdpLinkLayerAddrOption *option;
   NdpCacheEntry *entry;

   //Retrieve the length of the message
   length = chunkedBufferGetLength(buffer) - offset;

   //Check the length of the Neighbor Solicitation message
   if(length < sizeof(NdpNeighborSolMessage))
      return;

   //Point to the beginning of the message
   message = chunkedBufferAt(buffer, offset);
   //Sanity check
   if(!message) return;

   //Debug message
   TRACE_INFO("Neighbor Solicitation message received (%" PRIuSIZE " bytes)...\r\n", length);
   //Dump message contents for debugging purpose
   ndpDumpNeighborSolMessage(message);

   //The IPv6 Hop Limit field must have a value of 255 to ensure
   //that the packet has not been forwarded by a router
   if(hopLimit != NDP_HOP_LIMIT)
      return;

   //ICMPv6 Code must be 0
   if(message->code)
      return;

   //The target address must a valid unicast address assigned to the interface
   //or a tentative address on which DAD is being performed
   if(ipv6CompAddr(&message->targetAddr, &interface->ipv6Config.linkLocalAddr))
   {
      //Check whether the target address is tentative
      if(interface->ipv6Config.linkLocalAddrState == IPV6_ADDR_STATE_TENTATIVE)
      {
         //If the source address of the Neighbor Solicitation is the unspecified
         //address, the solicitation is from a node performing Duplicate Address
         //Detection
         if(ipv6CompAddr(&pseudoHeader->srcAddr, &IPV6_UNSPECIFIED_ADDR))
         {
            //Debug message
            TRACE_WARNING("The tentative address %s is a duplicate!\r\n",
               ipv6AddrToString(&interface->ipv6Config.linkLocalAddr, NULL));

            //The tentative address is a duplicate and should not be used
            interface->ipv6Config.linkLocalAddrDup = TRUE;
         }

         //In all cases, a node must not respond to a Neighbor Solicitation
         //for a tentative address
         return;
      }
   }
   else if(ipv6CompAddr(&message->targetAddr, &interface->ipv6Config.globalAddr))
   {
      //Check whether the target address is tentative
      if(interface->ipv6Config.globalAddrState == IPV6_ADDR_STATE_TENTATIVE)
      {
         //If the source address of the Neighbor Solicitation is the unspecified
         //address, the solicitation is from a node performing Duplicate Address
         //Detection
         if(ipv6CompAddr(&pseudoHeader->srcAddr, &IPV6_UNSPECIFIED_ADDR))
         {
            //Debug message
            TRACE_WARNING("The tentative address %s is a duplicate!\r\n",
               ipv6AddrToString(&interface->ipv6Config.globalAddr, NULL));

            //The tentative address is a duplicate and should not be used
            interface->ipv6Config.globalAddrDup = TRUE;
         }

         //In all cases, a node must not respond to a Neighbor Solicitation
         //for a tentative address
         return;
      }
   }
   else
   {
      //Debug message
      TRACE_WARNING("Wrong target address!\r\n");
      //Exit immediately
      return;
   }

   //If the IP source address is the unspecified address, the IP
   //destination address must be a solicited-node multicast address
   if(ipv6CompAddr(&pseudoHeader->srcAddr, &IPV6_UNSPECIFIED_ADDR) &&
      !ipv6IsSolicitedNodeAddr(&pseudoHeader->destAddr))
   {
      //Debug message
      TRACE_WARNING("Destination address must be a solicited-node address!\r\n");
      //Exit immediately
      return;
   }

   //Calculate the length of the Options field
   length -= sizeof(NdpNeighborSolMessage);
   //Search for the Source Link-Layer Address option
   option = ndpGetOption(message->options, length, NDP_OPT_SOURCE_LINK_LAYER_ADDR);

   //Source Link-Layer Address option found?
   if(option && option->length == 1)
   {
      //Debug message
      TRACE_DEBUG("  Source Link-Layer Address = %s\r\n",
         macAddrToString(&option->linkLayerAddr, NULL));

      //If the Source Address is not the unspecified address, then the Neighbor
      //cache should be updated for the IP source address of the solicitation
      if(ipv6CompAddr(&pseudoHeader->srcAddr, &IPV6_UNSPECIFIED_ADDR))
         return;

      //Acquire exclusive access to Neighbor cache
      osAcquireMutex(&interface->ndpCacheMutex);

      //Search the Neighbor cache for the source address of the solicitation
      entry = ndpFindEntry(interface, &pseudoHeader->srcAddr);

      //No matching entry has been found?
      if(!entry)
      {
         //Create an entry
         entry = ndpCreateEntry(interface);

         //Neighbor cache entry successfully created?
         if(entry)
         {
            //Record the IPv6 and the corresponding MAC address
            entry->ipAddr = pseudoHeader->srcAddr;
            entry->macAddr = option->linkLayerAddr;
            //Save current time
            entry->timestamp = osGetSystemTime();
            //Enter the STALE state
            entry->state = NDP_STATE_STALE;
         }
      }
      else
      {
         //INCOMPLETE state?
         if(entry->state == NDP_STATE_INCOMPLETE)
         {
            //Record link-layer address
            entry->macAddr = option->linkLayerAddr;
            //Send all the packets that are pending for transmission
            ndpSendQueuedPackets(interface, entry);
            //Save current time
            entry->timestamp = osGetSystemTime();
            //Enter the STALE state
            entry->state = NDP_STATE_STALE;
         }
         //REACHABLE, STALE, DELAY or PROBE state?
         else
         {
            //Different link-layer address than cached?
            if(!macCompAddr(&entry->macAddr, &option->linkLayerAddr))
            {
               //Update link-layer address
               entry->macAddr = option->linkLayerAddr;
               //Save current time
               entry->timestamp = osGetSystemTime();
               //Enter the STALE state
               entry->state = NDP_STATE_STALE;
            }
         }
      }

      //Release exclusive access to Neighbor cache
      osReleaseMutex(&interface->ndpCacheMutex);
   }
   //Source Link-Layer Address option not found?
   else
   {
      //This option must be included in multicast solicitations
      if(ipv6IsMulticastAddr(&pseudoHeader->destAddr))
      {
         //Debug message
         TRACE_WARNING("The Source Link-Layer Address must be included!\r\n");
         //Exit immediately
         return;
      }
   }

   //After any updates to the Neighbor cache, the node sends a Neighbor
   //Advertisement response as described in RFC 4861 7.2.4
   ndpSendNeighborAdv(interface, &message->targetAddr, &pseudoHeader->srcAddr);
}
Exemple #5
0
error_t httpServerCgiCallback(HttpConnection *connection,
   const char_t *param)
{
   static uint_t pageCounter = 0;
   uint_t length;
   MacAddr macAddr;
#if (IPV4_SUPPORT == ENABLED)
   Ipv4Addr ipv4Addr;
#endif
#if (IPV6_SUPPORT == ENABLED)
   uint_t n;
   Ipv6Addr ipv6Addr;
#endif

   //Underlying network interface
   NetInterface *interface = connection->socket->interface;

   //Check parameter name
   if(!strcasecmp(param, "PAGE_COUNTER"))
   {
      pageCounter++;
      sprintf(connection->buffer, "%u time%s", pageCounter, (pageCounter >= 2) ? "s" : "");
   }
   else if(!strcasecmp(param, "BOARD_NAME"))
   {
      strcpy(connection->buffer, "SAM7SE-EK");
   }
   else if(!strcasecmp(param, "SYSTEM_TIME"))
   {
      systime_t time = osGetSystemTime();
      formatSystemTime(time, connection->buffer);
   }
   else if(!strcasecmp(param, "MAC_ADDR"))
   {
      netGetMacAddr(interface, &macAddr);
      macAddrToString(&macAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_ADDR"))
   {
      ipv4GetHostAddr(interface, &ipv4Addr);
      ipv4AddrToString(ipv4Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "SUBNET_MASK"))
   {
      ipv4GetSubnetMask(interface, &ipv4Addr);
      ipv4AddrToString(ipv4Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "DEFAULT_GATEWAY"))
   {
      ipv4GetDefaultGateway(interface, &ipv4Addr);
      ipv4AddrToString(ipv4Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_PRIMARY_DNS"))
   {
      ipv4GetDnsServer(interface, 0, &ipv4Addr);
      ipv4AddrToString(ipv4Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_SECONDARY_DNS"))
   {
      ipv4GetDnsServer(interface, 1, &ipv4Addr);
      ipv4AddrToString(ipv4Addr, connection->buffer);
   }
#if (IPV6_SUPPORT == ENABLED)
   else if(!strcasecmp(param, "LINK_LOCAL_ADDR"))
   {
      ipv6GetLinkLocalAddr(interface, &ipv6Addr);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "GLOBAL_ADDR"))
   {
      ipv6GetGlobalAddr(interface, 0, &ipv6Addr);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PREFIX"))
   {
      ipv6GetPrefix(interface, 0, &ipv6Addr, &n);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
      length = strlen(connection->buffer);
      sprintf(connection->buffer + length, "/%u", n);
   }
   else if(!strcasecmp(param, "ROUTER"))
   {
      ipv6GetDefaultRouter(interface, 0, &ipv6Addr);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PRIMARY_DNS"))
   {
      ipv6GetDnsServer(interface, 0, &ipv6Addr);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_SECONDARY_DNS"))
   {
      ipv6GetDnsServer(interface, 1, &ipv6Addr);
      ipv6AddrToString(&ipv6Addr, connection->buffer);
   }
#endif
   else
   {
      return ERROR_INVALID_TAG;
   }

   //Get the length of the resulting string
   length = strlen(connection->buffer);

   //Send the contents of the specified environment variable
   return httpWriteStream(connection, connection->buffer, length);
}
Exemple #6
0
error_t httpServerCgiCallback(HttpConnection *connection,
   const char_t *param)
{
   static uint_t pageCounter = 0;
   uint_t length;
   time_t unixTime;
   DateTime date;

   //Underlying network interface
   NetInterface *interface = connection->socket->interface;

   //Check parameter name
   if(!strcasecmp(param, "PAGE_COUNTER"))
   {
      pageCounter++;
      sprintf(connection->buffer, "%u time%s", pageCounter, (pageCounter >= 2) ? "s" : "");
   }
   else if(!strcasecmp(param, "BOARD_NAME"))
   {
      strcpy(connection->buffer, interface->hostname);
   }
   else if(!strcasecmp(param, "SYSTEM_TIME"))
   {
      memset(&connection->buffer, 0x00, HTTP_SERVER_BUFFER_SIZE );
      //		unixTime = RTC_GetCounter();
      unixTime = 0;
      //Convert Unix timestamp to date
      convertUnixTimeToDate(unixTime, &date);
      formatDate(&date, connection->buffer);

   }
   else if(!strcasecmp(param, "MAC_ADDR"))
   {
      macAddrToString(&interface->macAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_ADDR"))
   {
      ipv4AddrToString(interface->ipv4Config.addr, connection->buffer);
   }
   else if(!strcasecmp(param, "SUBNET_MASK"))
   {
      ipv4AddrToString(interface->ipv4Config.subnetMask, connection->buffer);
   }
   else if(!strcasecmp(param, "DEFAULT_GATEWAY"))
   {
      ipv4AddrToString(interface->ipv4Config.defaultGateway, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_PRIMARY_DNS"))
   {
      ipv4AddrToString(interface->ipv4Config.dnsServer[0], connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_SECONDARY_DNS"))
   {
      ipv4AddrToString(interface->ipv4Config.dnsServer[1], connection->buffer);
   }
#if (IPV6_SUPPORT == ENABLED)
   else if(!strcasecmp(param, "LINK_LOCAL_ADDR"))
   {
      ipv6AddrToString(&interface->ipv6Config.linkLocalAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "GLOBAL_ADDR"))
   {
      ipv6AddrToString(&interface->ipv6Config.globalAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PREFIX"))
   {
      ipv6AddrToString(&interface->ipv6Config.prefix, connection->buffer);
      length = strlen(connection->buffer);
      sprintf(connection->buffer + length, "/%u", interface->ipv6Config.prefixLength);
   }
   else if(!strcasecmp(param, "ROUTER"))
   {
      ipv6AddrToString(&interface->ipv6Config.router, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PRIMARY_DNS"))
   {
      ipv6AddrToString(&interface->ipv6Config.dnsServer[0], connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_SECONDARY_DNS"))
   {
      ipv6AddrToString(&interface->ipv6Config.dnsServer[1], connection->buffer);
   }
#endif
   else
   {
      return ERROR_INVALID_TAG;
   }

   //Get the length of the resulting string
   length = strlen(connection->buffer);

   //Send the contents of the specified environment variable
   return httpWriteStream(connection, connection->buffer, length);
}
error_t dhcpDumpMessage(const DhcpMessage *message, size_t length)
{
   error_t error;
   uint_t i;
   const char_t *label;
   DhcpOption *option;

   //Ensure the length of the DHCP message is acceptable
   if(length < sizeof(DhcpMessage))
   {
      //Report a warning
      TRACE_WARNING("DHCP message length is invalid!\r\n");
      //Dump message contents for debugging purpose
      TRACE_DEBUG_ARRAY("  ", message, length);
      //Report an error
      return ERROR_INVALID_LENGTH;
   }

   //Retrieve the name associated with the opcode
   label = (message->op < arraysize(opcodeLabel)) ? opcodeLabel[message->op] : "";

   //Dump DHCP message contents
   TRACE_DEBUG("  Op Code (op) = %" PRIu8 " (%s)\r\n", message->op, label);
   TRACE_DEBUG("  Hardware Type (htype) = %" PRIu8 "\r\n", message->htype);
   TRACE_DEBUG("  Hardware Address Length (hlen) = %" PRIu8 "\r\n", message->hlen);
   TRACE_DEBUG("  Hops (hops) = %" PRIu8 "\r\n", message->hops);
   TRACE_DEBUG("  Transaction ID (xid) = 0x%08" PRIX32 "\r\n", ntohl(message->xid));
   TRACE_DEBUG("  Seconds (secs) = %" PRIu16 "s\r\n", ntohs(message->secs));
   TRACE_DEBUG("  Flags (flags) = 0x%04" PRIX16 "\r\n", ntohs(message->flags));
   TRACE_DEBUG("  Client IP Address (ciaddr) = %s\r\n", ipv4AddrToString(message->ciaddr, NULL));
   TRACE_DEBUG("  Your IP Address (yiaddr) = %s\r\n", ipv4AddrToString(message->yiaddr, NULL));
   TRACE_DEBUG("  Server IP Address (siaddr) = %s\r\n", ipv4AddrToString(message->siaddr, NULL));
   TRACE_DEBUG("  Relay IP Address (giaddr) = %s\r\n", ipv4AddrToString(message->giaddr, NULL));
   TRACE_DEBUG("  Client Hardware Address (chaddr) = %s\r\n", macAddrToString(&message->chaddr, NULL));
   TRACE_DEBUG("  Magic Cookie = 0x%08" PRIX32 "\r\n", ntohl(message->magicCookie));

   //Get the length of the options field
   length -= sizeof(DhcpMessage);

   //Parse DHCP options
   for(i = 0; i < length; i++)
   {
      //Point to the current option
      option = (DhcpOption *) (message->options + i);

      //Pad option detected?
      if(option->code == DHCP_OPT_PAD)
         continue;
      //End option detected?
      if(option->code == DHCP_OPT_END)
         break;
      //Check option length
      if((i + 1) >= length || (i + 1 + option->length) >= length)
      {
         //Report a warning
         TRACE_WARNING("DHCP option length is invalid!\r\n");
         //Dump message contents for debugging purpose
         TRACE_DEBUG_ARRAY("  ", message, length);
         //Report an error
         return ERROR_INVALID_LENGTH;
      }

      //Display the name of the current option
      if(option->code < arraysize(optionLabel))
         TRACE_DEBUG("  %s option (%" PRIu8 " bytes)\r\n", optionLabel[option->code], option->length);
      else
         TRACE_DEBUG("  Option %" PRIu8 " (%" PRIu8 " bytes)\r\n", option->code, option->length);

      //Check option code
      switch(option->code)
      {
      //Message type?
      case DHCP_OPT_DHCP_MESSAGE_TYPE:
         error = dhcpDumpMessageType(option);
         break;
      //Parameter Request List option
      case DHCP_OPT_PARAM_REQUEST_LIST:
         error = dhcpDumpParamRequestList(option);
         break;
      //Boolean value?
      case DHCP_OPT_IP_FORWARDING:
      case DHCP_OPT_NON_LOCAL_SOURCE_ROUTING:
      case DHCP_OPT_ALL_SUBNETS_ARE_LOCAL:
      case DHCP_OPT_PERFORM_MASK_DISCOVERY:
      case DHCP_OPT_MASK_SUPPLIER:
      case DHCP_OPT_PERFORM_ROUTER_DISCOVERY:
      case DHCP_OPT_TRAILER_ENCAPSULATION:
      case DHCP_OPT_ETHERNET_ENCAPSULATION:
      case DHCP_OPT_TCP_KEEPALIVE_GARBAGE:
         error = dhcpDumpBoolean(option);
         break;
      //8-bit unsigned integer?
      case DHCP_OPT_DEFAULT_IP_TTL:
      case DHCP_OPT_TCP_DEFAULT_TTL:
      case DHCP_OPT_NETBIOS_NODE_TYPE:
      case DHCP_OPT_OPTION_OVERLOAD:
         error = dhcpDumpInt8(option);
         break;
      //16-bit unsigned integer?
      case DHCP_OPT_BOOT_FILE_SIZE:
      case DHCP_OPT_MAX_DATAGRAM_REASSEMBLY_SIZE:
      case DHCP_OPT_INTERFACE_MTU:
      case DHCP_OPT_MAX_DHCP_MESSAGE_SIZE:
         error = dhcpDumpInt16(option);
         break;
      //32-bit unsigned integer?
      case DHCP_OPT_PATH_MTU_AGING_TIMEOUT:
      case DHCP_OPT_ARP_CACHE_TIMEOUT:
      case DHCP_OPT_TCP_KEEPALIVE_INTERVAL:
      case DHCP_OPT_IP_ADDRESS_LEASE_TIME:
      case DHCP_OPT_RENEWAL_TIME_VALUE:
      case DHCP_OPT_REBINDING_TIME_VALUE:
         error = dhcpDumpInt32(option);
         break;
      //Character strings?
      case DHCP_OPT_HOST_NAME:
      case DHCP_OPT_MERIT_DUMP_FILE:
      case DHCP_OPT_DOMAIN_NAME:
      case DHCP_OPT_ROOT_PATH:
      case DHCP_OPT_EXTENSIONS_PATH:
      case DHCP_OPT_NIS_DOMAIN:
      case DHCP_OPT_MESSAGE:
      case DHCP_OPT_NISP_DOMAIN:
      case DHCP_OPT_TFTP_SERVER_NAME:
      case DHCP_OPT_BOOTFILE_NAME:
         error = dhcpDumpString(option);
         break;
      //IPv4 address?
      case DHCP_OPT_SUBNET_MASK:
      case DHCP_OPT_SWAP_SERVER:
      case DHCP_OPT_BROADCAST_ADDRESS:
      case DHCP_OPT_ROUTER_SOLICITATION_ADDRESS:
      case DHCP_OPT_REQUESTED_IP_ADDRESS:
      case DHCP_OPT_SERVER_IDENTIFIER:
         error = dhcpDumpIpv4Addr(option);
         break;
      //List of IPv4 addresses?
      case DHCP_OPT_ROUTER:
      case DHCP_OPT_TIME_SERVER:
      case DHCP_OPT_NAME_SERVER:
      case DHCP_OPT_DNS_SERVER:
      case DHCP_OPT_LOG_SERVER:
      case DHCP_OPT_COOKIE_SERVER:
      case DHCP_OPT_LPR_SERVER:
      case DHCP_OPT_IMPRESS_SERVER:
      case DHCP_OPT_RESOURCE_LOCATION_SERVER:
      case DHCP_OPT_NIS_SERVER:
      case DHCP_OPT_NTP_SERVER:
      case DHCP_OPT_NETBIOS_NBNS_SERVER:
      case DHCP_OPT_NETBIOS_NBDD_SERVER:
      case DHCP_OPT_X11_FONT_SERVER:
      case DHCP_OPT_X11_DISPLAY_MANAGER:
      case DHCP_OPT_NISP_SERVER:
      case DHCP_OPT_MOBILE_IP_HOME_AGENT:
      case DHCP_OPT_SMTP_SERVER:
      case DHCP_OPT_POP3_SERVER:
      case DHCP_OPT_NNTP_SERVER:
      case DHCP_OPT_DEFAULT_WWW_SERVER:
      case DHCP_OPT_DEFAULT_FINGER_SERVER:
      case DHCP_OPT_DEFAULT_IRC_SERVER:
      case DHCP_OPT_STREETTALK_SERVER:
      case DHCP_OPT_STDA_SERVER:
         error = dhcpDumpIpv4AddrList(option);
         break;
      //Raw data?
      default:
         error = dhcpDumpRawData(option);
         break;
      }

      //Failed to parse current option?
      if(error)
      {
         //Report a warning
         TRACE_WARNING("Failed to parse DHCP options!\r\n");
         //Dump message contents for debugging purpose
         TRACE_DEBUG_ARRAY("  ", message, length);
      }

      //Jump to the next option
      i += option->length + 1;
   }

   //No error to report
   return NO_ERROR;
}
error_t httpServerProcessGetConfig(HttpConnection *connection)
{
   error_t error;
   uint_t i;
   size_t n;
   char_t *buffer;
   char_t temp[40];

   //Allocate a memory buffer
   buffer = osAllocMem(2048);
   //Failed to allocate memory?
   if(!buffer) return ERROR_OUT_OF_MEMORY;

   //Format XML data
   n = sprintf(buffer, "<settings>\r\n");

   //Icecast settings
   n += sprintf(buffer + n, "  <icecast>\r\n");
   //Icecast resource
   n += sprintf(buffer + n, "    <url>%s</url>\r\n",
      appSettings.icecast.url);
   //Icecast server port
   n += sprintf(buffer + n, "    <port>%" PRIu16 "</port>\r\n",
      appSettings.icecast.port);
   //End of Icecast settings
   n += sprintf(buffer + n, "  </icecast>\r\n");

   //LAN settings
   n += sprintf(buffer + n, "  <lan>\r\n");
   //MAC address
   n += sprintf(buffer + n, "    <macAddr>%s</macAddr>\r\n",
      macAddrToString(&appSettings.lan.macAddr, temp));
   //Host name
   n += sprintf(buffer + n, "    <hostName>%s</hostName>\r\n",
      appSettings.lan.hostname);
   //Enable DHCP
   n += sprintf(buffer + n, "    <enableDhcp>%u</enableDhcp>\r\n",
      appSettings.lan.enableDhcp);
   //IPv4 host address
   n += sprintf(buffer + n, "    <hostAddr>%s</hostAddr>\r\n",
      ipv4AddrToString(appSettings.lan.hostAddr, temp));
   //Subnet mask
   n += sprintf(buffer + n, "    <subnetMask>%s</subnetMask>\r\n",
      ipv4AddrToString(appSettings.lan.subnetMask, temp));
   //Default gateway
   n += sprintf(buffer + n, "    <defaultGateway>%s</defaultGateway>\r\n",
      ipv4AddrToString(appSettings.lan.defaultGateway, temp));
   //Primary DNS
   n += sprintf(buffer + n, "    <primaryDns>%s</primaryDns>\r\n",
      ipv4AddrToString(appSettings.lan.primaryDns, temp));
   //Secondary DNS
   n += sprintf(buffer + n, "    <secondaryDns>%s</secondaryDns>\r\n",
      ipv4AddrToString(appSettings.lan.secondaryDns, temp));
   //End of LAN settings
   n += sprintf(buffer + n, "  </lan>\r\n");

   //Proxy settings
   n += sprintf(buffer + n, "  <proxy>\r\n");
   //Enable proxy server
   n += sprintf(buffer + n, "    <enable>%u</enable>\r\n",
      appSettings.proxy.enable);
   //Proxy server name
   n += sprintf(buffer + n, "    <name>%s</name>\r\n",
      appSettings.proxy.name);
   //Proxy server port
   n += sprintf(buffer + n, "    <port>%" PRIu16 "</port>\r\n",
      appSettings.proxy.port);
   //End of proxy settings
   n += sprintf(buffer + n, "  </proxy>\r\n");

  //End of settings
   n += sprintf(buffer + n, "</settings>\r\n");

   //Format HTTP response header
   connection->response.version = connection->request.version;
   connection->response.statusCode = 200;
   connection->response.keepAlive = connection->request.keepAlive;
   connection->response.noCache = TRUE;
   connection->response.contentType = mimeGetType(".xml");
   connection->response.chunkedEncoding = FALSE;
   connection->response.contentLength = n;

   //Send the header to the client
   error = httpWriteHeader(connection);

   //Check status code
   if(!error)
   {
      //Send response body
      error = httpWriteStream(connection, buffer, n);
   }

   //Check status code
   if(!error)
   {
      //Properly close output stream
      error = httpCloseStream(connection);
   }

   //Free previously allocated memory
   osFreeMem(buffer);
   //Return status code
   return error;
}
Exemple #9
0
error_t httpServerCgiCallback(HttpConnection *connection, const char_t *param)
{
   static uint_t pageCounter = 0;
   uint_t length;

   //Underlying network interface
   NetInterface *interface = connection->socket->interface;

   //Check parameter name
   if(!strcasecmp(param, "PAGE_COUNTER"))
   {
      pageCounter++;
      sprintf(connection->buffer, "%u time%s", pageCounter, (pageCounter >= 2) ? "s" : "");
   }
   else if(!strcasecmp(param, "BOARD_NAME"))
   {
      strcpy(connection->buffer, "STM3240G-EVAL");
   }
   else if(!strcasecmp(param, "SYSTEM_TIME"))
   {
      time_t time = osGetTickCount();
      sprintf(connection->buffer, "%lus %03lums", time / 1000, time % 1000);
   }
   else if(!strcasecmp(param, "MAC_ADDR"))
   {
      macAddrToString(&interface->macAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_ADDR"))
   {
      ipv4AddrToString(interface->ipv4Config.addr, connection->buffer);
   }
   else if(!strcasecmp(param, "SUBNET_MASK"))
   {
      ipv4AddrToString(interface->ipv4Config.subnetMask, connection->buffer);
   }
   else if(!strcasecmp(param, "DEFAULT_GATEWAY"))
   {
      ipv4AddrToString(interface->ipv4Config.defaultGateway, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_PRIMARY_DNS"))
   {
      ipv4AddrToString(interface->ipv4Config.dnsServer[0], connection->buffer);
   }
   else if(!strcasecmp(param, "IPV4_SECONDARY_DNS"))
   {
      ipv4AddrToString(interface->ipv4Config.dnsServer[1], connection->buffer);
   }
#if (IPV6_SUPPORT == ENABLED)
   else if(!strcasecmp(param, "LINK_LOCAL_ADDR"))
   {
      ipv6AddrToString(&interface->ipv6Config.linkLocalAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "GLOBAL_ADDR"))
   {
      ipv6AddrToString(&interface->ipv6Config.globalAddr, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PREFIX"))
   {
      ipv6AddrToString(&interface->ipv6Config.prefix, connection->buffer);
      length = strlen(connection->buffer);
      sprintf(connection->buffer + length, "/%u", interface->ipv6Config.prefixLength);
   }
   else if(!strcasecmp(param, "ROUTER"))
   {
      ipv6AddrToString(&interface->ipv6Config.router, connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_PRIMARY_DNS"))
   {
      ipv6AddrToString(&interface->ipv6Config.dnsServer[0], connection->buffer);
   }
   else if(!strcasecmp(param, "IPV6_SECONDARY_DNS"))
   {
      ipv6AddrToString(&interface->ipv6Config.dnsServer[1], connection->buffer);
   }
#endif
   else
   {
      return ERROR_INVALID_TAG;
   }

   //Get the length of the resulting string
   length = strlen(connection->buffer);

   //Send the contents of the specified environment variable
   return httpWriteStream(connection, connection->buffer, length);
}