void slaacDumpConfig(SlaacContext *context) { uint_t n; Ipv6Addr ipv6Addr; //Debug message TRACE_INFO("\r\nSLAAC configuration:\r\n"); //Link-local address ipv6GetLinkLocalAddr(context->interface, &ipv6Addr); TRACE_INFO(" Link-local Address = %s\r\n", ipv6AddrToString(&ipv6Addr, NULL)); //IPv6 prefix ipv6GetPrefix(context->interface, &ipv6Addr, &n); TRACE_INFO(" Prefix = %s/%" PRIu8 "\r\n", ipv6AddrToString(&ipv6Addr, NULL), n); //Global address ipv6GetGlobalAddr(context->interface, &ipv6Addr); TRACE_INFO(" Global Address = %s\r\n", ipv6AddrToString(&ipv6Addr, NULL)); //Router address ipv6GetRouter(context->interface, &ipv6Addr); TRACE_INFO(" Router = %s\r\n", ipv6AddrToString(&ipv6Addr, NULL)); //DNS servers for(n = 0; n < IPV6_MAX_DNS_SERVERS; n++) { ipv6GetDnsServer(context->interface, n, &ipv6Addr); TRACE_INFO(" DNS Server %u = %s\r\n", n + 1, ipv6AddrToString(&ipv6Addr, NULL)); } }
error_t dhcpv6DumpRelayMessageOption(const Dhcpv6Option *option, uint_t level) { uint8_t type; const char_t *label; //Check the length of the option if(!ntohs(option->length)) return ERROR_INVALID_OPTION; //Retrieve the message type type = option->value[0]; //Get the corresponding label label = (type < arraysize(messageLabel)) ? messageLabel[type] : "Unknown"; //Relay agent/server message? if(type == DHCPV6_MSG_TYPE_RELAY_FORW || type == DHCPV6_MSG_TYPE_RELAY_REPL) { //Get the inner message const Dhcpv6RelayMessage *message = (Dhcpv6RelayMessage *) option->value; //Ensure the length of the DHCPv6 message is acceptable if(ntohs(option->length) < sizeof(Dhcpv6RelayMessage)) return ERROR_INVALID_OPTION; //Dump message header TRACE_DEBUG("%sRelay Message option (%u bytes)\r\n", prefix[level], ntohs(option->length)); TRACE_DEBUG("%sMessage Type = %u (%s)\r\n", prefix[level + 1], message->msgType, label); TRACE_DEBUG("%sHop Count = %u\r\n", prefix[level + 1], message->hopCount); TRACE_DEBUG("%sLink Address = %s\r\n", prefix[level + 1], ipv6AddrToString(&message->linkAddress, NULL)); TRACE_DEBUG("%sPeer Address = %s\r\n", prefix[level + 1], ipv6AddrToString(&message->peerAddress, NULL)); //Dump message options return dhcpv6DumpOptions(message->options, ntohs(option->length) - sizeof(Dhcpv6RelayMessage), level + 1); } //Client/server message? else { //Get the inner message const Dhcpv6Message *message = (Dhcpv6Message *) option->value; //Ensure the length of the DHCPv6 message is acceptable if(ntohs(option->length) < sizeof(Dhcpv6Message)) return ERROR_INVALID_OPTION; //Dump message header TRACE_DEBUG("%sRelay Message option (%u bytes)\r\n", prefix[level], ntohs(option->length)); TRACE_DEBUG("%sMessage Type = %u (%s)\r\n", prefix[level + 1], message->msgType, label); TRACE_DEBUG("%sTransaction ID = 0x%06X\r\n", prefix[level + 1], LOAD24BE(message->transactionId)); //Dump message options return dhcpv6DumpOptions(message->options, ntohs(option->length) - sizeof(Dhcpv6Message), level + 1); } }
void userTask(void *param) { char_t buffer[40]; //Point to the network interface NetInterface *interface = &netInterface[0]; lcdSetCursor(2, 0); printf("IPv4 Address\r\n"); lcdSetCursor(5, 0); printf("IPv6 Link-Local Address\r\n"); lcdSetCursor(8, 0); printf("IPv6 Global Address\r\n"); lcdSetCursor(11, 0); printf("Press SELECT button to run test\r\n"); //Endless loop while(1) { #if (IPV4_SUPPORT == ENABLED) //Display IPv4 host address lcdSetCursor(3, 0); printf("%-16s\r\n", ipv4AddrToString(interface->ipv4Config.addr, buffer)); #endif #if (IPV6_SUPPORT == ENABLED) //Display IPv6 link-local address lcdSetCursor(6, 0); printf("%-40s\r\n", ipv6AddrToString(&interface->ipv6Config.linkLocalAddr, buffer)); //Display IPv6 global address lcdSetCursor(9, 0); printf("%-40s\r\n", ipv6AddrToString(&interface->ipv6Config.globalAddr, buffer)); #endif //SELECT button pressed? if(!GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_1)) { //FTP client test routine ftpClientTest(); //Wait for the SELECT button to be released while(!GPIOPinRead(GPIO_PORTP_BASE, GPIO_PIN_1)); } //Loop delay osDelayTask(100); } }
void userTask(void *param) { char_t buffer[40]; //Point to the network interface NetInterface *interface = &netInterface[0]; //Initialize LCD display lcdSetCursor(2, 0); printf("IPv4 Addr\r\n"); lcdSetCursor(5, 0); printf("IPv6 Link-Local Addr\r\n"); lcdSetCursor(8, 0); printf("IPv6 Global Addr\r\n"); //Endless loop while(1) { #if (IPV4_SUPPORT == ENABLED) //Display IPv4 host address lcdSetCursor(3, 0); printf("%-16s\r\n", ipv4AddrToString(interface->ipv4Config.addr, buffer)); #endif #if (IPV6_SUPPORT == ENABLED) //Display IPv6 link-local address lcdSetCursor(6, 0); printf("%-40s\r\n", ipv6AddrToString(&interface->ipv6Config.linkLocalAddr, buffer)); //Display IPv6 global address lcdSetCursor(9, 0); printf("%-40s\r\n", ipv6AddrToString(&interface->ipv6Config.globalAddr, buffer)); #endif //User button pressed? if(BSP_PB_GetState(BUTTON_KEY)) { //FTP client test routine ftpClientTest(); //Wait for the user button to be released while(BSP_PB_GetState(BUTTON_KEY)); } //Loop delay osDelayTask(100); } }
error_t dhcpv6DumpDnsServersOption(const Dhcpv6Option *option, uint_t level) { uint_t i; uint_t n; Dhcpv6DnsServersOption *dnsServersOption; //Check the length of the option if(ntohs(option->length) % sizeof(Ipv6Addr)) return ERROR_INVALID_OPTION; //Point to the option contents dnsServersOption = (Dhcpv6DnsServersOption *) option->value; //Calculate the number of IPv6 addresses in the list n = ntohs(option->length) / sizeof(Ipv6Addr); //Dump contents TRACE_DEBUG("%sDNS Recursive Name Server option (%u bytes)\r\n", prefix[level], ntohs(option->length)); //Diplay the DNS servers for(i = 0; i < n; i++) TRACE_DEBUG("%s%s\r\n", prefix[level + 1], ipv6AddrToString(dnsServersOption->address + i, NULL)); //No error to report return NO_ERROR; }
void ndpDumpNeighborSolMessage(const NdpNeighborSolMessage *message) { //Dump Neighbor Solicitation message TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type); TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code); TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum)); TRACE_DEBUG(" Target Address = %s\r\n", ipv6AddrToString(&message->targetAddr, NULL)); }
void mldDumpMessage(const MldMessage *message) { //Dump MLD message TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type); TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code); TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum)); TRACE_DEBUG(" Max Resp Delay = %" PRIu16 "\r\n", message->maxRespDelay); TRACE_DEBUG(" Multicast Address = %s\r\n", ipv6AddrToString(&message->multicastAddr, NULL)); }
void ndpDumpNeighborAdvMessage(const NdpNeighborAdvMessage *message) { //Dump Neighbor Advertisement message TRACE_DEBUG(" Type = %" PRIu8 "\r\n", message->type); TRACE_DEBUG(" Code = %" PRIu8 "\r\n", message->code); TRACE_DEBUG(" Checksum = 0x%04" PRIX16 "\r\n", ntohs(message->checksum)); TRACE_DEBUG(" R = %" PRIu8 "\r\n", message->r); TRACE_DEBUG(" S = %" PRIu8 "\r\n", message->s); TRACE_DEBUG(" O = %" PRIu8 "\r\n", message->o); TRACE_DEBUG(" Target Address = %s\r\n", ipv6AddrToString(&message->targetAddr, NULL)); }
void userTask(void *param) { char_t buffer[40]; //Point to the network interface NetInterface *interface = &netInterface[0]; //Initialize LCD display lcdSetCursor(1, 0); printf("IPv4 Addr\r\n"); lcdSetCursor(4, 0); printf("IPv6 Link-Local Addr\r\n"); lcdSetCursor(7, 0); printf("IPv6 Global Addr\r\n"); //Endless loop while(1) { #if (IPV4_SUPPORT == ENABLED) //Display IPv4 host address lcdSetCursor(2, 0); printf("%-16s\r\n", ipv4AddrToString(interface->ipv4Config.addr, buffer)); #endif #if (IPV6_SUPPORT == ENABLED) //Display IPv6 link-local address lcdSetCursor(5, 0); printf("%-40s\r\n", ipv6AddrToString(&interface->ipv6Config.linkLocalAddr, buffer)); //Display IPv6 global address lcdSetCursor(8, 0); printf("%-40s\r\n", ipv6AddrToString(&interface->ipv6Config.globalAddr, buffer)); #endif //Start A/D conversion adcValue = (1023 - adcGetValue()) * 4; //Loop delay osDelayTask(500); } }
error_t dhcpv6DumpServerUnicastOption(const Dhcpv6Option *option, uint_t level) { Dhcpv6ServerUnicastOption *serverUnicastOption; //Check the length of the option if(ntohs(option->length) != sizeof(Dhcpv6ServerUnicastOption)) return ERROR_INVALID_OPTION; //Point to the option contents serverUnicastOption = (Dhcpv6ServerUnicastOption *) option->value; //Dump contents TRACE_DEBUG("%sServer Unicast option (%u bytes)\r\n", prefix[level], ntohs(option->length)); TRACE_DEBUG("%s%s\r\n", prefix[level + 1], ipv6AddrToString(&serverUnicastOption->serverAddr, NULL)); //No error to report return NO_ERROR; }
error_t dhcpv6DumpIaAddrOption(const Dhcpv6Option *option, uint_t level) { Dhcpv6IaAddrOption *iaAddrOption; //Check the length of the option if(ntohs(option->length) < sizeof(Dhcpv6IaAddrOption)) return ERROR_INVALID_OPTION; //Point to the option contents iaAddrOption = (Dhcpv6IaAddrOption *) option->value; //Dump contents TRACE_DEBUG("%sIA Address option (%u bytes)\r\n", prefix[level], ntohs(option->length)); TRACE_DEBUG("%sIPv6 Address = %s\r\n", prefix[level + 1], ipv6AddrToString(&iaAddrOption->address, NULL)); TRACE_DEBUG("%sPreferred Lifetime = %us\r\n", prefix[level + 1], ntohl(iaAddrOption->preferredLifetime)); TRACE_DEBUG("%sValid Lifetime = %us\r\n", prefix[level + 1], ntohl(iaAddrOption->validLifetime)); //Dump the options associated with this IA address dhcpv6DumpOptions(iaAddrOption->options, ntohs(option->length) - sizeof(Dhcpv6IaAddrOption), level + 1); //No error to report return NO_ERROR; }
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); }
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 dhcpv6DumpMessage(const void *message, size_t length) { error_t error; uint8_t type; const char_t *label; //Empty message? if(!length) return ERROR_INVALID_LENGTH; //Retrieve the message type type = *((uint8_t *) message); //Get the corresponding label label = (type < arraysize(messageLabel)) ? messageLabel[type] : "Unknown"; //Relay agent/server message? if(type == DHCPV6_MSG_TYPE_RELAY_FORW || type == DHCPV6_MSG_TYPE_RELAY_REPL) { //Ensure the length of the DHCPv6 message is acceptable if(length < sizeof(Dhcpv6RelayMessage)) { //Report an error error = ERROR_INVALID_LENGTH; } else { //Point to the DHCPv6 message const Dhcpv6RelayMessage *relayMessage = message; //Dump message header TRACE_DEBUG(" Message Type = %u (%s)\r\n", relayMessage->msgType, label); TRACE_DEBUG(" Hop Count = %u\r\n", relayMessage->hopCount); TRACE_DEBUG(" Link Address = %s\r\n", ipv6AddrToString(&relayMessage->linkAddress, NULL)); TRACE_DEBUG(" Peer Address = %s\r\n", ipv6AddrToString(&relayMessage->peerAddress, NULL)); //Dump message options error = dhcpv6DumpOptions(relayMessage->options, length - sizeof(Dhcpv6RelayMessage), 1); } } //Client/server message? else { //Ensure the length of the DHCPv6 message is acceptable if(length < sizeof(Dhcpv6Message)) { //Report an error error = ERROR_INVALID_LENGTH; } else { //Point to the DHCPv6 message const Dhcpv6Message *clientMessage = message; //Dump message header TRACE_DEBUG(" Message Type = %u (%s)\r\n", clientMessage->msgType, label); TRACE_DEBUG(" Transaction ID = 0x%06X\r\n", LOAD24BE(clientMessage->transactionId)); //Dump message options error = dhcpv6DumpOptions(clientMessage->options, length - sizeof(Dhcpv6Message), 1); } } //Did we encounter an error? if(error) { //Debug message TRACE_WARNING("DHCPv6 message is not valid!\r\n"); //Dump message contents for debugging purpose TRACE_DEBUG_ARRAY(" ", message, length); } //Return status code return error; }
error_t ftpSetPort(FtpClientContext *context, const IpAddr *ipAddr, uint16_t port) { error_t error; uint_t replyCode; char_t *p; //Invalid context? if(context == NULL) return ERROR_INVALID_PARAMETER; #if (IPV4_SUPPORT == ENABLED) //IPv4 FTP client? if(ipAddr->length == sizeof(Ipv4Addr)) { //Format the PORT command strcpy(context->buffer, "PORT "); //Append host address ipv4AddrToString(ipAddr->ipv4Addr, context->buffer + 5); //Parse the resulting string for(p = context->buffer; *p != '\0'; p++) { //Change dots to commas if(*p == '.') *p = ','; } //Append port number sprintf(p, ",%" PRIu8 ",%" PRIu8 "\r\n", MSB(port), LSB(port)); } else #endif #if (IPV6_SUPPORT == ENABLED) //IPv6 FTP client? if(ipAddr->length == sizeof(Ipv6Addr)) { //Format the EPRT command strcpy(context->buffer, "EPRT |2|"); //Append host address ipv6AddrToString(&ipAddr->ipv6Addr, context->buffer + 8); //Point to the end of the resulting string p = context->buffer + strlen(context->buffer); //Append port number sprintf(p, "|%" PRIu16 "|\r\n", port); } else #endif //Invalid IP address? { //Report an error return ERROR_INVALID_ADDRESS; } //Send the command to the server error = ftpSendCommand(context, context->buffer, &replyCode); //Any error to report? if(error) return error; //Check FTP response code if(!FTP_REPLY_CODE_2YZ(replyCode)) return ERROR_UNEXPECTED_RESPONSE; //Successful processing return NO_ERROR; }
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); }
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); }
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); }