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.

how to generally debug a Raw socket NDK stack problem?

Hi,

My program successfully creates a raw socket(AF_RAWETH, SOCK_RAWETH, 0x8892) but I never receive data from it in fdSelect()->fdPoll()->RawEthSockCheck(), anyway case SOCK_READ returns always 0 there in rawethsocket.c.

I want to find out why the incoming packets are swallowed und therefore debug the NDK stack. I have compiled my ndk_2_24_03_35 stack with debug information and I'm able to step into the NDK source code.

Which are the important NDK functions where it makes sense to set debugger breakpoints to see what happens? (Or what other ways can I go?)

Thanks + Bye

P.S.: Common TCP and UDP sockets work without problems in my program. I also use TI example code for the lowlevel driver (nimu_eth.c, ethdriver.c, csl_mac.c and csl_mdio.c) but it doesn't look like it setups the MAC in a way those packets will be skipped already there.

  • I searched for some general suggestions for debugging raw sockets.  I found these two forum threads that might be of some help:

    e2e.ti.com/.../387932

    e2e.ti.com/.../137717

    I wonder if in your case some packets are being filtered away?

    Does this help?

    Thanks,
    Scott

  • Thanks, your links are great, I've patched my source, appropriately. Now I can see (by debugger breakpoint) I receive packets with type 0x8892 in EMAC_RxServiceCheck()->emacDequeueRx()->RxPacket(). After that emacDequeueRx() calls pqPush(). I think it's scheduled for the NDK stack now, right? Now I need to debug if the packet passes through the stack until my call of select(). I'll report back then.

  • Just wanted to chime in a little here...

    As those posts that Scott linked above talk about, yes, it could be that Ethernet frames (containing your raw packets) are being dropped at the driver layer. You need to ensure that the driver is properly configured to handle/accept incoming frames containing raw packets.

    But, let's assume that the driver IS properly configured, and that it has plenty of memory available to store incoming frames from the wire (because if there isn't enough memory, frames will just be dropped, which is also a possibility here). Then, all frames received are passed up to the NDK stack via the function NIMUReceivePacket(). This function is found in the NDK, in the file ti/ndk/stack/nimu/nimu.c.

    Within NIMUReceivePacket(), there is a switch statement that looks at the 'type' field of the Ethernet frame received. There are cases for known and expected types, i.e. IP, IPv6 and ARP.

    The default case of this switch statement is where the raw packet will be passed up the stack (around line 313). All raw packets will come through this part of the code.

    So, this is the point in the code that you want to try to "catch" the packet, to check that you are receiving it.

    Steve
  • An important place was the while()-loop of RawEthSockPcbFind() in rawethsock_pcb.c for me, called from RawEthRxPacket() in raweth.c. I saw there the incoming packet could not accociate to an opened socket. Then I searched where ps->hIF is set and came across case SO_IFDEVICE of RawEthSockSet() in rawethsock.c which opened my eyes that I have to set an interface for my raw socket after I've created it:

    myRawSocket = socket(AF_RAWETH, SOCK_RAWETH, 0x.... /* my special type*/);
    int val = 1;
    setsockopt(myRawSocket, SOL_SOCKET, SO_IFDEVICE, &val, sizeof(val));

    After programming this setsockopt()-call, suddenly select() returned and it wasn't hard to see why the common function recv() does not work for NDK raw sockets, and so used recvnc() instead as response to a successfully returning fdSelect():

    fd_set fdRead; struct timeval timeout; 
    timeout.tv_sec = 1; timeout.tv_usec = 0;
    FD_ZERO(&fdRead); FD_SET(myRawSocket, &fdRead);
    if (fdSelect(0, &fdRead, 0L, 0L, &timeout) > 0) {
      HANDLE hbuff; char* pbuf;
      Length = recvnc (myRawSocket, (void**)&pbuf, /*0*/MSG_DONTWAIT, &hbuff); // returns the address to the packet data
      memcpy(pMyPacketBuffer, pbuf, Length);

    Thanks for your help. TI support is great!

    P.S.: At present I'm searching for the reason why RawEthTxPacket()->NIMUCreatePacket() returns with ENOBUFS on a raw socket sending trial, and it seems I must recompile the NDK stack giving more Ethernet frame buffers (e.g. #define PKT_NUM_FRAMEBUF    (192 * 32))...

  • P.S.: At present I'm searching for the reason why RawEthTxPacket()->NIMUCreatePacket() returns with ENOBUFS on a raw socket sending trial, and it seems I must recompile the NDK stack giving more Ethernet frame buffers (e.g. #define PKT_NUM_FRAMEBUF    (192 * 32))...

    You may not need to rebuild the stack for this.  Can you check your configuration file (*.cfg) for the value of the following?

    Global.enableCodeGeneration = [true, false];

    What value is it set to?

    If you have it set to false, then you must configure the buffer sizes as you already have discovered, by rebuilding the stack.


    However, if it is true, then you can use the XGCONF configuration tool to change these settings in your app's *.cfg file.  You won't need to rebuild the stack.

    Thanks for your help. TI support is great!

    Glad we could help you!

    Cheers,

    Steve

  • I found out it is not necessary to increase PKT_NUM_FRAMEBUF , but instead freeing with recvncfree() after I used recvnc() is a better idea. :-D

    P.S.: The module Global is not used in my .cfg file.