Index: cpukit/libnetworking/nfs/bootp_subr.c
===================================================================
RCS file: /usr1/CVS/rtems/cpukit/libnetworking/nfs/bootp_subr.c,v
retrieving revision 1.22
diff -c -3 -p -r1.22 bootp_subr.c
*** cpukit/libnetworking/nfs/bootp_subr.c	28 Mar 2007 02:42:47 -0000	1.22
--- cpukit/libnetworking/nfs/bootp_subr.c	25 Apr 2008 13:34:01 -0000
***************
*** 78,84 ****
  /*
   * What is the longest we will wait before re-sending a request?
   * Note this is also the frequency of "RPC timeout" messages.
!  * The re-send loop count sup linearly to this maximum, so the
   * first complaint will happen after (1+2+3+4+5)=15 seconds.
   */
  #define	MAX_RESEND_DELAY 5	/* seconds */
--- 78,84 ----
  /*
   * What is the longest we will wait before re-sending a request?
   * Note this is also the frequency of "RPC timeout" messages.
!  * The re-send loop counts up linearly to this maximum, so the
   * first complaint will happen after (1+2+3+4+5)=15 seconds.
   */
  #define	MAX_RESEND_DELAY 5	/* seconds */
*************** bootpc_call(call,reply,procp)
*** 377,384 ****
  	 * but delay each re-send by an increasing amount.
  	 * If the delay hits the maximum, start complaining.
  	 */
! 	timo = 0;
! 	for (;;) {
  		/* Send BOOTP request (or re-send). */
  		
  		aio.iov_base = (caddr_t) call;
--- 377,383 ----
  	 * but delay each re-send by an increasing amount.
  	 * If the delay hits the maximum, start complaining.
  	 */
! 	for (timo=1; timo <= MAX_RESEND_DELAY; timo++) {
  		/* Send BOOTP request (or re-send). */
  		
  		aio.iov_base = (caddr_t) call;
*************** bootpc_call(call,reply,procp)
*** 391,410 ****
  		auio.uio_offset = 0;
  		auio.uio_resid = sizeof(*call);
  		auio.uio_procp = procp;
- 
  		error = sosend(so, nam, &auio, NULL, NULL, 0);
  		if (error) {
  			printf("bootpc_call: sosend: %d\n", error);
! 			goto out;
  		}
  
- 		/* Determine new timeout. */
- 		if (timo < MAX_RESEND_DELAY)
- 			timo++;
- 		else
- 			printf("BOOTP timeout for server 0x%x\n",
- 			       (int)ntohl(sin->sin_addr.s_addr));
- 
  		/*
  		 * Wait for up to timo seconds for a reply.
  		 * The socket receive timeout was set to 1 second.
--- 390,413 ----
  		auio.uio_offset = 0;
  		auio.uio_resid = sizeof(*call);
  		auio.uio_procp = procp;
  		error = sosend(so, nam, &auio, NULL, NULL, 0);
  		if (error) {
  			printf("bootpc_call: sosend: %d\n", error);
!                         switch (error) {
!                         case  ENOBUFS:             /* No buffer space available */
!                         case  ENETUNREACH:         /* Network is unreachable */
!                         case  ENETDOWN:            /* Network interface is not configured */
!                         case  EHOSTDOWN:           /* Host is down */
!                         case  EHOSTUNREACH:        /* Host is unreachable */
!                         case  EMSGSIZE:            /* Message too long */
!                                 /* This is a possibly transient error.
!                                    We can still receive replies from previous attempts. */
!                                 break;
!                         default:
!                               goto out;
!                         }
  		}
  
  		/*
  		 * Wait for up to timo seconds for a reply.
  		 * The socket receive timeout was set to 1 second.
*************** bootpc_call(call,reply,procp)
*** 455,460 ****
--- 458,466 ----
  		} /* while secs */
  	} /* forever send/receive */
  
+         printf("BOOTP timeout for server 0x%x\n",
+                (int)ntohl(sin->sin_addr.s_addr));
+ 
  	error = ETIMEDOUT;
  	goto out;
  
*************** bootpc_fakeup_interface(struct ifreq *ir
*** 482,531 ****
     * IFF_UP set blindly, interface selection can be clobbered.
     */
    error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, procp);
!   if (error)
!     panic("bootpc_fakeup_interface: GIFFLAGS, error=%d", error);
    ireq->ifr_flags |= IFF_UP;
    error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)ireq, procp);
!   if (error)
!     panic("bootpc_fakeup_interface: SIFFLAGS, error=%d", error);
  
    /*
     * Do enough of ifconfig(8) so that the chosen interface
     * can talk to the servers.  (just set the address)
     */
!   
!   /* addr is 0.0.0.0 */
    
    sin = (struct sockaddr_in *)&ireq->ifr_addr;
    bzero((caddr_t)sin, sizeof(*sin));
    sin->sin_len = sizeof(*sin);
    sin->sin_family = AF_INET;
    sin->sin_addr.s_addr = INADDR_ANY;
!   error = ifioctl(so, SIOCSIFADDR, (caddr_t)ireq, procp);
!   if (error)
!     panic("bootpc_fakeup_interface: set if addr, error=%d", error);
    
!   /* netmask is 0.0.0.0 */
    
    sin = (struct sockaddr_in *)&ireq->ifr_addr;
    bzero((caddr_t)sin, sizeof(*sin));
    sin->sin_len = sizeof(*sin);
    sin->sin_family = AF_INET;
!   sin->sin_addr.s_addr = INADDR_ANY;
!   error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)ireq, procp);
!   if (error)
!     panic("bootpc_fakeup_interface: set if net addr, error=%d", error);
    
