summaryrefslogtreecommitdiffstats
path: root/cpukit/libnetworking
diff options
context:
space:
mode:
authorChris Johns <chrisj@rtems.org>2008-05-01 02:57:49 +0000
committerChris Johns <chrisj@rtems.org>2008-05-01 02:57:49 +0000
commit50303dfbd1c7cd9f101242908eaf0404c58b4af7 (patch)
tree4ce817d7cd613fe32d5968ca6b440f44d1b68df9 /cpukit/libnetworking
parent2008-04-30 Joel Sherrill <joel.sherrill@oarcorp.com> (diff)
downloadrtems-50303dfbd1c7cd9f101242908eaf0404c58b4af7.tar.bz2
2008-05-01 Maarten Van Es <maarten@mind.be>
* libnetworking/rtems/rtems_dhcp.c: Removed panic()s. Added interface for rtems_dhcp_failsafe. * libnetworking/rtems/rtems_dhcp.h: Added interface for rtems_dhcp_failsafe. 2008-05-01 Arnout Vandecappelle <arnout@mind.be> * libnetworking/nfs/bootp_subr: Allow some errors for sosend() and return on timeout in bootpc_call(). Removed panic()s. * libnetworking/rtems/rtems_glue.c: Fix the cast for the SIOCAIFADDR ioctl call. * libnetworking/rtems/rtems_dhcp_failsafe.c, libnetworking/rtems/rtems_dhcp_failsafe.h: New. * libnetworking/Makefile.am, libnetworking/preinstall.am: Added rtems_dhcp_failsafe.c and rtems_dhcp_failsafe.h files.
Diffstat (limited to 'cpukit/libnetworking')
-rw-r--r--cpukit/libnetworking/Makefile.am5
-rw-r--r--cpukit/libnetworking/nfs/bootp_subr.c183
-rw-r--r--cpukit/libnetworking/preinstall.am4
-rw-r--r--cpukit/libnetworking/rtems/dhcp.h2
-rw-r--r--cpukit/libnetworking/rtems/rtems_dhcp.c238
-rw-r--r--cpukit/libnetworking/rtems/rtems_dhcp_failsafe.c372
-rw-r--r--cpukit/libnetworking/rtems/rtems_dhcp_failsafe.h29
-rw-r--r--cpukit/libnetworking/rtems/rtems_glue.c2
8 files changed, 692 insertions, 143 deletions
diff --git a/cpukit/libnetworking/Makefile.am b/cpukit/libnetworking/Makefile.am
index a75e4e5fc4..e07ec5f3df 100644
--- a/cpukit/libnetworking/Makefile.am
+++ b/cpukit/libnetworking/Makefile.am
@@ -112,12 +112,13 @@ include_nfsclient_HEADERS = nfsclient/nfsargs.h nfsclient/nfsdiskless.h
include_rtemsdir = $(includedir)/rtems
include_rtems_HEADERS = rtems/rtems_bsdnet.h rtems/rtems_bsdnet_internal.h \
- rtems/dhcp.h rtems/tftp.h rtems/ftpfs.h rtems/mkrootfs.h
+ rtems/dhcp.h rtems/rtems_dhcp_failsafe.h rtems/tftp.h rtems/ftpfs.h \
+ rtems/mkrootfs.h
include_rtems_HEADERS += rtems/rtems_mii_ioctl.h
libnetworking_a_SOURCES += rtems/sghostname.c rtems/issetugid.c \
rtems/rtems_glue.c rtems/rtems_malloc_mbuf.c rtems/rtems_syscall.c \
- rtems/rtems_bootp.c rtems/rtems_dhcp.c \
+ rtems/rtems_bootp.c rtems/rtems_dhcp.c rtems/rtems_dhcp_failsafe.c \
rtems/rtems_showmbuf.c rtems/rtems_showroute.c rtems/rtems_showifstat.c \
rtems/rtems_showipstat.c rtems/rtems_showicmpstat.c \
rtems/rtems_showtcpstat.c rtems/rtems_showudpstat.c rtems/rtems_select.c \
diff --git a/cpukit/libnetworking/nfs/bootp_subr.c b/cpukit/libnetworking/nfs/bootp_subr.c
index 64753f178b..a6bbe67a68 100644
--- a/cpukit/libnetworking/nfs/bootp_subr.c
+++ b/cpukit/libnetworking/nfs/bootp_subr.c
@@ -78,7 +78,7 @@
/*
* 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
+ * 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 */
@@ -377,8 +377,7 @@ bootpc_call(call,reply,procp)
* but delay each re-send by an increasing amount.
* If the delay hits the maximum, start complaining.
*/
- timo = 0;
- for (;;) {
+ for (timo=1; timo <= MAX_RESEND_DELAY; timo++) {
/* Send BOOTP request (or re-send). */
aio.iov_base = (caddr_t) call;
@@ -391,20 +390,24 @@ bootpc_call(call,reply,procp)
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;
+ 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;
+ }
}
- /* 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.
@@ -455,6 +458,9 @@ bootpc_call(call,reply,procp)
} /* while secs */
} /* forever send/receive */
+ printf("BOOTP timeout for server 0x%x\n",
+ (int)ntohl(sin->sin_addr.s_addr));
+
error = ETIMEDOUT;
goto out;
@@ -482,18 +488,21 @@ bootpc_fakeup_interface(struct ifreq *ireq,struct socket *so,
* 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);
+ 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)
- panic("bootpc_fakeup_interface: SIFFLAGS, error=%d", error);
+ 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)
*/
-
/* addr is 0.0.0.0 */
sin = (struct sockaddr_in *)&ireq->ifr_addr;
@@ -502,8 +511,10 @@ bootpc_fakeup_interface(struct ifreq *ireq,struct socket *so,
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);
+ if (error) {
+ printf("bootpc_fakeup_interface: set if addr, error=%s\n", strerror(error));
+ return error;
+ }
/* netmask is 0.0.0.0 */
@@ -513,8 +524,10 @@ bootpc_fakeup_interface(struct ifreq *ireq,struct socket *so,
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);
+ if (error) {
+ printf("bootpc_fakeup_interface: set if netmask, error=%s\n", strerror(error));
+ return error;
+ }
/* Broadcast is 255.255.255.255 */
@@ -524,8 +537,11 @@ bootpc_fakeup_interface(struct ifreq *ireq,struct socket *so,
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);
+ if (error) {
+ printf("bootpc_fakeup_interface: set broadcast addr, error=%s\n", strerror(error));
+ return error;
+ }
+
/* Add default route to 0.0.0.0 so we can send data */
@@ -601,8 +617,10 @@ bootpc_adjust_interface(struct ifreq *ireq,struct socket *so,
*/
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);
+ 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 */
@@ -612,13 +630,17 @@ bootpc_adjust_interface(struct ifreq *ireq,struct socket *so,
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);
+ 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)
- panic("nfs_boot: set if addr, error=%d", error);
+ if (error) {
+ printf("bootpc_adjust_interface: set if addr, error=%s\n", strerror(error));
+ return error;
+ }
/* Add new default route */
@@ -628,11 +650,10 @@ bootpc_adjust_interface(struct ifreq *ireq,struct socket *so,
(struct sockaddr *) &oldmask,
(RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL);
if (error) {
- printf("nfs_boot: add net route, error=%d\n", error);
- return error;
+ printf("bootpc_adjust_interface: add net route, error=%d\n", error);
}
- return 0;
+ return error;
}
#if !defined(__rtems__)
@@ -758,24 +779,30 @@ processOptions (unsigned char *optbuf, int optbufSize)
switch (code) {
case 1:
/* Subnet mask */
- if (len!=4)
- panic("bootpc: subnet mask len is %d",len);
+ 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)
- panic("bootpc: time offset len is %d",len);
+ 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)
- panic ("bootpc: Router Len is %d", len);
+ 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;
@@ -784,8 +811,10 @@ processOptions (unsigned char *optbuf, int optbufSize)
case 42:
/* NTP servers */
- if (len % 4)
- panic ("bootpc: time server Len is %d", len);
+ if (len % 4) {
+ printf ("bootpc: time server Len is %d\n", len);
+ continue;
+ }
{
int tlen = 0;
while ((tlen < len) &&
@@ -804,8 +833,10 @@ processOptions (unsigned char *optbuf, int optbufSize)
case 6:
/* Domain Name servers */
- if (len % 4)
- panic ("bootpc: DNS Len is %d", len);
+ if (len % 4) {
+ printf ("bootpc: DNS Len is %d", len);
+ continue;
+ }
{
int dlen = 0;
while ((dlen < len) &&
@@ -824,18 +855,23 @@ processOptions (unsigned char *optbuf, int optbufSize)
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");
+ 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)
- panic ("bootpc: Log server Len is %d", len);
+ 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;
@@ -856,8 +892,10 @@ processOptions (unsigned char *optbuf, int optbufSize)
case 52:
/* DHCP option override */
- if (len != 1)
- panic ("bootpc: DHCP option overload len is %d", len);
+ if (len != 1) {
+ printf ("bootpc: DHCP option overload len is %d", len);
+ continue;
+ }
dhcpOptionOverload = p[0];
break;
@@ -872,8 +910,10 @@ processOptions (unsigned char *optbuf, int optbufSize)
*/
case 54:
/* DHCP server */
- if (len != 4)
- panic ("bootpc: DHCP server len is %d", len);
+ if (len != 4) {
+ printf ("bootpc: DHCP server len is %d", len);
+ continue;
+ }
bcopy(p, &rtems_bsdnet_bootp_server_address, 4);
dhcp_gotserver = 1;
break;
@@ -955,20 +995,23 @@ bootpc_init(int update_files)
if ((ifp->if_flags &
(IFF_LOOPBACK|IFF_POINTOPOINT)) == 0)
break;
- if (ifp == NULL)
- panic("bootpc_init: no suitable interface");
+ 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)
- panic("nfs_boot: socreate, error=%d", error);
-
- bootpc_fakeup_interface(&ireq,so,procp);
+ 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;
+ }
- printf("Bootpc testing starting\n");
-
/* Get HW address */
for (ifa = ifp->if_addrlist;ifa; ifa = ifa->ifa_next)
@@ -977,11 +1020,15 @@ bootpc_init(int update_files)
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);
+ 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="";
@@ -1018,8 +1065,10 @@ bootpc_init(int update_files)
error = bootpc_call(&call,&reply,procp);
- if (error)
- panic("BOOTP call failed -- error %d", error);
+ if (error) {
+ printf("BOOTP call failed -- error %d", error);
+ return;
+ }
/*
* Initialize network address structures
diff --git a/cpukit/libnetworking/preinstall.am b/cpukit/libnetworking/preinstall.am
index 6637892502..090c09ffef 100644
--- a/cpukit/libnetworking/preinstall.am
+++ b/cpukit/libnetworking/preinstall.am
@@ -290,6 +290,10 @@ $(PROJECT_INCLUDE)/rtems/dhcp.h: rtems/dhcp.h $(PROJECT_INCLUDE)/rtems/$(dirstam
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/dhcp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/dhcp.h
+$(PROJECT_INCLUDE)/rtems/rtems_dhcp_failsafe.h: rtems/rtems_dhcp_failsafe.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/rtems_dhcp_failsafe.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/rtems_dhcp_failsafe.h
+
$(PROJECT_INCLUDE)/rtems/tftp.h: rtems/tftp.h $(PROJECT_INCLUDE)/rtems/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/tftp.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/tftp.h
diff --git a/cpukit/libnetworking/rtems/dhcp.h b/cpukit/libnetworking/rtems/dhcp.h
index f8cde76a41..fde94b8e4d 100644
--- a/cpukit/libnetworking/rtems/dhcp.h
+++ b/cpukit/libnetworking/rtems/dhcp.h
@@ -29,6 +29,8 @@ extern "C"
* 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.
diff --git a/cpukit/libnetworking/rtems/rtems_dhcp.c b/cpukit/libnetworking/rtems/rtems_dhcp.c
index db5783269b..16e5952f6b 100644
--- a/cpukit/libnetworking/rtems/rtems_dhcp.c
+++ b/cpukit/libnetworking/rtems/rtems_dhcp.c
@@ -10,6 +10,12 @@
*/
/*
+ * 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.
@@ -186,7 +192,6 @@ extern int bootpc_adjust_interface (struct ifreq *ireq,
struct proc *procp);
extern void *bootp_strdup_realloc (char *dst,
const char *src);
-extern int nfs_diskless_valid;
/*
* Variables
@@ -271,6 +276,8 @@ process_options (unsigned char *optbuf, int optbufSize)
int code, ncode;
char *p;
+ dhcp_message_type = 0;
+
ncode = optbuf[0];
while (j < optbufSize)
{
@@ -303,24 +310,30 @@ process_options (unsigned char *optbuf, int optbufSize)
{
case 1:
/* Subnet mask */
- if (len != 4)
- panic ("dhcpc: subnet mask len is %d", len);
+ 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)
- panic ("dhcpc: time offset len is %d", len);
+ 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)
- panic ("dhcpc: Router Len is %d", len);
+ if (len % 4) {
+ printf ("dhcpc: Router Len is %d\n", len);
+ continue;
+ }
if (len > 0)
{
memcpy (&dhcp_gw.sin_addr, p, 4);
@@ -330,8 +343,10 @@ process_options (unsigned char *optbuf, int optbufSize)
case 42:
/* NTP servers */
- if (len % 4)
- panic ("dhcpc: time server Len is %d", len);
+ if (len % 4) {
+ printf ("dhcpc: time server Len is %d\n", len);
+ continue;
+ }
{
int tlen = 0;
while ((tlen < len) &&
@@ -349,8 +364,10 @@ process_options (unsigned char *optbuf, int optbufSize)
case 6:
/* Domain Name servers */
- if (len % 4)
- panic ("dhcpc: DNS Len is %d", len);
+ if (len % 4) {
+ printf ("dhcpc: DNS Len is %d\n", len);
+ continue;
+ }
{
int dlen = 0;
while ((dlen < len) &&
@@ -368,10 +385,12 @@ process_options (unsigned char *optbuf, int optbufSize)
case 12:
/* Host name */
- if (len >= MAXHOSTNAMELEN)
- panic ("dhcpc: hostname >= %d bytes", MAXHOSTNAMELEN);
+ if (len >= MAXHOSTNAMELEN) {
+ printf ("dhcpc: hostname >= %d bytes\n", MAXHOSTNAMELEN);
+ len = MAXHOSTNAMELEN-1;
+ }
if (sethostname (p, len) < 0)
- panic ("dhcpc: can't set host name");
+ printf ("dhcpc: can't set host name");
if (dhcp_hostname != NULL)
{
dhcp_hostname = realloc (dhcp_hostname, len);
@@ -383,8 +402,10 @@ process_options (unsigned char *optbuf, int optbufSize)
case 7:
/* Log servers */
- if (len % 4)
- panic ("dhcpc: Log server Len is %d", len);
+ if (len % 4) {
+ printf ("dhcpc: Log server Len is %d\n", len);
+ continue;
+ }
if (len > 0)
{
memcpy (&rtems_bsdnet_log_host_address, p, 4);
@@ -406,7 +427,7 @@ process_options (unsigned char *optbuf, int optbufSize)
case 50:
/* DHCP Requested IP Address */
if (len != 4)
- panic ("dhcpc: DHCP option requested IP len is %d", len);
+ 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
@@ -416,23 +437,29 @@ process_options (unsigned char *optbuf, int optbufSize)
case 51:
/* DHCP Lease Length */
- if (len != 4)
- panic ("dhcpc: DHCP option lease-length len is %d", len);
+ 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)
- panic ("dhcpc: DHCP option overload len is %d", len);
+ 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)
- panic ("dhcpc: DHCP message len is %d", len);
+ if (len != 1) {
+ printf ("dhcpc: DHCP message len is %d", len);
+ continue;
+ }
dhcp_message_type = p[0];
break;
@@ -447,8 +474,10 @@ process_options (unsigned char *optbuf, int optbufSize)
*/
case 54:
/* DHCP server */
- if (len != 4)
- panic ("dhcpc: DHCP server len is %d", len);
+ if (len != 4) {
+ printf ("dhcpc: DHCP server len is %d", len);
+ continue;
+ }
memcpy (&rtems_bsdnet_bootp_server_address, p, 4);
dhcp_gotserver = 1;
break;
@@ -667,13 +696,28 @@ dhcp_task (rtems_task_argument _sdl)
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 ();
@@ -684,10 +728,12 @@ dhcp_task (rtems_task_argument _sdl)
* Send the Request.
*/
error = bootpc_call (&call, &dhcp_req, procp);
-
- if (error)
- panic ("DHCP call failed -- error %d", error);
-
+ if (error) {
+ rtems_bsdnet_semaphore_release ();
+ printf ("DHCP call failed -- error %d", error);
+ continue;
+ }
+
/*
* Check for DHCP ACK/NACK
*/
@@ -696,7 +742,8 @@ dhcp_task (rtems_task_argument _sdl)
sizeof (dhcp_magic_cookie)) != 0)
{
rtems_bsdnet_semaphore_release ();
- panic ("DHCP server did not send Magic Cookie.\n");
+ printf ("DHCP server did not send Magic Cookie.\n");
+ continue;
}
process_options (&dhcp_req.vend[4], sizeof (dhcp_req.vend) - 4);
@@ -704,23 +751,21 @@ dhcp_task (rtems_task_argument _sdl)
if (dhcp_message_type != DHCP_ACK)
{
rtems_bsdnet_semaphore_release ();
- panic ("DHCP server did not accept the DHCP request");
+ printf ("DHCP server did not accept the DHCP request");
+ continue;
}
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++;
}
+
+
+ dhcp_task_id = 0;
+ printf ("dhcpc: exiting lease renewal task.\n");
+ rtems_task_delete( RTEMS_SELF);
+
}
/*
@@ -795,8 +840,12 @@ dhcp_interface_has_ip (struct ifreq *ireq, struct socket *so, struct proc *procp
* 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
*/
-void
+int
dhcp_init (int update_files)
{
struct dhcp_packet call;
@@ -811,12 +860,6 @@ dhcp_init (int update_files)
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
@@ -834,13 +877,18 @@ dhcp_init (int update_files)
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");
+ 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)
- panic ("nfs_boot: socreate, error=%d", error);
+ 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);
@@ -854,11 +902,15 @@ dhcp_init (int update_files)
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",
+ 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
@@ -869,19 +921,25 @@ dhcp_init (int update_files)
* Send the Discover.
*/
error = bootpc_call (&call, &reply, procp);
- if (error)
- panic ("BOOTP call failed -- error %d", error);
+ 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)
- panic ("DHCP server did not send Magic Cookie.\n");
+ 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)
- panic ("DHCP server did not send a DHCP Offer.\n");
+ if (dhcp_message_type != DHCP_OFFER) {
+ printf ("DHCP server did not send a DHCP Offer.\n");
+ return -1;
+ }
/*
* Send a DHCP REQUEST
@@ -889,19 +947,25 @@ dhcp_init (int update_files)
dhcp_request_req (&call, &reply, sdl, TRUE);
error = bootpc_call (&call, &reply, procp);
- if (error)
- panic ("BOOTP call failed -- error %d", error);
+ 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)
- panic ("DHCP server did not send Magic Cookie.\n");
+ 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)
- panic ("DHCP server did not accept the DHCP request");
+ if (dhcp_message_type != DHCP_ACK) {
+ printf ("DHCP server did not accept the DHCP request\n");
+ return -1;
+ }
/*
* Initialize network address structures
@@ -1039,6 +1103,8 @@ dhcp_init (int update_files)
dhcp_start_task (sdl, &reply, 150);
soclose (so);
+
+ return 0;
}
/*
@@ -1049,10 +1115,32 @@ dhcp_init (int update_files)
void rtems_bsdnet_do_dhcp (void)
{
rtems_bsdnet_semaphore_obtain ();
- dhcp_init (TRUE);
+ while( dhcp_init (TRUE) < 0 ) {
+ rtems_bsdnet_semaphore_release();
+ rtems_task_wake_after(TOD_MILLISECONDS_TO_TICKS(1000));
+ rtems_bsdnet_semaphore_obtain ();
+ }
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,
@@ -1092,8 +1180,10 @@ rtems_bsdnet_do_dhcp_refresh_only (unsigned long xid,
}
}
- if (!match)
- panic ("dhcpc: no matching interface");
+ 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 &&
@@ -1101,8 +1191,10 @@ rtems_bsdnet_do_dhcp_refresh_only (unsigned long xid,
sdl->sdl_type == IFT_ETHER)
break;
- if (!match)
- panic ("dhcpc: no matching interface");
+ if (!match) {
+ printf ("dhcpc: no matching interface address\n");
+ return;
+ }
/*
* Set up given values in a simulated DHCP reply.
diff --git a/cpukit/libnetworking/rtems/rtems_dhcp_failsafe.c b/cpukit/libnetworking/rtems/rtems_dhcp_failsafe.c
new file mode 100644
index 0000000000..3f69882c33
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_dhcp_failsafe.c
@@ -0,0 +1,372 @@
+/*
+ $Id$
+
+ Description: Wrapper around DHCP client to restart it when the interface
+ moves to another network.
+
+ Authors: Arnout Vandecappelle <arnout@mind.be>, Essensium/Mind
+ Maarten Van Es <maarten@mind.be>, Essensium/Mind
+ (C) Septentrio 2008
+
+ The license and distribution terms for this file may be
+ found in the file LICENSE in this distribution or at
+ http://www.rtems.com/license/LICENSE.
+
+
+ To use this functionality, call rtems_bsdnet_do_dhcp_failsafe() or set it
+ as the bootp member of the rtems_bsdnet_config structure.
+
+ The rtems_bsdnet_do_dhcp_failsafe() function provides the following
+ functionalities:
+
+ * It starts DHCP on the first non-loopback, non-point-to-point interface.
+ Before DHCP is started, any existing IP address on that interface is
+ removed, as well as the default route.
+
+ * If DHCP fails to acquire an address for whatever reason, the interface
+ is reconfigured with the static address provided in its
+ rtems_bsdnet_ifconfig structure, and the default route from
+ rtems_bsdnet_config is restored.
+ It is possible to change the address in the rtems_bsdnet_ifconfig structure
+ while the system is running.
+
+ * Optionally, after the interface is configured (either with DHCP or
+ statically), a task is started to monitor it. When the interface remains
+ disconnected (i.e. its IFF_RUNNING flag is off) for NETWORK_FAIL_TIMEOUT
+ seconds, the dhcp lease renewal is stopped. As soon as the interface is
+ connected again, DHCP is started again as above.
+ If NETWORK_FAIL_TIMEOUT is set to 0, the monitor task is not started.
+
+ * Optionally, when the interface is disconnected, it is also brought down
+ for NETWORK_DOWN_TIME seconds. Since this possibly makes the IFF_RUNNING
+ flag unuseable, the interface is brought up again before the flag is
+ polled.
+ If NETWORK_DOWN_TIME is set to 0, the interface is not brought down.
+
+ * Optionally, before DHCP is started, we wait for BROADCAST_DELAY seconds.
+ This is necessary to allow some routers to perform spanning tree discovery.
+
+ Note that DHCP doesn't work well with multiple interfaces: only one of them
+ is configured using DHCP, and we can't guarantee it's the same one that is
+ monitored by this function.
+
+*/
+
+#include <rtems.h>
+#include <rtems/error.h>
+#include <rtems/rtems_bsdnet.h>
+#include <rtems/rtems_bsdnet_internal.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rtems/dhcp.h>
+
+struct proc; /* Unused parameter of some functions. */
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/route.h>
+#include <netinet/in.h> /* for sockaddr_in */
+#include <net/if.h> /* for if.h */
+#include <net/if_var.h> /* for in_var.h */
+#include <netinet/in_var.h> /* for in_aliasreq */
+#include <sys/sockio.h> /* for ioctl definitions */
+#include <arpa/inet.h> /* for inet_addr, inet_ntop */
+
+
+#define NETWORK_FAIL_TIMEOUT 5 /* the number of seconds before the interface is considered disconnected */
+#define NETWORK_DOWN_TIME 30 /* number of seconds the interface remains down */
+#define BROADCAST_DELAY 0 /* Delay (seconds) before broadcasts are sent */
+#define DHCP_MONITOR_PRIORITY 250 /* Low priority */
+
+/*
+ * returns 0 when successful, negative value for failure
+ */
+static int remove_address(const char *if_name)
+{
+ struct sockaddr_in address;
+ struct in_aliasreq ifra;
+ int retval = 0;
+
+ memset (&address, '\0', sizeof (address));
+ address.sin_len = sizeof (address);
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = INADDR_ANY;
+
+ /* Remove old default route to 0.0.0.0 */
+ if (rtems_bsdnet_rtrequest (RTM_DELETE, (struct sockaddr *)&address, NULL,
+ (struct sockaddr *)&address,
+ (RTF_UP | RTF_STATIC), NULL) < 0 ) {
+ printf ("Failed to delete default route: %s (%d)\n", strerror (errno), errno);
+ retval = -1;
+ }
+
+ /* Remove old ip-address */
+ if (rtems_bsdnet_ifconfig(if_name, SIOCGIFADDR, &address) < 0) {
+ printf ("Failed to get if address: %s (%d)\n", strerror (errno), errno);
+ return -1;
+ }
+
+ strncpy (ifra.ifra_name, if_name, IFNAMSIZ);
+ memcpy (&ifra.ifra_addr, &address, sizeof(address));
+ if (rtems_bsdnet_ifconfig(if_name, SIOCDIFADDR, &ifra)) {
+ printf ("Can't delete if address: %s (%d)\n", strerror (errno), errno);
+ return -1;
+ }
+
+ return retval;
+}
+
+
+#if NETWORK_DOWN_TIME
+static int
+dhcp_if_down (const char* ifname)
+{
+ int flags;
+ if (rtems_bsdnet_ifconfig (ifname, SIOCGIFFLAGS, &flags) < 0) {
+ printf ("Can't get flags for %s: %s\n", ifname, strerror (errno));
+ return -1;
+ }
+ if (flags & IFF_UP) {
+ flags &= ~IFF_UP;
+ if (rtems_bsdnet_ifconfig (ifname, SIOCSIFFLAGS, &flags) < 0) {
+ printf ("Can't bring %s down: %s\n", ifname, strerror (errno));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+#endif
+
+static int
+dhcp_if_up (const char* ifname)
+{
+ int flags;
+ if (rtems_bsdnet_ifconfig (ifname, SIOCGIFFLAGS, &flags) < 0) {
+ printf ("Can't get flags for %s: %s\n", ifname, strerror (errno));
+ return -1;
+ }
+ if (!(flags & IFF_UP)) {
+ flags |= IFF_UP;
+ if (rtems_bsdnet_ifconfig (ifname, SIOCSIFFLAGS, &flags) < 0) {
+ printf ("Can't bring %s up: %s\n", ifname, strerror (errno));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+
+static int
+set_static_address (struct rtems_bsdnet_ifconfig *ifp)
+{
+ short flags;
+ struct sockaddr_in address;
+ struct sockaddr_in netmask;
+ struct sockaddr_in broadcast;
+ struct sockaddr_in gateway;
+
+ if (ifp->ip_address != NULL) {
+ printf("Setting static address for interface %s.\n", ifp->name);
+
+ /*
+ * Bring interface up
+ */
+ if (dhcp_if_up (ifp->name) < 0)
+ return -1;
+
+ /*
+ * Set interface netmask
+ */
+ memset (&netmask, '\0', sizeof netmask);
+ netmask.sin_len = sizeof netmask;
+ netmask.sin_family = AF_INET;
+ netmask.sin_addr.s_addr = inet_addr (ifp->ip_netmask);
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFNETMASK, &netmask) < 0) {
+ printf ("Can't set %s netmask: %s\n", ifp->name, strerror (errno));
+ return -1;
+ }
+
+ /*
+ * Set interface address
+ */
+ memset (&address, '\0', sizeof address);
+ address.sin_len = sizeof address;
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = inet_addr (ifp->ip_address);
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFADDR, &address) < 0) {
+ printf ("Can't set %s address: %s\n", ifp->name, strerror (errno));
+ return -1;
+ }
+
+ /*
+ * Set interface broadcast address if the interface has the
+ * broadcast flag set.
+ */
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCGIFFLAGS, &flags) < 0) {
+ printf ("Can't read %s flags: %s\n", ifp->name, strerror (errno));
+ return -1;
+ }
+ if (flags & IFF_BROADCAST) {
+ memset (&broadcast, '\0', sizeof broadcast);
+ broadcast.sin_len = sizeof broadcast;
+ broadcast.sin_family = AF_INET;
+ broadcast.sin_addr.s_addr = address.sin_addr.s_addr | ~netmask.sin_addr.s_addr;
+
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCSIFBRDADDR, &broadcast) < 0) {
+ struct in_addr in_addr;
+ char buf[20];
+
+ in_addr.s_addr = broadcast.sin_addr.s_addr;
+ if (!inet_ntop (AF_INET, &in_addr, buf, sizeof (buf)))
+ strcpy (buf, "?.?.?.?");
+ printf ("Can't set %s broadcast address %s: %s\n", ifp->name, buf, strerror (errno));
+ }
+ }
+ }
+
+ /*
+ * Set default route
+ */
+ if (rtems_bsdnet_config.gateway) {
+ address.sin_addr.s_addr = INADDR_ANY;
+ netmask.sin_addr.s_addr = INADDR_ANY;
+ memset (&gateway, '\0', sizeof gateway);
+ gateway.sin_len = sizeof gateway;
+ gateway.sin_family = AF_INET;
+ gateway.sin_addr.s_addr = inet_addr (rtems_bsdnet_config.gateway);
+
+ if (rtems_bsdnet_rtrequest (RTM_ADD,
+ (struct sockaddr *) &address,
+ (struct sockaddr *) &gateway,
+ (struct sockaddr *) &netmask,
+ (RTF_UP | RTF_GATEWAY | RTF_STATIC),
+ NULL
+ ) < 0) {
+ printf ("Can't set default route: %s\n", strerror (errno));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void
+do_dhcp_init (struct rtems_bsdnet_ifconfig *ifp)
+{
+#if BROADCAST_DELAY
+ /* Wait before sending broadcast. */
+ rtems_task_wake_after(TOD_MILLISECONDS_TO_TICKS(BROADCAST_DELAY * 1000));
+#endif
+
+ printf ("starting dhcp client...\n");
+
+ remove_address(ifp->name);
+ if (rtems_bsdnet_do_dhcp_timeout () != 0) {
+ remove_address(ifp->name);
+ set_static_address (ifp); /* use static ip-address if dhcp failed */
+ }
+
+}
+
+/*
+ * Main dhcp monitor thread
+ */
+static void dhcp_monitor_task (rtems_task_argument ifp_arg)
+{
+ struct rtems_bsdnet_ifconfig *ifp = (struct rtems_bsdnet_ifconfig *)ifp_arg;
+ char *ifname = ifp->name;
+ unsigned int downcount = 0;
+ int ifflags;
+ int must_renew = FALSE;
+
+ while (TRUE) {
+ if (rtems_bsdnet_ifconfig(ifname, SIOCGIFFLAGS, &ifflags) < 0) {
+ printf ("Failed to get if flags: %s (%d)\n", strerror (errno), errno);
+ goto error_out;
+ }
+
+ if ((ifflags & IFF_RUNNING) != 0) {
+ if(must_renew) {
+ must_renew = FALSE;
+ do_dhcp_init(ifp);
+ }
+ downcount = 0;
+ } else {
+ if (downcount < NETWORK_FAIL_TIMEOUT) {
+ downcount++;
+
+ if (downcount == NETWORK_FAIL_TIMEOUT) {
+ printf ("lost network connection...\n");
+ rtems_bsdnet_dhcp_down ();
+ must_renew = TRUE;
+#if NETWORK_DOWN_TIME
+ dhcp_if_down(ifname);
+ rtems_task_wake_after(TOD_MILLISECONDS_TO_TICKS(NETWORK_DOWN_TIME * 1000));
+ dhcp_if_up(ifname);
+ downcount = 0;
+#endif
+ }
+ }
+ }
+
+ rtems_task_wake_after(TOD_MILLISECONDS_TO_TICKS(1000));
+ }
+
+error_out:
+ printf("Stopping dhcp monitoring application.\n");
+ rtems_task_delete(RTEMS_SELF);
+}
+
+/*
+* initialize dhcp monitoring application
+* start dhcp monitoring thread
+*/
+void rtems_bsdnet_do_dhcp_failsafe (void)
+{
+ rtems_status_code sc;
+ rtems_id id;
+ struct rtems_bsdnet_ifconfig *ifp;
+ int ifflags;
+
+ /* Find a suitable interface */
+ for (ifp = rtems_bsdnet_config.ifconfig; ifp; ifp = ifp->next) {
+ if (rtems_bsdnet_ifconfig (ifp->name, SIOCGIFFLAGS, &ifflags) < 0)
+ continue;
+ if ((ifflags & (IFF_LOOPBACK | IFF_POINTOPOINT)) == 0)
+ break;
+ }
+ if (ifp == NULL){
+ printf ("dhcpc_failsafe: no suitable interface\n");
+ return;
+ }
+ printf("starting dhcp on interface %s\n", ifp->name);
+ do_dhcp_init(ifp);
+
+#if NETWORK_FAIL_TIMEOUT
+ sc = rtems_task_create (rtems_build_name ('d','h','c','m'),
+ DHCP_MONITOR_PRIORITY,
+ 2048,
+ RTEMS_PREEMPT |
+ RTEMS_NO_TIMESLICE |
+ RTEMS_NO_ASR |
+ RTEMS_INTERRUPT_LEVEL (0),
+ RTEMS_LOCAL,
+ &id);
+
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("Failed to create dhcp monitor task, code %d\n", sc);
+ return;
+ }
+
+ sc = rtems_task_start (id, dhcp_monitor_task, (rtems_task_argument) ifp);
+
+ if (sc != RTEMS_SUCCESSFUL) {
+ printf ("Failed to start dhcp monitor task, code %d\n", sc);
+ }
+#endif
+}
+
diff --git a/cpukit/libnetworking/rtems/rtems_dhcp_failsafe.h b/cpukit/libnetworking/rtems/rtems_dhcp_failsafe.h
new file mode 100644
index 0000000000..24c1c900c0
--- /dev/null
+++ b/cpukit/libnetworking/rtems/rtems_dhcp_failsafe.h
@@ -0,0 +1,29 @@
+/*
+ $Id$
+
+ Description: Wrapper around DHCP client to restart it when the interface
+ moves to another network.
+
+ Authors: Arnout Vandecappelle <arnout@mind.be>, Essensium/Mind
+ Maarten Van Es <maarten@mind.be>, Essensium/Mind
+ (C) Septentrio 2008
+
+ The license and distribution terms for this file may be
+ found in the file LICENSE in this distribution or at
+ http://www.rtems.com/license/LICENSE.
+*/
+
+#ifndef _RTEMS_DHCP_FAILSAFE_H_
+#define _RTEMS_DHCP_FAILSAFE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void rtems_bsdnet_do_dhcp_failsafe (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/cpukit/libnetworking/rtems/rtems_glue.c b/cpukit/libnetworking/rtems/rtems_glue.c
index 88f05dad90..52db0e0f49 100644
--- a/cpukit/libnetworking/rtems/rtems_glue.c
+++ b/cpukit/libnetworking/rtems/rtems_glue.c
@@ -1127,7 +1127,7 @@ int rtems_bsdnet_ifconfig (const char *ifname, uint32_t cmd, void *param)
case SIOCAIFADDR:
case SIOCDIFADDR:
- r = ioctl(s, cmd, (struct freq *) param);
+ r = ioctl(s, cmd, (struct ifreq *) param);
break;
default: