[En-Nut-Discussion] Eboot DHCP problem

Lars Andersson laran at ikp.liu.se
Mon Mar 10 12:34:03 CET 2003


Hi all !

I have been looking into the Ethernet boot loader again.

After debugging the code I managed to find out that the "sframe" variable
 is corrupted after the first message from the dhcp server is received in the DhcpQuery function, ore specific is that the "sframe.u.bootp.bp_xid" is set to zero. I created a help variable to store the "sframe" while receiving the frames and now I am available to get an address from the server. I paste the code of the modified DhcpQuery function below. Even though the ethernut board get an IP from the dhcp it does not download the binary from the tftp server. I think there may be a similar problem as there is with the dhcp client.
If someone have an idea about why the sframe variable gets corrupted when a frame is read please let me know.

Regards,
/Lars



int DhcpQuery(void)
{
    u_char type;
    u_char retry;
    int rlen;
    int slen;
    u_char i;
    u_char *cp;

    BOOTPHDR bootphdr;

    /*
     * Discovery loop.
     */
    slen = DhcpFrameInit();
    for(rlen = retry = 0; rlen == 0 && retry < 10; retry++) {
        if(UdpOutput(INADDR_BROADCAST, DHCP_SERVERPORT, DHCP_CLIENTPORT, slen) < 0)
            return -1;
        	
		bootphdr = sframe.u.bootp;
		
		if((rlen = UdpInput(DHCP_CLIENTPORT, 5000)) < 0) 
            break;
		
		sframe.u.bootp = bootphdr;
        
	   if(rlen &&
           rframe.u.bootp.bp_xid == sframe.u.bootp.bp_xid &&
           DhcpGetOption(DHCPOPT_MSGTYPE, &type, 1) == 1 && 
           type == DHCP_OFFER)
               break;
        rlen = 0;
    }
    if(rlen == 0) {
        return -1;
    }

    DhcpGetOption(DHCPOPT_SID, &sid, 4);

    /*
     * Request loop.
     */
    slen = DhcpRequestFrame();
    for(rlen = retry = 0; rlen == 0 && retry < 10; retry++) {
        if(UdpOutput(INADDR_BROADCAST, DHCP_SERVERPORT, DHCP_CLIENTPORT, slen) < 0)
            return -1;
		
		bootphdr = sframe.u.bootp;
        
	  if((rlen = UdpInput(DHCP_CLIENTPORT, 1000)) < 0)
            return -1;
		
		sframe.u.bootp = bootphdr;
        
	  if(rlen &&
           rframe.u.bootp.bp_xid == sframe.u.bootp.bp_xid &&
           DhcpGetOption(DHCPOPT_MSGTYPE, &type, 1) == 1 && 
           type == DHCP_ACK) 
                break;
        rlen = 0;
    }
    if(rlen == 0) {
        return -1;
    }

    local_ip = rframe.u.bootp.bp_yiaddr;
    server_ip = rframe.u.bootp.bp_siaddr;
    for(cp = rframe.u.bootp.bp_file, i = 0; *cp && i < sizeof(bootfile) - 1; cp++, i++)
        bootfile[i] = *cp;
    bootfile[i] = 0;

    DhcpGetOption(DHCPOPT_NETMASK, &netmask, 4);
    DhcpGetOption(DHCPOPT_BROADCAST, &broadcast, 4);
    DhcpGetOption(DHCPOPT_GATEWAY, &gateway, 4);
    DhcpGetOption(DHCPOPT_DNS, &dns, 4);
    DhcpGetOption(DHCPOPT_SID, &sid, 4);

    return 0;
}




More information about the En-Nut-Discussion mailing list