!   /* Broadcast is 255.255.255.255 */
    
    sin = (struct sockaddr_in *)&ireq->ifr_addr;
    bzero((caddr_t)sin, sizeof(*sin));
    sin->sin_len = sizeof(*sin);
    sin->sin_family = AF_INET;
!   sin->sin_addr.s_addr = INADDR_BROADCAST;
!   error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t)ireq, procp);
!   if (error)
!     panic("bootpc_fakeup_interface: set if broadcast addr, error=%d", error);
    
    /* Add default route to 0.0.0.0 so we can send data */
    
--- 488,547 ----
     * IFF_UP set blindly, interface selection can be clobbered.
     */
    error = ifioctl(so, SIOCGIFFLAGS, (caddr_t)ireq, procp);
!   if (error) {
!     printf("bootpc_fakeup_interface: GIFFLAGS, error=%s\n", strerror(error));
!     return error;
!   }
    ireq->ifr_flags |= IFF_UP;
    error = ifioctl(so, SIOCSIFFLAGS, (caddr_t)ireq, procp);
!   if (error) {
!     printf("bootpc_fakeup_interface: SIFFLAGS, error=%s\n", strerror(error));
!     return error;
!   }
  
    /*
     * Do enough of ifconfig(8) so that the chosen interface
     * can talk to the servers.  (just set the address)
     */
!   /* netmask is 0.0.0.0 */
    
    sin = (struct sockaddr_in *)&ireq->ifr_addr;
    bzero((caddr_t)sin, sizeof(*sin));
    sin->sin_len = sizeof(*sin);
    sin->sin_family = AF_INET;
    sin->sin_addr.s_addr = INADDR_ANY;
!   error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)ireq, procp);
!   if (error) {
!     printf("bootpc_fakeup_interface: set if netmask, error=%s\n", strerror(error));
!     return error;
!   }
    
!   /* Broadcast is 255.255.255.255 */
    
    sin = (struct sockaddr_in *)&ireq->ifr_addr;
    bzero((caddr_t)sin, sizeof(*sin));
    sin->sin_len = sizeof(*sin);
    sin->sin_family = AF_INET;
!   sin->sin_addr.s_addr = INADDR_BROADCAST;
!   error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t)ireq, procp);
!   if (error) {
!     printf("bootpc_fakeup_interface: set broadcast addr, error=%s\n", strerror(error));
!     return error;
!   }
    
!   
!   /* addr is 0.0.0.0 */
    
    sin = (struct sockaddr_in *)&ireq->ifr_addr;
    bzero((caddr_t)sin, sizeof(*sin));
    sin->sin_len = sizeof(*sin);
    sin->sin_family = AF_INET;
!   sin->sin_addr.s_addr = INADDR_ANY;
!   error = ifioctl(so, SIOCSIFADDR, (caddr_t)ireq, procp);
!   if (error) {
!     printf("bootpc_fakeup_interface: set if addr, error=%s\n", strerror(error));
!     return error;
!   }
    
    /* Add default route to 0.0.0.0 so we can send data */
    
*************** bootpc_adjust_interface(struct ifreq *ir
*** 601,608 ****
     */
    bcopy(netmask,&ireq->ifr_addr,sizeof(*netmask));
    error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)ireq, procp);
!   if (error)
!     panic("nfs_boot: set if netmask, error=%d", error);
  
    /* Broadcast is with host part of IP address all 1's */
    
--- 617,626 ----
     */
    bcopy(netmask,&ireq->ifr_addr,sizeof(*netmask));
    error = ifioctl(so, SIOCSIFNETMASK, (caddr_t)ireq, procp);
!   if (error) {
!     printf("bootpc_adjust_interface: set netmask, error=%s\n", strerror(error));
!     return error;
!   }
  
    /* Broadcast is with host part of IP address all 1's */
    
*************** bootpc_adjust_interface(struct ifreq *ir
*** 612,624 ****
    sin->sin_family = AF_INET;
    sin->sin_addr.s_addr = myaddr->sin_addr.s_addr | ~ netmask->sin_addr.s_addr;
    error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t)ireq, procp);
!   if (error)
!     panic("bootpc_call: set if broadcast addr, error=%d", error);
    
    bcopy(myaddr,&ireq->ifr_addr,sizeof(*myaddr));
    error = ifioctl(so, SIOCSIFADDR, (caddr_t)ireq, procp);
!   if (error)
!     panic("nfs_boot: set if addr, error=%d", error);
  
    /* Add new default route */
  
--- 630,646 ----
    sin->sin_family = AF_INET;
    sin->sin_addr.s_addr = myaddr->sin_addr.s_addr | ~ netmask->sin_addr.s_addr;
    error = ifioctl(so, SIOCSIFBRDADDR, (caddr_t)ireq, procp);
!   if (error) {
!     printf("bootpc_adjust_interface: set broadcast addr, error=%s\n", strerror(error));
!     return error;
!   }
    
    bcopy(myaddr,&ireq->ifr_addr,sizeof(*myaddr));
    error = ifioctl(so, SIOCSIFADDR, (caddr_t)ireq, procp);
!   if (error) {
!     printf("bootpc_adjust_interface: set if addr, error=%s\n", strerror(error));
!     return error;
!   }
  
    /* Add new default route */
  
*************** bootpc_adjust_interface(struct ifreq *ir
*** 628,638 ****
  		    (struct sockaddr *) &oldmask,
  		    (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL);
    if (error) {
!     printf("nfs_boot: add net route, error=%d\n", error);
!     return error;
    }
  
!   return 0;
  }
  
  #if !defined(__rtems__)
