WIZnet Developer Forum

Sending UDP unicast fails to get ARP response?

I have managed to piece together some details of how to get DHCP working, finally. I did this in order to be able to send UDP unicast packets through a gateway.

I press a button to run the sendto() command to send the UDP unicast message. I understand that with a UDP unicast message it must trigger an ARP request first to receive the hardware address of the gateway.
I see this ARP request on the network, but it never gets a response from the gateway. Additionally, I cannot then trigger the UDP message again after this. I have checked the structure of the ARP request against one from my PC and it seems to be identical other than some padding (See picture below).

You can see the device handling the DHCP configuration here, followed by an ARP packet

Side by side of an ARP request from my laptop (which received a response) and my Wiznet part:

My initialisation:

void w5100s_init(void)
{

    // Pull the chip out of reset
    PIN_setOutputValue(ethPinHandle, Board_ETHERNET_RST, 1);
    // Wait 62ms for startup
    Task_sleep(62*(1000/Clock_tickPeriod));

    intr_kind temp = IK_SOCK_ALL;
    unsigned char W5100S_AdrSet[2][4] = {{2,2,2,2},{2,2,2,2}};
    /*
     */
    temp = IK_DEST_UNREACH;

    if(ctlwizchip(CW_INIT_WIZCHIP,(void*)W5100S_AdrSet) == -1)
    {
        printf("W5100S initialized fail.\r\n");
    }

    if(ctlwizchip(CW_SET_INTRMASK,&temp) == -1)
    {
        printf("W5100S interrupt\r\n");
    }

    uint8_t tmp1, tmp2;
    uint8_t phyChecks = 0;

    // Check a link exists (i.e. Ethernet connectet)
    while(1){
        ctlwizchip(CW_GET_PHYLINK, &tmp1 );
        ctlwizchip(CW_GET_PHYLINK, &tmp2 );
        if(tmp1==PHY_LINK_ON && tmp2==PHY_LINK_ON) break;
        phyChecks++;
        if(phyChecks>4) break; // TODO Use this to return 0; and do better management of Ethernet in general
    }

    ctlnetwork(CN_SET_NETINFO, (void*) &gWIZNETINFO);

    /* Initialise the socket for UDP unicast datalogging */
    do{
        setSn_RTR(SOCKET_UDP2, 2000)                         // Retry time: 2000*100us = 0.2s
        setSn_RCR(SOCKET_UDP2, 2);                           // Num retries
        setSn_IMR(SOCKET_UDP2, 0xFF-6);                      // Int Mask Reg (Turn off Recv, Dcon, Con interrupts)
        setSn_MR(SOCKET_UDP2, Sn_MR_UDP);                    // Unicast, UDP
        setSn_MR2(SOCKET_UDP2,0x20);                         // Block UDP broadcast packets
        setSn_PORT(SOCKET_UDP2, defaultUdpSrcPort);          // Source port
        setSn_DPORT(SOCKET_UDP2, defaultUdpDstPort);         // Destination port
        setSn_CR(SOCKET_UDP2, Sn_CR_OPEN);                   // Command Reg: open socket
    } while(getSn_SR(SOCKET_UDP2) != SOCK_UDP);              // Check socket has been configured and started
    
}

My DHCP setup:

/* Configure DHCP if possible */
void dhcp_setup(void)
{
    // DHCP clock is started with the task

    uint8_t dhcp_retry = 2;

    uint32_t ret;

    /* DHCP Process */
    DHCP_init(0, test_buf);
    reg_dhcp_cbfunc(&dhcp_assign, &dhcp_update, &dhcp_conflict);
    if (gWIZNETINFO.dhcp == NETINFO_DHCP) {       // CHEP DHCP
        // Start DHCP
        while (1) {
            ret = DHCP_run();

            if (ret == DHCP_IP_LEASED) {
                //printf("DHCP Success\r\n");
                break;
            }
            else if (ret == DHCP_FAILED) {
                dhcp_retry++;
            }

            if (dhcp_retry > 3) {
                //printf("DHCP Fail\r\n");
                break;
            }
        }
    }

    ctlnetwork(CN_SET_NETINFO, (void*) &gWIZNETINFO);

}

Trying to send the UDP packet:

static void logPacketOverEthernet(union ConcentratorPacket * packet, int8_t rssi, uint8_t length)
{
    // determine the size
    uint8_t packetLength = length + sizeof(rssi);

    // Send the packet
    int32_t udpTxStatus = sendto(SOCKET_UDP2, (uint8_t *)packet, packetLength, gWIZNETINFO.gw, defaultUdpDstPort);
    if(udpTxStatus<0){
        // failed
    }

}

Can someone tell me what’s wrong here?

Also, is there any better documentation on the ioLibrary? Most of what I’ve put together I have had to do so from snippets here and there because I can’t find one good resource that documents the library and how to use it. It’s very frustrating!

Try changing MAC address to the laptop’s one (disconnecting laptop prior connecting WIZ with this MAC address) so that WIZ would look like your laptop and see if request will get through the switch/router. Connect WIZ into the port laptop was connected to.

I do not think you have control over padding in ARP request, and do not remember it was causing issues.

Unfortunately that didn’t work.

I am able to see the DHCP lease on the router itself, it just seems to not respond to ARP at all. I’ve tried two different routers with the same result.

Still struggling with this, can someone please help?

There’s utility called NMAP, and you can use it sending exactly the packet W5100 sends, but from your PC - to prove or deny hypothesis that padding is the cause of the issue. First send the data PC sends to see (and prove) if it will yield reply, then send packet of W5100 with padding and see if it will also get reply or not.

I’ve downloaded NMAP, but it seems to have a pretty steep learning curve for the network amateur. I have no idea how to send a fake packet over my ethernet connection. As far as I understand I want to use the nping functionality but beyond that I’m lost.

That’s correct. I think you must make the binary file with contents of the packet, and then feed it to NMAP together with command line options. Start Wireshark on the PC, and run NMAP on it - and you must see packet exchange in Wireshark log.

Struggling to find any documentation on this.
There’s and argument to load a host file (https://nmap.org/book/man-target-specification.html), and also an argument to append data (–data).

I can’t find something that will just allow me to feed in the hex of the ARP packet.

My best attempt so far was to use a command to try to spoof the ARP packet.

nping -e eth2 --arp-type ARP --arp-sender-mac 00:08:dc:ff:ff:89 --arp-sender-ip 192.168.1.101 --arp-target-ip 192.168.1.1 --dest-ip 192.168.1.1 -c 1

This does get a response, but when I look at the packet it also still originates from my laptop MAC, so it’s hard to call it an accurate comparison:

Copyright © 2017 WIZnet Co., Ltd. All Rights Reserved.