This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Determine which interface (PPP or ethernet) a UDP packet is received on?

I have an application with an ethernet and PPP interface.  I have a UDP socket that I would like to receive packets on from either interface.  This I have working.  I then need to be able to send a reply back to the IP address that sent the packet using the same interface that I received the packet on.  Using revncfrom(), I see no way to determine which interface the packet came in on.  Is there some other way to determine this?  If not, maybe adding the socket option IP_PKTINFO. 

As background, thread NDK PPP SEND VIA SPECIFIC INTERFACE had some good information about how to manipulate the route table to force using a specific interface. There was mention of possibly adding a socket option SO_BINDTODEVICE but It wasn't in the latest release NDK_2_25_00_09.  Any status on this?   

Thanks

  • Hi Steve,

    Is the app that you want to receive data on a server or a client? Can you elaborate on the use case for receiving on either interface? Does receiving on one interface mean that communication will always happen on that interface or does the reply need to go to either interface depending on the where the reply came from?

    Unfortunately, the socket option SO_BINDTODEVICE has not been implemented yet and there is no current support for IP_PKTINFO.

    Gilbert
  • The use case is having a field device that has 2 interfaces for redundancy. The device will normally listen on a udp socket with packets coming in on the ethernet interface. If the computer that talks to the field device loses communication on the ethernet interface, it will try to communicate to the device via a cell modem that attaches to the device over a PPP connection on a serial port. Therefore, the device always needs to send back reply packets on the interface that the request packet was received on otherwise the host computer will not receive it. I could have the device send back replys on both interfaces all of the time but that would rack up quite a bit a cell data given we have 1000's of devices.
  • Are you binding your socket to a socket address struct set for INADDR_ANY or are you binding it to a specific address?

    For example:

        memset(&localAddr, 0, sizeof(localAddr));
        localAddr.sin_family = AF_INET;
        localAddr.sin_addr.s_addr = htonl(INADDR_ANY); // <-- socket address struct
        localAddr.sin_port = htons(arg0);
    
        status = bind(server, (struct sockaddr *)&localAddr, sizeof(localAddr));
    
       …
    
        bytesRcvd = recvfrom(server, buffer, UDPPACKETSIZE, 0,
                            (struct sockaddr *)&clientAddr, &addrlen);  //this returns data from PC side app over both Ethernet and PPP interfaces
    

  • I am using INADDR_ANY and the socket does receive from both interfaces.  The problems becomes

    knowing which interface a packet is received on and then forcing the socket to use that interface when

    sending back a reply packet. 

  • recvfrom should provide you the address that data was received from. It would be the fifth argument in the code snippet posted above. You should be able to send data back using that address. TIRTOS has a udpecho example that you can look at that does something similar.
  • Your are correct but understand that the udpecho example only has 1 network interface.  When there are 2 network interfaces, the stack has rules that determine which network interface the packet will go out on.  I'm looking for a way to set the rules (on a per socket basis) so I can send packets on which ever interface I want.  Having 2 network interfaces means that the device is actually on 2 separate networks.    

  • Please find the modified version of the udpEcho example for Tiva at the end of the message.  The  example has been updated to have 2 interfaces:

     

    1. PPP interface
      1. Static IP address 172.16.0.4, configured via the Linux pppd command
      2. [You may be setting your PPP IF up differently, but this example follows the TI-RTOS tcpEchoPPP example (please refer to the tcpEchoPPP example readme file for more info on pppd)]
    2. Ethernet interface
      1. Static IP address configured to be 10.90.90.24 via the application configuration file (*.cfg file)

     

    2 PCs were used to communicate with the Tiva device

     

    1. Windows PC
      1. IP address 10.90.90.5 on an Ethernet IF
    2. Linux PC
      1. IP address 172.16.0.2, configured with pppd command (again, you may be setting up your PPP connection differently)

     

    Note that the example’s socket code is identical to the standard udpEcho example, which has a single IF.

     

    This updated example can and will receive data from either of the 2 IF’s.  It behaves as follows:

     

    Case A:

    1. udpEcho app is blocked on the call to recvfrom()
    2. UDP data is sent from the Winows PC via Ethernet to the 10.90.90.24 address.  PC’s address is 10.90.90.5
    3. The app’s recvfrom() call (udpEcho.c, line 105) receives the data and the sender’s address (10.90.90.5) is stored in the clientAddr struct
    4. The app replies with a sendto() call (udpEcho.c line 109), using the same clientAddr struct.  This reply will be sent back to address 10.90.90.5, via the Ethernet IF
    5. -> the reply is sent back on the same IF it was received from

     

    Case B:

    1. udpEcho app is blocked on the call to recvfrom()
    2. UDP data is sent from the Linux PC via PPP (USB cable) to the 172.16.0.4 address.  In this case, the PC is configured with a PPP IF that has IP address 172.16.0.2
    3. The app’s recvfrom() call (udpEcho.c, line 105) receives the data and the sender’s address (172.16.0.2) is stored in the clientAddr struct
    4. The app replies with a sendto() call (udpEcho.c line 109), using the same clientAddr struct.  This reply will be sent back to address 172.16.0.2, via IP address 172.16.0.4 (the PPP IF)
    5. -> the reply is sent back on the same IF it was received from

     

    In both cases, the reply is sent back on the same IF it was received from.  Isn’t this what you are asking for?

    0815.udpEth+PPP.tar.gz

  • Thanks for the reply.  The difference in our application from the example that I didn't mention is that instead of having 2 different host PCs with different IP addresses,  we have single host (1 IP address) that has an ethernet connection to the Tiva device and a cell connection to the modem that the tiva device has a PPP connection to.  So, from the perspective of the Tiva device, packets that come in on the PPP interface and ethernet interface both have the same clientAddr struct.  The stack then follows its routing rules to determine which interface to send on which isn't the last interace it received on.  I'll dig into it more and see if I can find any options and let you know.       

  • I found out how to determine which interface a packet is received on.
    With ps being the handle to the socket:

    SB * pSB;
    llEnter();
    pSB = (SB *) ps->hSBRx;
    ifID = IFGetIndex(pSB->pPktLast->hIFRx);
    llExit();
  • Ok, I see that the previous solution/example won’t work due to the new details you provided. But sounds like you figured out how to get past your issue, great news! If so, could you please mark this thread as ‘answered?’