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.

Failure to read BOOTP messages from C6678

I have an EVM6678L connected to a Windows 7 laptop by Ethernet. The laptop has all firewalls disabled.
The EVM is set to boot from Ethernet and is sending BOOTP packets every 3 seconds to port 67 as expected.
Wireshark running on the laptop sees these correctly-formatted BOOTP packets coming in.

I have a program running on the laptop with a socket successfully bound to port 67. I can see this using
CurrPorts.exe. Nothing else is shown as accessing port 67.

The program never sees any packets coming in.

If I run a program in the EVM that sends ordinary UDP packets to port 67, Wireshark sees them coming in
and reports that they are corrupt BOOTP packets, but now, my program gets them.

Any idea what's going on here?

Does anyone have code for Windows 7 that can actually read these packets?

  • Hi Peter,

    Is the UDP packet that you get in the application is a unicast packet or a broadcast packet. The BootP is a braodcast packet.

    Thanks,

    Arun.

  • I'm not exactly sure what you are asking.

    The BOOTP packets I cannot receive are broadcast packets (to MAC address FF-FF-FF-FF-FF-FF).

    The packets I can receive are sent to the PC's actual MAC address ( just to ensure that my code wasn't broken).

  • Hi Peter,

    That is what i was asking. This means that for some reason your code is not receiving any broadcast packaet. The Wireshark actually sniff at the PHY layer.  Please take a look at your application to see if you can receive any broadcast packet.

    Thanks,

    Arun.

  • There's not much to look at - it's quite trivial. The relevant part follows:

    int inner_bootp(SOCKET boot_sock) {
       sockaddr_in   boot;
       sockaddr_in   s;
       unsigned char B[400];
       memset(&boot, 0, sizeof(boot));
       boot.sin_family      = AF_INET;
       boot.sin_addr.s_addr = INADDR_ANY;
       boot.sin_port        = htons(67);
       if (bind(boot_sock, (sockaddr *)&boot, sizeof(boot))==SOCKET_ERROR) return 1;
       DWORD br = TRUE;
       if (setsockopt(boot_sock, SOL_SOCKET, SO_BROADCAST, (char *)&br, sizeof(br))==SOCKET_ERROR) return 2; // fatuous
       printf("Waiting for BOOTP...\n");
       for (;;) {
          for (;;) {
             fd_set  readFDS;
             timeval tout;
             tout.tv_sec  = 10;
             tout.tv_usec = 0;
             FD_ZERO(&readFDS);
             FD_SET(boot_sock, &readFDS);
             int t = select(-1, &readFDS, 0, 0, &tout);
             if (t==SOCKET_ERROR) return 3;
             if (t) break;   // not time-out *** never breaks here ***
             if (MessageBox(0, L"Still waiting", L"No BOOTP detected", MB_RETRYCANCEL | MB_TOPMOST) != IDRETRY) return 0;
          }
          int size = sizeof(s);
          if (recvfrom(boot_sock, (char *)B, sizeof(B), 0, (SOCKADDR *)&s, &size)==SOCKET_ERROR) return 4;
          if (B[0] != 1) {    // BOOTP
             printf("non-BOOTP received\n");
          } else {
             int Id = (B[4]<<24) | (B[5]<<16) | (B[6]<<8) | B[7];
             if (Id == 0x12345678) break;
             printf("unexpected transaction ID %08X\n",  Id);
          }
       }
       char info[20];
       sprintf(info, "%02x-%02x-%02x-%02x-%02x-%02x", B[28],B[29],B[30],B[31],B[32],B[33]);
       printf("Info: Bootp request from:\t%s\n", info);
       return 0;
    }

  • Here's the complete program:

    #include "stdafx.h"
    #include <stdio.h>
    #include <winsock2.h>
    #pragma comment(lib, "ws2_32.lib")

    int inner_bootp(SOCKET boot_sock) {
       sockaddr_in   boot;
       sockaddr_in   s;
       unsigned char B[400];
       memset(&boot, 0, sizeof(boot));
       boot.sin_family      = AF_INET;
       boot.sin_addr.s_addr = INADDR_ANY;
       boot.sin_port        = htons(67);
       if (bind(boot_sock, (sockaddr *)&boot, sizeof(boot))==SOCKET_ERROR) return 1;
       DWORD br = TRUE;
       if (setsockopt(boot_sock, SOL_SOCKET, SO_BROADCAST, (char *)&br, sizeof(br))==SOCKET_ERROR) return 2; // fatuous
       printf("Waiting for BOOTP...\n");
       for (;;) {
          for (;;) {
             fd_set  readFDS;
             timeval tout;
             tout.tv_sec  = 10;
             tout.tv_usec = 0;
             FD_ZERO(&readFDS);
             FD_SET(boot_sock, &readFDS);
             int t = select(-1, &readFDS, 0, 0, &tout);
             if (t==SOCKET_ERROR) return 3;
             if (t) break;   // not time-out
             if (MessageBox(0, L"Still waiting", L"No BOOTP detected", MB_RETRYCANCEL | MB_TOPMOST) != IDRETRY) return 0;
          }
          int size = sizeof(s);
          if (recvfrom(boot_sock, (char *)B, sizeof(B), 0, (SOCKADDR *)&s, &size)==SOCKET_ERROR) return 4;
          if (B[0] != 1) {    // BOOTP
             printf("non-BOOTP received\n");
          } else {
             int Id = (B[4]<<24) | (B[5]<<16) | (B[6]<<8) | B[7];
             if (Id == 0x12345678) break;
             printf("unexpected transaction ID %08X\n",  Id);
          }
       }
       char info[20];
       sprintf(info, "%02x-%02x-%02x-%02x-%02x-%02x", B[28],B[29],B[30],B[31],B[32],B[33]);
       printf("Info: Bootp request from:\t%s\n", info);
       return 0;
    }

    void WaitForBOOTP(void) {
       SOCKET boot_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
       if (boot_sock==INVALID_SOCKET) {
          printf("failed to create bootp socket (%d)\n", WSAGetLastError());
       } else {
          int n = inner_bootp(boot_sock);
          if (n) printf("wait for bootp fails %d (%d)\n", n, WSAGetLastError());
          closesocket(boot_sock);
       }
    }

    void main() {
       WSADATA Data;
       if (WSAStartup(MAKEWORD(1, 1), &Data)) {
          printf("Unable to initialize WinSock for host info\n");
       } else {
          WaitForBOOTP();
          WSACleanup();
          printf("Done\n");
       }
    }

  • I assume that TI must have tested the reception of BOOTP packets under WIndows 7. What program was used for this?

  • Hi Peter,

    As you mentioned that the packet is seen on the the wireshark. So the packet is indeed reaches the PC. I am not an expert in windows programming. But I thought you said that you your code with unicast packet and that worked. Can you capture any broadcast packet? The ideal way to test is with a DHCP packet. See if your code can see the DHCP packet.

    Thanks,

    Arun.

  • Hi,

    I have done some more experiments that show the following:

    1. An ARP broadcast from the DSP is received by W7 and is processed correctly.
    2. All other broadcasts I have tried (Destination MAC FF-FF-FF-FF-FF-FF) arrive at W7 (Wireshark) but are then dropped before reaching my code.

    One of the test packets that I have tried sending repeatedly from the DSP in case 2 is:

    ff ff ff ff ff ff  dst MAC
    40 5f c2 b9 21 d1  src MAC
    08 00              IPV4
    45 00              IPver 4, IHL 5
    00 5c              total length
    00 00 00 00       
    05 11
    b5 92              checksum
    00 00 00 00        src IP
    00 00 00 00        dst IP
    c0 c0              UDP src port
    c0 c0              UDP dst port
    00 48              UDP len
    00 00              UDP checksum
    00 00 ....         UDP payload

    This packet is seen by Wireshark as well-formed, but is not received by my program.

    I have no problem reading non-broadcast packets.

    This issue is driving me mad. The only response I have had about this issue from other forums has been to suggest that I need to set the option SO_BROADCAST on my receiving socket. I have done this (even though the Microsoft documentation is quite clear that this is for transmission only) and it has no effect.

    As I mentioned before, TI must have tested that the BOOTP packets can be read under Windows 7 (otherwise, what's the point of generating them?). What special thing is that code doing?

    Peter

  • Peter,

    As i mentioned, we do not have winsock program sample inside TI. But can you confirm that the same packets if you send from let us say another program, you can receive it through your code. Because i still suspect the application running in the PC as you can see the packet in the PC wire.

    Thanks,

    Arun.

  • It clearly is something to do with the W7 side, but nobody seems to have a clue as to what the problem could be.

    I am surprised that TI has not tested the reception of these packets on what must be a major platform for development.

    What I'm really looking for is anybody who might be able to give the smallest hint as to what's going on here.

  • Hi Peter,

    some time ago i had a similar problem. In Windows 7, I was not able to read the BOOTP packets, although Wireshark saw them.
    I used a little trick to solve my problem. Instead of trying to read only BOOTP packets, I read all, and then processed only BOOTP packets. I think that the main points in the code were:

    1) socket call using SOCK_RAW:

    mysocket = socket(AF_INET, SOCK_RAW, IPPROTO_IP);

    2) bind to any port

    memset(&dest, 0, sizeof(dest));
    dest.sin_addr.s_addr = inet_addr(strLocalIP);
    dest.sin_family = AF_INET;
    bind(mysocket,(struct sockaddr *)&dest, sizeof(dest));

    3) Setting SIO_RCVALL after bind (I think I also put a timeout above 3 seconds)

    int in;
    int iArg = RCVALL_IPLEVEL;
    WSAIoctl(mysocket, SIO_RCVALL, &iArg, sizeof(int), 0, 0, (LPDWORD) &in , 0 , 0);

    4) checking ports / protocol on any received packet to process only those with:
    protocol IPPROTO_UDP, source port 68 and dest port 69


    When I received a packet that satisfied all the conditions above, it had the C6678 MAC inside.

    I know that this is like cracking a nut with a sledgehammer, and it may present some other problems. However, at least it worked for me and I was able to detect the C6678 and get its MAC under Windows 7 (Windows 7 Pro SP1 32 bit).

    One more thing: are you running your program as administrator? (explicitly using the "Run as administrator" option). It my be needed to be able to receive this kind of packets.

    I hope this idea helps you!

    Best regards,
    Alejandro

  • Thank you very much. At last a suggestion that actually works!

    In case anyone else hits these problems, here is the significant part of a program that will access BOOTP packets and extract the MAC address of the C6678.

    This program does need to be run as administrator under Windows 7.

    #include "stdafx.h"
    #include <stdio.h>
    #include <winsock2.h>
    #include <MSTcpIP.h>
    #pragma comment(lib, "ws2_32.lib")

    int isBOOTP(unsigned char *B) {
       if (B[9] != 17) return 0;                 // not UDP
       if (B[20] != 0 || B[21] != 68) return 0;  // not BOOTP client
       if (B[22] != 0 || B[23] != 67) return 0;  // not BOOTP server
       if (B[28] != 1)                return 0;  // not BOOTP request
       if (B[32] != 0x12 ||
           B[33] != 0x34 ||
           B[34] != 0x56 ||
           B[35] != 0x78)             return 0;  // not expected ID
       return 1;                                 // correct BOOTP packet
    }

    int inner_bootp(SOCKET boot_sock) {
       sockaddr_in   boot;
       sockaddr_in   s;
       unsigned char B[400];
       memset(&boot, 0, sizeof(boot));
       boot.sin_family      = AF_INET;
       boot.sin_addr.s_addr = inet_addr("192.168.2.100");  // IP address of this machine
       boot.sin_port        = htons(67);
       if (bind(boot_sock, (sockaddr *)&boot, sizeof(boot))==SOCKET_ERROR) return 1;
       DWORD in, arg = RCVALL_IPLEVEL;
       if (WSAIoctl(boot_sock, SIO_RCVALL, &arg, sizeof(int), 0, 0, &in, 0, 0)) return 2;
       printf("Waiting for BOOTP...\n");
       for (;;) {
          for (;;) {
             fd_set  readFDS;
             timeval tout;
             tout.tv_sec  = 10;  // long enough for at least 3 BOOTP packets to be sent
             tout.tv_usec = 0;
             FD_ZERO(&readFDS);
             FD_SET(boot_sock, &readFDS);
             int t = select(-1, &readFDS, 0, 0, &tout);
             if (t==SOCKET_ERROR) return 3;
             if (t) break;   // not time-out
             if (MessageBox(0, L"Still waiting", L"No BOOTP detected", MB_RETRYCANCEL | MB_TOPMOST) != IDRETRY) return 0;
          }
          int size = sizeof(s);
          if ((size=recvfrom(boot_sock, (char *)B, sizeof(B), 0, (SOCKADDR *)&s, &size))==SOCKET_ERROR) return 4;
          if (isBOOTP(B)) break;
          printf("non-BOOTP received\n");
       }
       char info[256];
       sprintf(info, "%02x-%02x-%02x-%02x-%02x-%02x", B[56],B[57],B[58],B[59],B[60],B[61]);
       printf("Bootp request received from %s\n", info);
       return 0;
    }

    void WaitForBOOTP(void) {
       SOCKET boot_sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
       if (boot_sock==INVALID_SOCKET) {
          printf("failed to create bootp socket (%d)\n", WSAGetLastError());
       } else {
          int n = inner_bootp(boot_sock);
          if (n) printf("wait for bootp fails %d (%d)\n", n, WSAGetLastError());
          closesocket(boot_sock);
       }
    }

    void main() {
       WSADATA Data;
       if (WSAStartup(MAKEWORD(1, 1), &Data)) {
          printf("Unable to initialize WinSock for host info\n");
       } else {
          WaitForBOOTP();
          WSACleanup();
       }
    }

  • Few more notes on the subject.

    First, about coding. Usually the packets flying on the net connection to DSP are short. However, I would use a buffer large enough to accommodate the whole IP datagram.

    Second, one may opt not disable firewall at all, but rather create a firewall rule allowing ports 67-68 to be passed through.