zkkkk12 opened a new pull request, #17730:
URL: https://github.com/apache/nuttx/pull/17730

   Supports no Neighbor request for invalid routing addresses in cross-segment 
communication
   
   *Note: Please adhere to [Contributing 
Guidelines](https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md).*
   
   ## Summary
   
   Supports no Neighbor request for invalid routing addresses in cross-segment 
communication
   
   ## Impact
   
   When processing IPv6 packet transmission, if the destination address is 
unspecified, the device buffer length is set to 0 and the device returns 
directly without sending any packets.This prevents the system from attempting 
to send data packets to invalid addresses, thus avoiding wasting network 
resources.
   
   ## Testing
   
   ```
   #include <nuttx/config.h>
   #include <sys/socket.h>
   #include <netinet/in.h>
   #include <arpa/inet.h>
   #include <net/if.h>
   #include <errno.h>
   #include <string.h>
   #include <unistd.h>
   #include <sys/ioctl.h>
   #include <stdio.h>
   #include <stdlib.h>
   
   #include <nuttx/net/net.h>
   #include <nuttx/net/netdev.h>
   #include <nuttx/net/icmpv6.h>
   #include <nuttx/net/neighbor.h>
   
   #include "Ipv6NeighborTest.h"
   #include "CunitTest.h"
   
   /* Test constants */
   #define TEST_INTERFACE_NAME "test_eth0"
   
   /* IPv6 unspecified address (all zeros) */
   static const net_ipv6addr_t g_unspecified_addr = {0, 0, 0, 0, 0, 0, 0, 0};
   
   /* Helper function to create a network device structure for testing */
   static struct net_driver_s *create_test_netdev(void)
   {
     struct net_driver_s *dev;
   
     /* Allocate memory for test netdev */
     dev = (struct net_driver_s *)malloc(sizeof(struct net_driver_s));
     if (dev == NULL)
       {
         return NULL;
       }
   
     /* Initialize basic fields */
     memset(dev, 0, sizeof(struct net_driver_s));
   
     /* Set device properties for IPv6 testing */
     dev->d_lltype = NET_LL_ETHERNET;
     dev->d_ifname = TEST_INTERFACE_NAME;
     dev->d_ifup = true;
   
     /* Set IPv6 link-local address (fe80::1) */
     dev->d_ipv6addr[0] = HTONS(0xfe80);
     dev->d_ipv6addr[1] = 0;
     dev->d_ipv6addr[2] = 0;
     dev->d_ipv6addr[3] = 0;
     dev->d_ipv6addr[4] = 0;
     dev->d_ipv6addr[5] = 0;
     dev->d_ipv6addr[6] = 0;
     dev->d_ipv6addr[7] = HTONS(0x0001);
   
     /* Set IPv6 netmask (prefix length 64) */
     dev->d_ipv6netmask[0] = HTONS(0xffff);
     dev->d_ipv6netmask[1] = HTONS(0xffff);
     dev->d_ipv6netmask[2] = HTONS(0xffff);
     dev->d_ipv6netmask[3] = HTONS(0xffff);
     dev->d_ipv6netmask[4] = 0;
     dev->d_ipv6netmask[5] = 0;
     dev->d_ipv6netmask[6] = 0;
     dev->d_ipv6netmask[7] = 0;
   
     /* Set default router to unspecified address (this is what we want to 
test) */
     memset(dev->d_ipv6draddr, 0, sizeof(net_ipv6addr_t));
   
     /* Set MAC address */
     dev->d_mac.ether.ether_addr_octet[0] = 0x00;
     dev->d_mac.ether.ether_addr_octet[1] = 0x11;
     dev->d_mac.ether.ether_addr_octet[2] = 0x22;
     dev->d_mac.ether.ether_addr_octet[3] = 0x33;
     dev->d_mac.ether.ether_addr_octet[4] = 0x44;
     dev->d_mac.ether.ether_addr_octet[5] = 0x55;
   
     /* Clear NOARP flag to allow neighbor discovery */
     IFF_CLR_NOARP(dev->d_flags);
   
     return dev;
   }
   
   /* Helper function to cleanup test netdev */
   static void cleanup_test_netdev(struct net_driver_s *dev)
   {
     if (dev != NULL)
       {
         free(dev);
       }
   }
   
   /* Helper function to create IPv6 packet in device buffer */
   static void create_test_ipv6_packet(struct net_driver_s *dev, const 
net_ipv6addr_t dest_addr)
   {
     struct ipv6_hdr_s *ip;
   
     /* Allocate buffer for Ethernet + IPv6 header */
     dev->d_buf = malloc(sizeof(struct eth_hdr_s) + sizeof(struct ipv6_hdr_s));
     if (dev->d_buf == NULL)
       {
         return;
       }
   
     /* Set packet length */
     dev->d_len = sizeof(struct eth_hdr_s) + sizeof(struct ipv6_hdr_s);
   
     /* Skip Ethernet header and get IPv6 header */
     ip = (struct ipv6_hdr_s *)(dev->d_buf + sizeof(struct eth_hdr_s));
   
     /* Set IPv6 header fields */
     ip->vtc = 0x60;  /* Version 6, Traffic class 0 */
     ip->tcf = 0;     /* Traffic class 0, Flow label 0 */
     ip->flow = 0;    /* Flow label 0 */
     ip->len[0] = 0;  /* Payload length (will be set later) */
     ip->len[1] = 0;
     ip->proto = IP_PROTO_TCP;  /* Next header */
     ip->ttl = 64;    /* Hop limit */
   
     /* Set source address (link-local) */
     ip->srcipaddr[0] = HTONS(0xfe80);
     ip->srcipaddr[1] = 0;
     ip->srcipaddr[2] = 0;
     ip->srcipaddr[3] = 0;
     ip->srcipaddr[4] = 0;
     ip->srcipaddr[5] = 0;
     ip->srcipaddr[6] = 0;
     ip->srcipaddr[7] = HTONS(0x0001);
   
     /* Set destination address */
     memcpy(ip->destipaddr, dest_addr, sizeof(net_ipv6addr_t));
   }
   
   /* Test icmpv6_neighbor function with unspecified address */
   int do_icmpv6_neighbor_unspecified_addr_test(void)
   {
     struct net_driver_s *dev;
     int ret;
   
     /* Create test network device */
     dev = create_test_netdev();
     if (dev == NULL)
       {
         printf("Failed to create test netdev\n");
         return TEST_FAIL;
       }
   
     /* Test icmpv6_neighbor with unspecified address - should return 
EHOSTUNREACH */
     ret = icmpv6_neighbor(dev, g_unspecified_addr);
     if (ret != -EHOSTUNREACH)
       {
         printf("icmpv6_neighbor should return EHOSTUNREACH for unspecified 
address, got %d\n", ret);
         cleanup_test_netdev(dev);
         return TEST_FAIL;
       }
   
     cleanup_test_netdev(dev);
     return TEST_PASS;
   }
   
   /* Test neighbor_ethernet_out function with unspecified address */
   int do_neighbor_ethernet_out_unspecified_addr_test(void)
   {
     struct net_driver_s *dev;
     uint16_t original_len;
   
     /* Create test network device */
     dev = create_test_netdev();
     if (dev == NULL)
       {
         printf("Failed to create test netdev\n");
         return TEST_FAIL;
       }
   
     /* Create IPv6 packet with unspecified destination address */
     create_test_ipv6_packet(dev, g_unspecified_addr);
     if (dev->d_buf == NULL)
       {
         printf("Failed to create test packet\n");
         cleanup_test_netdev(dev);
         return TEST_FAIL;
       }
   
     original_len = dev->d_len;
   
     /* Call neighbor_ethernet_out - should detect unspecified address and set 
d_len to 0 */
     neighbor_ethernet_out(dev);
   
     if (dev->d_len != 0)
       {
         printf("neighbor_ethernet_out should set d_len to 0 for unspecified 
address, got %d\n", dev->d_len);
         free(dev->d_buf);
         cleanup_test_netdev(dev);
         return TEST_FAIL;
       }
   
     /* Cleanup */
     free(dev->d_buf);
     cleanup_test_netdev(dev);
     return TEST_PASS;
   }
   
   
   /****************************************************************************
    * Name: main
    *
    * Description:
    *   Main function to run IPv6 neighbor unspecified address tests
    *
    * Returned Value:
    *   Zero on success, non-zero on failure
    *
    
****************************************************************************/
   
   int main(int argc, char *argv[])
   {
     int ret;
     int passed = 0;
     int failed = 0;
   
     printf("=== IPv6 Neighbor Unspecified Address Test ===\n\n");
   
     /* Test 1: icmpv6_neighbor with unspecified address */
     printf("Running do_icmpv6_neighbor_unspecified_addr_test...\n");
     ret = do_icmpv6_neighbor_unspecified_addr_test();
     if (ret == TEST_PASS)
       {
         printf("PASS: icmpv6_neighbor correctly handles unspecified 
address\n");
         passed++;
       }
     else
       {
         printf("FAIL: icmpv6_neighbor test failed\n");
         failed++;
       }
   
     printf("\n");
   
     /* Test 2: neighbor_ethernet_out with unspecified address */
     printf("Running do_neighbor_ethernet_out_unspecified_addr_test...\n");
     ret = do_neighbor_ethernet_out_unspecified_addr_test();
     if (ret == TEST_PASS)
       {
         printf("PASS: neighbor_ethernet_out correctly handles unspecified 
address\n");
         passed++;
       }
     else
       {
         printf("FAIL: neighbor_ethernet_out test failed\n");
         failed++;
       }
   
     printf("\n");
     printf("=== Test Results ===\n");
     printf("Total tests: %d\n", passed + failed);
     printf("Passed: %d\n", passed);
     printf("Failed: %d\n", failed);
   
     if (failed == 0)
       {
         printf("\nSUCCESS: All IPv6 neighbor unspecified address tests 
passed!\n");
         printf("The fix ensures that:\n");
         printf("1. icmpv6_neighbor() returns EHOSTUNREACH when address is 
unspecified\n");
         printf("2. neighbor_ethernet_out() sets packet length to 0 when 
address is unspecified\n");
         return 0;
       }
     else
       {
         printf("\nFAILURE: Some tests failed!\n");
         return 1;
       }
   }
   ```
   Terminal output log:
   ```
   core1> === IPv6 Neighbor Unspecified Address Test ===
   core1> Running do_icmpv6_neighbor_unspecified_addr_test...
   core1> PASS: icmpv6_neighbor correctly handles unspecified address
   core1> Running do_neighbor_ethernet_out_unspecified_addr_test...
   core1> PASS: neighbor_ethernet_out correctly handles unspecified address
   core1> === Test Results ===
   core1> SUCCESS: All IPv6 neighbor unspecified address tests passed!
   ```


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to