--- 650,659 ----
  		    (struct sockaddr *) &oldmask,
  		    (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL);
    if (error) {
!     printf("bootpc_adjust_interface: add net route, error=%d\n", error);
    }
  
!   return error;
  }
  
  #if !defined(__rtems__)
*************** processOptions (unsigned char *optbuf, i
*** 758,781 ****
      switch (code) {
      case 1:
        /* Subnet mask */
!       if (len!=4) 
!         panic("bootpc: subnet mask len is %d",len);
        bcopy (p, &dhcp_netmask.sin_addr, 4);
        dhcp_gotnetmask = 1;
        break;
  
      case 2:
        /* Time offset */
!       if (len!=4) 
!         panic("bootpc: time offset len is %d",len);
        bcopy (p, &rtems_bsdnet_timeoffset, 4);
        rtems_bsdnet_timeoffset = ntohl (rtems_bsdnet_timeoffset);
        break;
  
      case 3:
        /* Routers */
!       if (len % 4) 
!         panic ("bootpc: Router Len is %d", len);
        if (len > 0) {
          bcopy(p, &dhcp_gw.sin_addr, 4);
  	dhcp_gotgw = 1;
--- 779,808 ----
      switch (code) {
      case 1:
        /* Subnet mask */
!       if (len!=4) {
!         printf("bootpc: subnet mask len is %d\n",len);
!         continue;
!       }
        bcopy (p, &dhcp_netmask.sin_addr, 4);
        dhcp_gotnetmask = 1;
        break;
  
      case 2:
        /* Time offset */
!       if (len!=4) {
!         printf("bootpc: time offset len is %d\n",len);
!         continue;
!       }
        bcopy (p, &rtems_bsdnet_timeoffset, 4);
        rtems_bsdnet_timeoffset = ntohl (rtems_bsdnet_timeoffset);
        break;
  
      case 3:
        /* Routers */
!       if (len % 4) {
!         printf ("bootpc: Router Len is %d\n", len);
!         continue;
!       }
        if (len > 0) {
          bcopy(p, &dhcp_gw.sin_addr, 4);
  	dhcp_gotgw = 1;
*************** processOptions (unsigned char *optbuf, i
*** 784,791 ****
  
      case 42:
        /* NTP servers */
!       if (len % 4) 
!         panic ("bootpc: time server Len is %d", len);
        {
        int tlen = 0;
        while ((tlen < len) &&
--- 811,820 ----
  
      case 42:
        /* NTP servers */
!       if (len % 4) {
!         printf ("bootpc: time server Len is %d\n", len);
!         continue;
!       }
        {
        int tlen = 0;
        while ((tlen < len) &&
*************** processOptions (unsigned char *optbuf, i
*** 804,811 ****
  
      case 6:
        /* Domain Name servers */
!       if (len % 4) 
!         panic ("bootpc: DNS Len is %d", len);
        {
        int dlen = 0;
        while ((dlen < len) &&
--- 833,842 ----
  
      case 6:
        /* Domain Name servers */
!       if (len % 4) {
!         printf ("bootpc: DNS Len is %d", len);
!         continue;
!       }
        {
        int dlen = 0;
        while ((dlen < len) &&
*************** processOptions (unsigned char *optbuf, i
*** 824,841 ****
  
      case 12:
        /* Host name */
!       if (len>=MAXHOSTNAMELEN)
!         panic ("bootpc: hostname >=%d bytes", MAXHOSTNAMELEN);
!       if (sethostname ((char *)p, len) < 0)
!         panic("Can't set host name");
        printf("Hostname is %s\n", p);
        dhcp_hostname = bootp_strdup_realloc(dhcp_hostname,(char *)p);
        break;
  
      case 7:
        /* Log servers */
!       if (len % 4) 
!         panic ("bootpc: Log server Len is %d", len);
        if (len > 0) {
          bcopy(p, &rtems_bsdnet_log_host_address, 4);
  	dhcp_gotlogserver = 1;
--- 855,877 ----
  
      case 12:
        /* Host name */
!       if (len>=MAXHOSTNAMELEN) {
!         printf ("bootpc: hostname >=%d bytes", MAXHOSTNAMELEN);
!         continue;
!       }
!       if (sethostname ((char *)p, len) < 0) {
!         printf("bootpc: Can't set host name");
!       }
        printf("Hostname is %s\n", p);
        dhcp_hostname = bootp_strdup_realloc(dhcp_hostname,(char *)p);
        break;
  
      case 7:
        /* Log servers */
!       if (len % 4) {
!         printf ("bootpc: Log server Len is %d", len);
!         continue;
!       }
        if (len > 0) {
          bcopy(p, &rtems_bsdnet_log_host_address, 4);
  	dhcp_gotlogserver = 1;
*************** processOptions (unsigned char *optbuf, i
*** 856,863 ****
  
      case 52:
        /* DHCP option override */
!       if (len != 1) 
!         panic ("bootpc: DHCP option overload len is %d", len);
        dhcpOptionOverload = p[0];
        break;
  
--- 892,901 ----
  
      case 52:
        /* DHCP option override */
!       if (len != 1) {
!         printf ("bootpc: DHCP option overload len is %d", len);
!         continue;
!       }
        dhcpOptionOverload = p[0];
        break;
  
*************** processOptions (unsigned char *optbuf, i
*** 872,879 ****
                 */
      case 54:
        /* DHCP server */
!       if (len != 4) 
!         panic ("bootpc: DHCP server len is %d", len);
        bcopy(p, &rtems_bsdnet_bootp_server_address, 4);
        dhcp_gotserver = 1;
        break;
--- 910,919 ----
                 */
      case 54:
        /* DHCP server */
!       if (len != 4) {
!         printf ("bootpc: DHCP server len is %d", len);
!         continue;
!       }
        bcopy(p, &rtems_bsdnet_bootp_server_address, 4);
        dhcp_gotserver = 1;
        break;
*************** bootpc_init(int update_files)
*** 955,974 ****
      if ((ifp->if_flags &
        (IFF_LOOPBACK|IFF_POINTOPOINT)) == 0)
  	break;
!   if (ifp == NULL)
!     panic("bootpc_init: no suitable interface");
    bzero(&ireq,sizeof(ireq));
    sprintf(ireq.ifr_name, "%s%d", ifp->if_name,ifp->if_unit);
    printf("bootpc_init: using network interface '%s'\n",
  	 ireq.ifr_name);
  
!   if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)) != 0)
!     panic("nfs_boot: socreate, error=%d", error);
! 	  
!   bootpc_fakeup_interface(&ireq,so,procp);
  
-   printf("Bootpc testing starting\n");
-   
    /* Get HW address */
  
    for (ifa = ifp->if_addrlist;ifa; ifa = ifa->ifa_next)
--- 995,1017 ----
      if ((ifp->if_flags &
        (IFF_LOOPBACK|IFF_POINTOPOINT)) == 0)
  	break;
!   if (ifp == NULL) {
!     printf("bootpc_init: no suitable interface\n");
!     return;
!   }
    bzero(&ireq,sizeof(ireq));
    sprintf(ireq.ifr_name, "%s%d", ifp->if_name,ifp->if_unit);
    printf("bootpc_init: using network interface '%s'\n",
  	 ireq.ifr_name);
  
!   if ((error = socreate(AF_INET, &so, SOCK_DGRAM, 0,procp)) != 0) {
!     printf("bootpc_init: socreate, error=%d", error);
!     return;
!   }
!   if (bootpc_fakeup_interface(&ireq,so,procp) != 0) {
!     return;
!   }
  
    /* Get HW address */
  
    for (ifa = ifp->if_addrlist;ifa; ifa = ifa->ifa_next)
*************** bootpc_init(int update_files)
*** 977,987 ****
  	sdl->sdl_type == IFT_ETHER)
        break;
    
!   if (!sdl)
!     panic("bootpc: Unable to find HW address");
!   if (sdl->sdl_alen != EALEN ) 
!     panic("bootpc: HW address len is %d, expected value is %d",
! 	  sdl->sdl_alen,EALEN);
  
    printf("bootpc hw address is ");
    delim="";
--- 1020,1034 ----
  	sdl->sdl_type == IFT_ETHER)
        break;
    
!   if (!sdl) {
!     printf("bootpc: Unable to find HW address\n");
!     return;
!   }
!   if (sdl->sdl_alen != EALEN ) {
!     printf("bootpc: HW address len is %d, expected value is %d\n",
! 	   sdl->sdl_alen,EALEN);
!     return;
!   }
  
    printf("bootpc hw address is ");
    delim="";
*************** bootpc_init(int update_files)
*** 1018,1025 ****
    
    error = bootpc_call(&call,&reply,procp);
    
!   if (error)
!     panic("BOOTP call failed -- error %d", error);
    
    /*
     * Initialize network address structures
--- 1065,1074 ----
    
    error = bootpc_call(&call,&reply,procp);
    
!   if (error) {
!     printf("BOOTP call failed -- error %d", error);
!     return;
!   }
    
    /*
     * Initialize network address structures
Index: cpukit/libnetworking/rtems/dhcp.h
===================================================================
RCS file: /usr1/CVS/rtems/cpukit/libnetworking/rtems/dhcp.h,v
retrieving revision 1.1
diff -c -3 -p -r1.1 dhcp.h
*** cpukit/libnetworking/rtems/dhcp.h	30 Jun 2005 04:03:56 -0000	1.1
--- cpukit/libnetworking/rtems/dhcp.h	25 Apr 2008 13:34:01 -0000
*************** extern "C"
*** 29,34 ****
--- 29,36 ----
   * Perform DHCP.
   */
  void rtems_bsdnet_do_dhcp (void);
+ int rtems_bsdnet_do_dhcp_timeout (void);
+ void rtems_bsdnet_dhcp_down (void);
  
  /*
   * Maintain a DHCP offer that has already been accepted.
Index: cpukit/libnetworking/rtems/rtems_dhcp.c
===================================================================
RCS file: /usr1/CVS/rtems/cpukit/libnetworking/rtems/rtems_dhcp.c,v
retrieving revision 1.1
diff -c -3 -p -r1.1 rtems_dhcp.c
*** cpukit/libnetworking/rtems/rtems_dhcp.c	30 Jun 2005 04:01:12 -0000	1.1
--- cpukit/libnetworking/rtems/rtems_dhcp.c	25 Apr 2008 13:34:01 -0000
***************
*** 10,15 ****
--- 10,21 ----
   */
  
  /*
+  * Added interface to terminate DHCP task, and removed panics.
+  * Arnout Vandecappelle <arnout@mind.be>, Essensium/Mind
+  * Maarten Van Es <maarten@mind.be>, Essensium/Mind
+  */
+ 
+ /*
   * Copyright (c) 1995 Gordon Ross, Adam Glass
   * Copyright (c) 1992 Regents of the University of California.
   * All rights reserved.
*************** extern int bootpc_adjust_interface (stru
*** 186,192 ****
                                      struct proc *procp);
  extern void *bootp_strdup_realloc (char *dst,
                                     const char *src);
- extern int nfs_diskless_valid;
  
  /*
   * Variables
--- 192,197 ----
*************** process_options (unsigned char *optbuf, 
*** 271,276 ****
--- 276,283 ----
    int code, ncode;
    char *p;
  
+   dhcp_message_type = 0;
+ 
    ncode = optbuf[0];
    while (j < optbufSize)
    {
*************** process_options (unsigned char *optbuf, 
*** 303,326 ****
      {
        case 1:
          /* Subnet mask */
!         if (len != 4)
!           panic ("dhcpc: subnet mask len is %d", len);
          memcpy (&dhcp_netmask.sin_addr, p, 4);
          dhcp_gotnetmask = 1;
          break;
  
        case 2:
          /* Time offset */
!         if (len != 4)
!           panic ("dhcpc: time offset len is %d", len);
          memcpy (&rtems_bsdnet_timeoffset, p, 4);
          rtems_bsdnet_timeoffset = ntohl (rtems_bsdnet_timeoffset);
          break;
  
        case 3:
          /* Routers */
!         if (len % 4)
!           panic ("dhcpc: Router Len is %d", len);
          if (len > 0)
          {
            memcpy (&dhcp_gw.sin_addr, p, 4);
--- 310,339 ----
      {
        case 1:
          /* Subnet mask */
!         if (len != 4) {
!           printf ("dhcpc: subnet mask len is %d\n", len);
!           continue;
!         }
          memcpy (&dhcp_netmask.sin_addr, p, 4);
          dhcp_gotnetmask = 1;
          break;
  
        case 2:
          /* Time offset */
!         if (len != 4) {
!           printf ("dhcpc: time offset len is %d\n", len);
!           continue;
!         }
          memcpy (&rtems_bsdnet_timeoffset, p, 4);
          rtems_bsdnet_timeoffset = ntohl (rtems_bsdnet_timeoffset);
          break;
  
        case 3:
          /* Routers */
!         if (len % 4) {
!           printf ("dhcpc: Router Len is %d\n", len);
!           continue;
!         }
          if (len > 0)
          {
            memcpy (&dhcp_gw.sin_addr, p, 4);
*************** process_options (unsigned char *optbuf, 
*** 330,337 ****
  
        case 42:
          /* NTP servers */
!         if (len % 4)
!           panic ("dhcpc: time server Len is %d", len);
          {
            int tlen = 0;
            while ((tlen < len) &&
--- 343,352 ----
  
        case 42:
          /* NTP servers */
!         if (len % 4) {
!           printf ("dhcpc: time server Len is %d\n", len);
!           continue;
!         }
          {
            int tlen = 0;
            while ((tlen < len) &&
*************** process_options (unsigned char *optbuf, 
*** 349,356 ****
  
        case 6:
          /* Domain Name servers */
!         if (len % 4)
!           panic ("dhcpc: DNS Len is %d", len);
          {
            int dlen = 0;
            while ((dlen < len) &&
--- 364,373 ----
  
        case 6:
          /* Domain Name servers */
!         if (len % 4) {
!           printf ("dhcpc: DNS Len is %d\n", len);
!           continue;
!         }
          {
            int dlen = 0;
            while ((dlen < len) &&
*************** process_options (unsigned char *optbuf, 
*** 368,377 ****
  
        case 12:
          /* Host name */
!         if (len >= MAXHOSTNAMELEN)
!           panic ("dhcpc: hostname >= %d bytes", MAXHOSTNAMELEN);
          if (sethostname (p, len) < 0)
!           panic ("dhcpc: can't set host name");
          if (dhcp_hostname != NULL)
          {
            dhcp_hostname = realloc (dhcp_hostname, len);
--- 385,396 ----
  
        case 12:
          /* Host name */
!         if (len >= MAXHOSTNAMELEN) {
!           printf ("dhcpc: hostname >= %d bytes\n", MAXHOSTNAMELEN);
!           len = MAXHOSTNAMELEN-1;
!         }
          if (sethostname (p, len) < 0)
!           printf ("dhcpc: can't set host name");
          if (dhcp_hostname != NULL)
          {
            dhcp_hostname = realloc (dhcp_hostname, len);
*************** process_options (unsigned char *optbuf, 
*** 383,390 ****
  
        case 7:
          /* Log servers */
!         if (len % 4)
!           panic ("dhcpc: Log server Len is %d", len);
          if (len > 0)
          {
            memcpy (&rtems_bsdnet_log_host_address, p, 4);
--- 402,411 ----
  
        case 7:
          /* Log servers */
!         if (len % 4) {
!           printf ("dhcpc: Log server Len is %d\n", len);
!           continue;
!         }
          if (len > 0)
          {
            memcpy (&rtems_bsdnet_log_host_address, p, 4);
*************** process_options (unsigned char *optbuf, 
*** 406,412 ****
        case 50:
          /* DHCP Requested IP Address */
          if (len != 4)
!           panic ("dhcpc: DHCP option requested IP len is %d", len);
          /* 
           * although nothing happens here, this case keeps the client
           * from complaining about unknown options.  The Requested IP
--- 427,433 ----
        case 50:
          /* DHCP Requested IP Address */
          if (len != 4)
!           printf ("dhcpc: DHCP option requested IP len is %d", len);
          /* 
           * although nothing happens here, this case keeps the client
           * from complaining about unknown options.  The Requested IP
*************** process_options (unsigned char *optbuf, 
*** 416,438 ****
  
        case 51:
          /* DHCP Lease Length */
!         if (len != 4)
!           panic ("dhcpc: DHCP option lease-length len is %d", len);
          memcpy (&dhcp_lease_time, &p[0], 4);
          dhcp_lease_time = ntohl (dhcp_lease_time);
          break;
          
        case 52:
          /* DHCP option override */
!         if (len != 1)
!           panic ("dhcpc: DHCP option overload len is %d", len);
          dhcp_option_overload = p[0];
          break;
  
        case 53:
          /* DHCP message */
!         if (len != 1)
!           panic ("dhcpc: DHCP message len is %d", len);
          dhcp_message_type = p[0];
          break;
  
--- 437,465 ----
  
        case 51:
          /* DHCP Lease Length */
!         if (len != 4) {
!           printf ("dhcpc: DHCP option lease-length len is %d", len);
!           continue;
!         }
          memcpy (&dhcp_lease_time, &p[0], 4);
          dhcp_lease_time = ntohl (dhcp_lease_time);
          break;
          
        case 52:
          /* DHCP option override */
!         if (len != 1) {
!           printf ("dhcpc: DHCP option overload len is %d", len);
!           continue;
!         }
          dhcp_option_overload = p[0];
          break;
  
        case 53:
          /* DHCP message */
!         if (len != 1) {
!           printf ("dhcpc: DHCP message len is %d", len);
!           continue;
!         }
          dhcp_message_type = p[0];
          break;
  
*************** process_options (unsigned char *optbuf, 
*** 447,454 ****
                     */
        case 54:
          /* DHCP server */
!         if (len != 4)
!           panic ("dhcpc: DHCP server len is %d", len);
          memcpy (&rtems_bsdnet_bootp_server_address, p, 4);
          dhcp_gotserver = 1;
          break;
--- 474,483 ----
                     */
        case 54:
          /* DHCP server */
!         if (len != 4) {
!           printf ("dhcpc: DHCP server len is %d", len);
!           continue;
!         }
          memcpy (&rtems_bsdnet_bootp_server_address, p, 4);
          dhcp_gotserver = 1;
          break;
*************** dhcp_request_req (struct dhcp_packet* ca
*** 646,652 ****
   * Variables for the DHCP task.
   */
  static struct dhcp_packet dhcp_req;
! static rtems_id           dhcp_task_id;
  
  /*
   * The DHCP task counts until half the lease time has expired.
--- 675,681 ----
   * Variables for the DHCP task.
   */
  static struct dhcp_packet dhcp_req;
! static rtems_id           dhcp_task_id = 0;
  
  /*
   * The DHCP task counts until half the lease time has expired.
*************** dhcp_task (rtems_task_argument _sdl)
*** 667,679 ****
    unsigned int        timeout = 0;
    int                 error;
    struct proc *procp = NULL;
    
    sdl = (struct sockaddr_dl *) _sdl;
    
    count = dhcp_elapsed_time;
!   
    while (TRUE)
    {
      if (count >= (dhcp_lease_time / 2))
      {
        rtems_bsdnet_semaphore_obtain ();
--- 696,723 ----
    unsigned int        timeout = 0;
    int                 error;
    struct proc *procp = NULL;
+   int                 disconnected;
    
    sdl = (struct sockaddr_dl *) _sdl;
    
    count = dhcp_elapsed_time;
!   disconnected = 0;
!  
! 
    while (TRUE)
    {
+     /*
+      * Sleep until the next poll
+      */
+     timeout = TOD_MILLISECONDS_TO_TICKS (1000);
+     rtems_event_receive (RTEMS_EVENT_0,
+                          RTEMS_WAIT | RTEMS_EVENT_ANY,
+                          timeout, &event_out);
+ 
+     if(event_out & RTEMS_EVENT_0) break;
+ 
+     count++;
+ 
      if (count >= (dhcp_lease_time / 2))
      {
        rtems_bsdnet_semaphore_obtain ();
*************** dhcp_task (rtems_task_argument _sdl)
*** 684,726 ****
         * Send the Request.
         */
        error = bootpc_call (&call, &dhcp_req, procp);
!       
!       if (error)
!         panic ("DHCP call failed -- error %d", error);
!       
        /*
!        * Check for DHCP ACK/NACK
!        */
        if (memcmp (&dhcp_req.vend[0],
                    dhcp_magic_cookie,
                    sizeof (dhcp_magic_cookie)) != 0)
        {
          rtems_bsdnet_semaphore_release ();
!         panic ("DHCP server did not send Magic Cookie.\n");
        }
!   
        process_options (&dhcp_req.vend[4], sizeof (dhcp_req.vend) - 4);
!   
        if (dhcp_message_type != DHCP_ACK)
        {
          rtems_bsdnet_semaphore_release ();
!         panic ("DHCP server did not accept the DHCP request");
        }
!       
        rtems_bsdnet_semaphore_release ();
!       
        count = 0;
      }
- 
-     /*
-      * Sleep until the next poll
-      */
-     timeout = TOD_MILLISECONDS_TO_TICKS (1000);
-     rtems_event_receive (RTEMS_EVENT_0,
-                          RTEMS_WAIT | RTEMS_EVENT_ANY,
-                          timeout, &event_out);
-     count++;
    }
  }
  
  /*
--- 728,771 ----
         * Send the Request.
         */
        error = bootpc_call (&call, &dhcp_req, procp);
!       if (error) {
!         rtems_bsdnet_semaphore_release ();
!         printf ("DHCP call failed -- error %d", error);
!         continue;
!       }
! 
        /*
!       * Check for DHCP ACK/NACK
!       */
        if (memcmp (&dhcp_req.vend[0],
                    dhcp_magic_cookie,
                    sizeof (dhcp_magic_cookie)) != 0)
        {
          rtems_bsdnet_semaphore_release ();
!         printf ("DHCP server did not send Magic Cookie.\n");
!         continue;
        }
! 
        process_options (&dhcp_req.vend[4], sizeof (dhcp_req.vend) - 4);
! 
        if (dhcp_message_type != DHCP_ACK)
        {
          rtems_bsdnet_semaphore_release ();
!         printf ("DHCP server did not accept the DHCP request");
!         continue;
        }
! 
        rtems_bsdnet_semaphore_release ();
! 
        count = 0;
      }
    }
+ 
+ 
+   dhcp_task_id = 0;
+   printf ("dhcpc: exiting lease renewal task.\n");
+   rtems_task_delete( RTEMS_SELF);
+ 
  }
  
  /*
*************** dhcp_interface_has_ip (struct ifreq *ire
*** 795,802 ****
   *  DCHP Client Routine 
   *    - The first DHCP offer is always accepted
   *    - No DHCP DECLINE message is sent if ARPing fails
   */
! void
  dhcp_init (int update_files)
  {
    struct dhcp_packet   call;
--- 840,851 ----
   *  DCHP Client Routine 
   *    - The first DHCP offer is always accepted
   *    - No DHCP DECLINE message is sent if ARPing fails
+  *
+  *    return value:
+  *    0: ok
+  *    < 0: failed to startup or configure interface
   */
! int
  dhcp_init (int update_files)
  {
    struct dhcp_packet   call;
*************** dhcp_init (int update_files)
*** 811,822 ****
    struct ifaddr        *ifa;
    struct sockaddr_dl   *sdl = NULL;
    struct proc          *procp = NULL;
-   
-   /*
-    * If already filled in, don't touch it here 
-    */
-   if (nfs_diskless_valid)
-     return;
  
    /*
     * If we are to update the files create the root
--- 860,865 ----
*************** dhcp_init (int update_files)
*** 834,846 ****
    for (ifp = ifnet; ifp != 0; ifp = ifp->if_next)
      if ((ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0)
        break;
!   if (ifp == NULL)
!     panic ("dhcpc_init: no suitable interface");
    memset (&ireq, 0, sizeof (ireq));
    sprintf (ireq.ifr_name, "%s%d", ifp->if_name, ifp->if_unit);
  
!   if ((error = socreate (AF_INET, &so, SOCK_DGRAM, 0, procp)) != 0)
!     panic ("nfs_boot: socreate, error=%d", error);
  
    if (!dhcp_interface_has_ip (&ireq, so, procp))
      bootpc_fakeup_interface (&ireq, so, procp);
--- 877,894 ----
    for (ifp = ifnet; ifp != 0; ifp = ifp->if_next)
      if ((ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0)
        break;
!   if (ifp == NULL){
!     printf ("dhcpc_init: no suitable interface\n");
!     return -1;
!   }
! 
    memset (&ireq, 0, sizeof (ireq));
    sprintf (ireq.ifr_name, "%s%d", ifp->if_name, ifp->if_unit);
  
!   if ((error = socreate (AF_INET, &so, SOCK_DGRAM, 0, procp)) != 0) {
!     printf ("dhcpc_init: socreate, error=%d\n", error);
!     return -1;
!   }
  
    if (!dhcp_interface_has_ip (&ireq, so, procp))
      bootpc_fakeup_interface (&ireq, so, procp);
*************** dhcp_init (int update_files)
*** 854,864 ****
          sdl->sdl_type == IFT_ETHER)
        break;
  
!   if (!sdl)
!     panic ("dhcpc: Unable to find HW address");
!   if (sdl->sdl_alen != EALEN)
!     panic ("dhcpc: HW address len is %d, expected value is %d",
             sdl->sdl_alen, EALEN);
  
    /*
     * Build the DHCP Discover
--- 902,916 ----
          sdl->sdl_type == IFT_ETHER)
        break;
  
!   if (!sdl){
!     printf ("dhcpc_init: Unable to find HW address\n");
!     return -1;
!   }
!   if (sdl->sdl_alen != EALEN) {
!     printf ("dhcpc_init: HW address len is %d, expected value is %d\n",
             sdl->sdl_alen, EALEN);
+     return -1;
+   }
  
    /*
     * Build the DHCP Discover
*************** dhcp_init (int update_files)
*** 869,887 ****
     * Send the Discover.
     */
    error = bootpc_call (&call, &reply, procp);
!   if (error)
!     panic ("BOOTP call failed -- error %d", error);
  
    /*
     * Check for DHCP OFFER
     */
!   if (memcmp (&reply.vend[0], dhcp_magic_cookie, sizeof (dhcp_magic_cookie)) != 0)
!     panic ("DHCP server did not send Magic Cookie.\n");
  
    process_options (&reply.vend[4], sizeof (reply.vend) - 4);
    
!   if (dhcp_message_type != DHCP_OFFER)
!     panic ("DHCP server did not send a DHCP Offer.\n");
  
    /*
     * Send a DHCP REQUEST 
--- 921,945 ----
     * Send the Discover.
     */
    error = bootpc_call (&call, &reply, procp);
!   if (error) {
!     printf ("BOOTP call failed -- error %d\n", error);
!     return -1;
!   }
  
    /*
     * Check for DHCP OFFER
     */
!   if (memcmp (&reply.vend[0], dhcp_magic_cookie, sizeof (dhcp_magic_cookie)) != 0) {
!     printf ("DHCP server did not send Magic Cookie.\n");
!     return -1;
!   }
  
    process_options (&reply.vend[4], sizeof (reply.vend) - 4);
    
!   if (dhcp_message_type != DHCP_OFFER) {
!     printf ("DHCP server did not send a DHCP Offer.\n");
!     return -1;
!   }
  
    /*
     * Send a DHCP REQUEST 
*************** dhcp_init (int update_files)
*** 889,907 ****
    dhcp_request_req (&call, &reply, sdl, TRUE);
    
    error = bootpc_call (&call, &reply, procp);
!   if (error)
!     panic ("BOOTP call failed -- error %d", error);
  
    /*
     * Check for DHCP ACK/NACK
     */
!   if (memcmp (&reply.vend[0], dhcp_magic_cookie, sizeof (dhcp_magic_cookie)) != 0)
!     panic ("DHCP server did not send Magic Cookie.\n");
    
    process_options (&reply.vend[4], sizeof (reply.vend) - 4);
    
!   if (dhcp_message_type != DHCP_ACK)
!     panic ("DHCP server did not accept the DHCP request");
  
    /*
     * Initialize network address structures
--- 947,971 ----
    dhcp_request_req (&call, &reply, sdl, TRUE);
    
    error = bootpc_call (&call, &reply, procp);
!   if (error) {
!     printf ("BOOTP call failed -- error %d\n", error);
!     return -1;
!   }
  
    /*
     * Check for DHCP ACK/NACK
     */
!   if (memcmp (&reply.vend[0], dhcp_magic_cookie, sizeof (dhcp_magic_cookie)) != 0) {
!     printf ("DHCP server did not send Magic Cookie.\n");
!     return -1;
!   }
    
    process_options (&reply.vend[4], sizeof (reply.vend) - 4);
    
!   if (dhcp_message_type != DHCP_ACK) {
!     printf ("DHCP server did not accept the DHCP request\n");
!     return -1;
!   }
  
    /*
     * Initialize network address structures
*************** dhcp_init (int update_files)
*** 1039,1044 ****
--- 1103,1110 ----
      dhcp_start_task (sdl, &reply, 150);
    
    soclose (so);
+ 
+   return 0;
  }
  
  /*
*************** dhcp_init (int update_files)
*** 1049,1058 ****
  void rtems_bsdnet_do_dhcp (void)
  {
    rtems_bsdnet_semaphore_obtain ();
!   dhcp_init (TRUE);
    rtems_bsdnet_semaphore_release ();
  }
  
  void
  rtems_bsdnet_do_dhcp_refresh_only (unsigned long xid,
                                     unsigned long lease_time,
--- 1115,1146 ----
  void rtems_bsdnet_do_dhcp (void)
  {
    rtems_bsdnet_semaphore_obtain ();
!   while( dhcp_init (TRUE) < 0 ) {
!     rtems_bsdnet_semaphore_release();
!     rtems_task_wake_after(TOD_MILLISECONDS_TO_TICKS(1000));
!     rtems_bsdnet_semaphore_release ();
!   }
    rtems_bsdnet_semaphore_release ();
  }
  
+ int rtems_bsdnet_do_dhcp_timeout( void )
+ {
+   int return_value;
+ 
+   rtems_bsdnet_semaphore_obtain ();
+   return_value = dhcp_init (FALSE);
+   rtems_bsdnet_semaphore_release ();
+ 
+   return return_value;
+ }
+ 
+ void rtems_bsdnet_dhcp_down (void)
+ {
+    if(dhcp_task_id != 0) {
+      rtems_event_send (dhcp_task_id, RTEMS_EVENT_0);
+    }
+ }
+ 
  void
  rtems_bsdnet_do_dhcp_refresh_only (unsigned long xid,
                                     unsigned long lease_time,
*************** rtems_bsdnet_do_dhcp_refresh_only (unsig
*** 1092,1099 ****
            }
          }
  
!   if (!match)
!     panic ("dhcpc: no matching interface");
  
    for (ifa = mtif->if_addrlist; ifa != NULL; ifa = ifa->ifa_next)
      if (ifa->ifa_addr->sa_family == AF_LINK &&
--- 1180,1189 ----
            }
          }
  
!   if (!match) {
!     printf ("dhcpc: no matching interface\n");
!     return;
!   }
  
    for (ifa = mtif->if_addrlist; ifa != NULL; ifa = ifa->ifa_next)
      if (ifa->ifa_addr->sa_family == AF_LINK &&
*************** rtems_bsdnet_do_dhcp_refresh_only (unsig
*** 1101,1108 ****
          sdl->sdl_type == IFT_ETHER)
        break;
    
!   if (!match)
!     panic ("dhcpc: no matching interface");
  
    /*
     * Set up given values in a simulated DHCP reply.
--- 1191,1200 ----
          sdl->sdl_type == IFT_ETHER)
        break;
    
!   if (!match) {
!     printf ("dhcpc: no matching interface address\n");
!     return;
!   }
  
    /*
     * Set up given values in a simulated DHCP reply.
Index: cpukit/libnetworking/rtems/rtems_glue.c
===================================================================
RCS file: /usr1/CVS/rtems/cpukit/libnetworking/rtems/rtems_glue.c,v
retrieving revision 1.47
diff -c -3 -p -r1.47 rtems_glue.c
*** cpukit/libnetworking/rtems/rtems_glue.c	5 Feb 2008 22:29:19 -0000	1.47
--- cpukit/libnetworking/rtems/rtems_glue.c	25 Apr 2008 13:34:02 -0000
*************** int rtems_bsdnet_ifconfig (const char *i
*** 1127,1133 ****
  
  		case SIOCAIFADDR:
  		case SIOCDIFADDR:
! 			r = ioctl(s, cmd, (struct freq *) param);
  			break;
  
  		default:
--- 1127,1133 ----
  
  		case SIOCAIFADDR:
  		case SIOCDIFADDR:
! 			r = ioctl(s, cmd, (struct ifreq *) param);
  			break;
  
  		default:
