Error adding CONFIG_NET_ICMPV4 to my project

I need to check if the Ethernet cable is connected or not, I am using the eth_click for ENC28J60. I see the driver does not allow me to see directly if the cable is connected or not, so I am trying to ping my device.

However, in order to do so, I need to add CONFIG_NET_ICMPV4=y to my prj.config file.

I get an error

I2C bus unit address format error, expected "4b"

"warning: attempt to assign the value 'y' to the undefined symbol NET_ICMPV4

error: Aborting due to Kconfig warnings

error: cmake failed

create_nordic_project.py failed

However, I have already added the dependencies

# Drivers
CONFIG_GPIO=y
CONFIG_I2C=y
CONFIG_ADC=y
CONFIG_PWM=y
CONFIG_NRFX_UARTE0=y
CONFIG_UART_ASYNC_API=y
CONFIG_NETWORKING=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_DNS_RESOLVER=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y
CONFIG_WATCHDOG=y

# Networking
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=n
CONFIG_NET_LOG=y
CONFIG_ETHERNET_LOG_LEVEL_INF=y
CONFIG_NET_L2_ETHERNET_LOG_LEVEL_INF=y
CONFIG_LOG=y
#CONFIG_NET_ICMPV4=n
CONFIG_NET_DHCPV4=y
  • Hi,

    Which version of the nRF Connect SDK are you using?

    You should not have to set CONFIG_NET_ICMPV4 for ping to work. How have you implemented the ping?

    Best regards,
    Marte

  • I am using NCS 1.5.

    I have implemented the ping, however, it returns an interface with IP 0.0.0.

    This is my debug log:

     [00:00:13.373,931] [0m<inf> Modem: PING.Trying ping to IP: 10.131.17.2[0m
    [00:00:13.373,962] [0m<inf> Modem: PING. Interface is up.[0m
    [00:00:13.373,992] [0m<inf> Modem: PING. Interface Index: 0[0m
    [00:00:13.374,023] [0m<inf> Modem: PING. Checking interface with IPv4 Address: 0.0.0.0[0m
    [00:00:13.374,053] [0m<inf> Modem: PING. Interface ID: enx0004a3010203[0m
    [00:00:13.374,145] [0m<inf> Modem: PING. MAC Address: 00:04:a3:01:02:03[0m
    [00:00:13.374,145] [0m<inf> Modem: PING. Interface pointer (address): 0x20001a7c[0m
    [00:00:13.374,176] [1;31m<err> Modem: PING. Failed to find the correct network interface[0m
    [00:00:13.374,206] [0m<inf> Modem: PING. Found interface with IPv4 Address: 0.0.0.0[0m
    [00:00:13.374,237] [1;31m<err> Modem: PING. Interface is down with IPv4 Address: [0m
    [00:00:13.467,254] [0m<inf> Modem: PING.Ping socket successfully open[0m
    [00:00:13.467,315] [0m<inf> Modem: PING.Ethernet interface is up.[0m
    [00:00:13.467,346] [0m<inf> Modem: PING.Ethernet interface IPv4 Address: 0.0.0.0[0m
    [00:00:13.467,376] [0m<inf> Modem: PING.Sending ping request to 10.131.17.2[0m
    [00:00:13.467,956] [1;31m<err> net_arp: Gateway not set for iface 0x20001a7c[0m
    [00:00:13.468,048] [0m<inf> Modem: PING.Ping request successfully sent[0m
    [00:00:13.468,139] [0m<inf> Modem: PING.Ping socket closed![0m

    This is my draft code:

    static void iface_callback(struct net_if *iface, void *user_data) {
        struct net_if_addr *if_addr;
        char buf[NET_IPV4_ADDR_LEN];

        // Check if the interface is up
        if (net_if_is_up(iface)) {
            LOG_INF("PING. Interface is up.");
            // Get the IPv4 address of the interface
            if_addr = net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED);
            LOG_INF("PING. Interface Index: %d", net_if_get_by_index(iface));
            if (if_addr) {
              net_addr_ntop(AF_INET, &if_addr->address.in_addr, buf, sizeof(buf));
              LOG_INF("PING. Checking interface with IPv4 Address: %s", log_strdup(buf));

              struct net_linkaddr *link_addr = net_if_get_link_addr(iface);

              if (link_addr) {
                LOG_INF("PING. Interface ID: enx%02x%02x%02x%02x%02x%02x",
                        link_addr->addr[0], link_addr->addr[1], link_addr->addr[2],
                        link_addr->addr[3], link_addr->addr[4], link_addr->addr[5]);
           
            // Optionally, also print it in standard colon-separated format for clarity
                LOG_INF("PING. MAC Address: %02x:%02x:%02x:%02x:%02x:%02x",
                        link_addr->addr[0], link_addr->addr[1], link_addr->addr[2],
                        link_addr->addr[3], link_addr->addr[4], link_addr->addr[5]);
              }

              LOG_INF("PING. Interface pointer (address): %p", iface);
                 
              // Compare with the target IP address
              if (strcmp(buf, "10.131.17.2") == 0) {
                LOG_INF("PING. Found the correct network interface.");
                *(struct net_if **)user_data = iface;  // Store the correct interface in user_data
              }
              LOG_ERR("PING. Failed to find the correct network interface");
              *(struct net_if **)user_data = iface; //Store any interface it found
              LOG_INF("PING. Found interface with IPv4 Address: %s", log_strdup(buf));
            }
        }else{
          LOG_ERR("PING. Interface is down with IPv4 Address: %s", log_strdup(buf));
        }
    }

    void ping(const char *ip_addr_str) {
        LOG_INF("PING.Trying ping to IP: %s", log_strdup(ip_addr_str));

        struct sockaddr_in addr;
        struct net_if *iface = NULL;  // Interface pointer
        int sock, ret;
        char recv_buf[128];  // Buffer to receive ping reply
        static uint16_t ping_seq_num = 0;
        char buf[NET_IPV4_ADDR_LEN];

        // Iterate over all network interfaces
        net_if_foreach(iface_callback, &iface);

        if (iface == NULL) {
          LOG_ERR("PING.Failed to find the correct network interface");
    /*
          iface = net_if_get_default();
          if (!net_if_is_up(iface)) {
            LOG_INF("PING. Default unterface is down");
          }else if(!(iface=net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET))))
          {
            LOG_ERR("PING. No first Ethernet interface found.");
          }
        }
    */
     
        // Create an IPv4 RAW socket for ICMP
        sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
        if (sock < 0) {
            LOG_ERR("PING.Failed to create socket, error %d", errno);
            return;
        }
        LOG_INF("PING.Ping socket successfully open");

        // Set up the destination address
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;
        inet_pton(AF_INET, ip_addr_str, &addr.sin_addr);

        if (net_if_is_up(iface)) {
            LOG_INF("PING.Ethernet interface is up.");
        } else {
            LOG_ERR("PING.Ethernet interface is down.");
            close(sock);
            return;
        }

        struct net_if_addr *if_addr = net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED);
        if (if_addr) {
            net_addr_ntop(AF_INET, &if_addr->address.in_addr, buf, sizeof(buf));
            LOG_INF("PING.Ethernet interface IPv4 Address: %s", log_strdup(buf));
        } else {
            LOG_ERR("PING.No IPv4 address assigned to the correct interface.");
            close(sock);
            return;
        }
        //check_network_interfaces();
        ping_seq_num++;

        // Send ICMP Echo Request (ping) using the correct interface
        LOG_INF("PING.Sending ping request to %s", log_strdup(ip_addr_str));
        ret = net_icmpv4_send_echo_request(iface, &addr, ping_seq_num, PING_ID, 1);
        if (ret < 0) {
            LOG_ERR("PING.Failed to send ping request, error %d", ret);
            close(sock);
            return;
        }
        LOG_INF("PING.Ping request successfully sent");

        // Set socket receive timeout
        struct timeval timeout;
        timeout.tv_sec = PING_TIMEOUT_MS / 1000;
        timeout.tv_usec = (PING_TIMEOUT_MS % 1000) * 1000;
        setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));

    /*
        // Wait for an ICMP Echo Reply
        while (true) {
            ret = recv(sock, recv_buf, sizeof(recv_buf), 0);
            if (ret > 0) {
                // Parse the ICMP packet
                uint8_t icmp_type = recv_buf[20];  // ICMP type is the 21st byte
                uint8_t icmp_code = recv_buf[21];  // ICMP code is the 22nd byte
                uint16_t icmp_id = (recv_buf[24] << 8) | recv_buf[25];  // ICMP identifier
                uint16_t icmp_seq = (recv_buf[26] << 8) | recv_buf[27]; // ICMP sequence number

                // Check if it's an ICMP Echo Reply (type 0, code 0) and matches our ID and sequence
                if (icmp_type == 0 && icmp_code == 0 && icmp_id == PING_ID && icmp_seq == ping_seq_num) {
                    LOG_INF("PING.Ping reply received from %s", log_strdup(ip_addr_str));
                    break;
                }
            } else if (ret == -1 && errno == EAGAIN) {
                LOG_ERR("PING.Ping timeout.");
                break;
            } else {
                LOG_ERR("PING.Failed to receive ping reply, error %d", errno);
                break;
            }
        }
    */
        // Clean up
        close(sock);
        LOG_INF("PING.Ping socket closed!");
    }

  • Hi,

    To verify, the issue is that the Ethernet interface does not get an IPv4 address?

    Are you setting the IPv4 address yourself, or do you expect to get one from a DHCPv4 server? Do you have CONFIG_NET_DHCPV4 enabled in prj.conf?

    Can you upload your complete project? If you do not want to share it in a public ticket, please let me know, and I will make the ticket private.

    Best regards,
    Marte

Related