How to Obtain IP Destination Address from UDP Packet

Ben 106 Reputation points
2021-06-17T14:05:42.093+00:00

I am using Azure RTOS (formerly Express Logic) NetX v. 5 on a Reneasas S7G2 platform with Synergy SSP.

In our application, we receive UDP packets - both directed at our IP address and directed at the IP Broadcast address - and I need to differentiate between the two.

The function nx_udp_packet_info_extract() has the ip_address parameter, but this is the source address - not the destination address.

How can I get the destination address from the IP header of a UDP packet? Or - more specifically - is there an API call that will allow me to determine if a received UDP packet was sent to the broadcast address or my device's specific IP address?

Thanks for your help.

Regards,

Ben

Azure RTOS
Azure RTOS
An Azure embedded development suite including a small but powerful operating system for resource-constrained devices.
341 questions
0 comments No comments
{count} votes

Accepted answer
  1. Ben 106 Reputation points
    2021-06-22T14:31:20.297+00:00

    TiejunZhou:

    We are implementing support for the EtherNet/IP industrial protocol in our measurement gauge. The EtherNet/IP spec requires differentiating between received UDP packets sent to the broadcast vs. the "directed" destination address. This is needed thwart DDOS attacks. If the incoming UDP packet has the broadcast address as its destination, the protocol backs off for a random period of time before sending the response. If the incoming UDP packet is "directed," then the protocol sends the response immediately.

    ......................

    I also have an additional question. I found in the NetX documentation and source code that the NX_PACKET structure has a pointer to the IPv4 header of the received UDP packet. I tried using the following code to extract and examine the IP destination address and network mask of the received UDP packet, but I'm getting very inconsistent results in the values found in the "nx_ip_header_destination_ip" field:

    static uint8 IsUdpBroadcastPacket (NX_PACKET *pCmdPacket) {  
        ULONG           destinationIpAddr;  
        ULONG           inverseNetworkMask;     // Clear out the network portion, keep only the host portion of the address.  
        NX_IPV4_HEADER *pIpV4Header;  
        uint8           returnValue = false;  
    
        do {  
            if (NULL == pCmdPacket) { break; }  
    
            if (NX_IP_VERSION_V4 != pCmdPacket->nx_packet_ip_version) { break; }  
    
            if (NULL == pCmdPacket->nx_packet_address.nx_packet_interface_ptr) { break; }  
    
            pIpV4Header = (NX_IPV4_HEADER*)pCmdPacket->nx_packet_ip_header;  
            destinationIpAddr = pIpV4Header->nx_ip_header_destination_ip;  
            inverseNetworkMask = ~(pCmdPacket->nx_packet_address.nx_packet_interface_ptr->nx_interface_ip_network_mask);  
    
            msgLog("%s: UDP Packet - Inverse Network mask: 0x%8.8lX, Dest Addr: 0x%8.8lX", __FUNCTION__, inverseNetworkMask, destinationIpAddr);  
    
            // If the host portion of the IPV4 address is all Fs, then  
            // this is a broadcast address.  
            returnValue = (destinationIpAddr & inverseNetworkMask) == (0xFFFFFFFFUL & inverseNetworkMask);  
        } while (false);  
    
        return returnValue;  
    }  
    
      
    static NX_UDP_SOCKET udpCIP;  
    
    void eips_usersock_udpCIPReceive () {  
    
    ... %< %< snippet %< %< ...  
    
        NX_PACKET  *cmdPacket;  
        uint8       isUdpBroadcastPacket = 0;  
        char        packetPayload[32];  
        ULONG       pktLen;  
        char        recvBuf[USERSOCK_MAX_BUF_SIZ];  
        UINT        returnCode;  
    
        returnCode = nx_udp_socket_receive(&udpCIP, &cmdPacket, NX_NO_WAIT);  
    
    ... %< %< snippet %< %< ...  
    
        returnCode = nx_packet_data_retrieve(cmdPacket, recvBuf, &pktLen);  
    
    ... %< %< snippet %< %< ...  
    
        isUdpBroadcastPacket = IsUdpBroadcastPacket(cmdPacket);  
    
        strncpy(&packetPayload[0], &recvBuf[0], sizeof(packetPayload));  
        packetPayload[sizeof(packetPayload) - 1] = '\0';  
        if (pktLen < sizeof(packetPayload)) { packetPayload[pktLen] = '\0'; }  
        msgLog("%s: Received UDP packet at the %s address, PAYLOAD: <%s>",  
                __FUNCTION__, isUdpBroadcastPacket ? "BROADCAST" : "DIRECTED", &packetPayload[0]);  
    }  
    

    I'm using a separate Linux system to send UDP broadcast packets to my device via netcat:

    me@somewhere:~$ echo 'BROADCAST 1' | nc -b -u 192.168.1.255 44818  
    me@somewhere:~$ echo 'BROADCAST 2' | nc -b -u 192.168.1.255 44818  
    me@somewhere:~$ echo 'BROADCAST 3' | nc -b -u 192.168.1.255 44818  
    me@somewhere:~$ echo 'BROADCAST 4' | nc -b -u 192.168.1.255 44818  
    

    With the results of my code and the NetX destination address analysis:

    [   
    {"Time":     285833, "Msg": "IsUdpBroadcastPacket: UDP Packet - Inverse Network mask: 0x000000FF, Dest Addr: 0xE8181ECA"},  
    {"Time":     285833, "Msg": "eips_usersock_udpCIPReceive: Received UDP packet at the DIRECTED address, PAYLOAD: <BROADCAST 1 >"},  
    
    {"Time":     289049, "Msg": "IsUdpBroadcastPacket: UDP Packet - Inverse Network mask: 0x000000FF, Dest Addr: 0x0008CBC0"},  
    {"Time":     289049, "Msg": "eips_usersock_udpCIPReceive: Received UDP packet at the DIRECTED address, PAYLOAD: <BROADCAST 2 >"},  
    
    {"Time":     291112, "Msg": "IsUdpBroadcastPacket: UDP Packet - Inverse Network mask: 0x000000FF, Dest Addr: 0xE8181ECA"},  
    {"Time":     291112, "Msg": "eips_usersock_udpCIPReceive: Received UDP packet at the DIRECTED address, PAYLOAD: <BROADCAST 3 >"},  
    
    {"Time":     293224, "Msg": "IsUdpBroadcastPacket: UDP Packet - Inverse Network mask: 0x000000FF, Dest Addr: 0xFFFFFFFF"},  
    {"Time":     293224, "Msg": "eips_usersock_udpCIPReceive: Received UDP packet at the BROADCAST address, PAYLOAD: <BROADCAST 4 >"}  
    ]  
    

    Even though the UDP destination address (in reality) is always 192.168.1.255 (0xC0A801FF,) the destination address found in the NetX structure is very inconsistent. The address detection code finds the BROADCAST address only one time out of the four, and this appears to be based on a bogus value of 0xFFFFFFFF rather than the actual broadcast address of 0xC0A801FF.

    Do you have any ideas about this?

    Thank you,

    Ben


1 additional answer

Sort by: Most helpful
  1. Tiejun Zhou 1,131 Reputation points Microsoft Employee
    2021-06-21T01:20:42.723+00:00

    Currently, it is not supported to retrieve destination IP address. Could you describe your use case? This would help us to decide if we will add this kind of API or not.

    1 person found this answer helpful.
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.