summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1998-11-19 17:35:49 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1998-11-19 17:35:49 +0000
commit847375f3ad4af55b9bd4d8a6daff313165de5fd8 (patch)
tree53d4acf4aaffaaaa6e7aafa52f2457fdf2758e44
parentChanged BOOTP -> BOOTP/DHCP. (diff)
downloadrtems-847375f3ad4af55b9bd4d8a6daff313165de5fd8.tar.bz2
Patch from Eric Norum <eric@skatter.usask.ca>:
1) Socket timeout field changed from `short' to `long'. This makes longer timeouts possible. With a 1 kHz system clock the old system allowed timeouts only up to a little over 30 seconds! This change is a slightly cleaned-up version of the patch proposed by Ian Lance Taylor. 2) Major changes to BOOTP/DHCP reply handling. Now supports much of RFC2132. These changes were done at the request of, and with the assistance of, Erik Ivanenko. If you're making changes, you might want to change the network supplement Essentially just do a global search and replace of BOOTP with BOOTP/DHCP.
-rw-r--r--c/src/exec/libnetworking/kern/uipc_socket.c7
-rw-r--r--c/src/exec/libnetworking/nfs/bootp_subr.c381
-rw-r--r--c/src/exec/libnetworking/rtems/rtems_bsdnet.h1
-rw-r--r--c/src/exec/libnetworking/rtems/rtems_glue.c1
-rw-r--r--c/src/exec/libnetworking/sys/socketvar.h4
-rw-r--r--c/src/exec/posix/src/psignal.c2
-rw-r--r--c/src/exec/score/headers/thread.h7
-rw-r--r--c/src/exec/score/include/rtems/score/thread.h7
-rw-r--r--c/src/exec/score/src/thread.c8
-rw-r--r--c/src/lib/libbsp/powerpc/psim/startup/device-tree3
-rw-r--r--c/src/lib/libbsp/powerpc/psim/startup/linkcmds7
-rw-r--r--c/src/lib/libnetworking/kern/uipc_socket.c7
-rw-r--r--c/src/lib/libnetworking/nfs/bootp_subr.c381
-rw-r--r--c/src/lib/libnetworking/rtems/rtems_bsdnet.h1
-rw-r--r--c/src/lib/libnetworking/rtems/rtems_glue.c1
-rw-r--r--c/src/lib/libnetworking/sys/socketvar.h4
-rw-r--r--c/src/libnetworking/kern/uipc_socket.c7
-rw-r--r--c/src/libnetworking/nfs/bootp_subr.c381
-rw-r--r--c/src/libnetworking/rtems/rtems_bsdnet.h1
-rw-r--r--c/src/libnetworking/rtems/rtems_glue.c1
-rw-r--r--c/src/libnetworking/sys/socketvar.h4
-rw-r--r--cpukit/libnetworking/kern/uipc_socket.c7
-rw-r--r--cpukit/libnetworking/nfs/bootp_subr.c381
-rw-r--r--cpukit/libnetworking/rtems/rtems_bsdnet.h1
-rw-r--r--cpukit/libnetworking/rtems/rtems_glue.c1
-rw-r--r--cpukit/libnetworking/sys/socketvar.h4
-rw-r--r--cpukit/posix/src/psignal.c2
-rw-r--r--cpukit/score/include/rtems/score/thread.h7
-rw-r--r--cpukit/score/src/thread.c8
29 files changed, 925 insertions, 702 deletions
diff --git a/c/src/exec/libnetworking/kern/uipc_socket.c b/c/src/exec/libnetworking/kern/uipc_socket.c
index 895d1c7d45..04489f4017 100644
--- a/c/src/exec/libnetworking/kern/uipc_socket.c
+++ b/c/src/exec/libnetworking/kern/uipc_socket.c
@@ -49,6 +49,7 @@
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
#include <sys/sysctl.h>
+#include <limits.h>
static int somaxconn = SOMAXCONN;
SYSCTL_INT(_kern, KERN_SOMAXCONN, somaxconn, CTLFLAG_RW, &somaxconn, 0, "");
@@ -948,14 +949,14 @@ sosetopt(so, level, optname, m0)
case SO_RCVTIMEO:
{
struct timeval *tv;
- short val;
+ unsigned long val;
if (m == NULL || m->m_len < sizeof (*tv)) {
error = EINVAL;
goto bad;
}
tv = mtod(m, struct timeval *);
- if (tv->tv_sec > SHRT_MAX / hz - hz) {
+ if (tv->tv_sec >= (ULONG_MAX - hz) / hz) {
error = EDOM;
goto bad;
}
@@ -1065,7 +1066,7 @@ sogetopt(so, level, optname, mp)
case SO_SNDTIMEO:
case SO_RCVTIMEO:
{
- int val = (optname == SO_SNDTIMEO ?
+ unsigned long val = (optname == SO_SNDTIMEO ?
so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
m->m_len = sizeof(struct timeval);
diff --git a/c/src/exec/libnetworking/nfs/bootp_subr.c b/c/src/exec/libnetworking/nfs/bootp_subr.c
index cb7d3d3407..f6831eed71 100644
--- a/c/src/exec/libnetworking/nfs/bootp_subr.c
+++ b/c/src/exec/libnetworking/nfs/bootp_subr.c
@@ -682,6 +682,162 @@ static void printip(char *prefix,struct in_addr addr)
ip >> 24, (ip >> 16) & 255 ,(ip >> 8) & 255 ,ip & 255 );
}
+static int dhcpOptionOverload = 0;
+static char dhcp_gotgw = 0;
+static char dhcp_gotnetmask = 0;
+static char dhcp_gotserver = 0;
+static char dhcp_gotlogserver = 0;
+static struct sockaddr_in dhcp_netmask;
+static struct sockaddr_in dhcp_gw;
+
+static void
+processOptions (unsigned char *optbuf, int optbufSize)
+{
+ int j = 0;
+ int len;
+ int code, ncode;
+ char *p;
+
+ ncode = optbuf[0];
+ while (j < optbufSize) {
+ code = optbuf[j] = ncode;
+ if (code == 255)
+ return;
+ if (code == 0) {
+ j++;
+ continue;
+ }
+ len = optbuf[j+1];
+ j += 2;
+ if ((len + j) >= optbufSize) {
+ printf ("Truncated field for code %d", code);
+ return;
+ }
+ ncode = optbuf[j+len];
+ optbuf[j+len] = '\0';
+ p = &optbuf[j];
+ j += len;
+
+ /*
+ * Process the option
+ */
+ 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, unused */
+ 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;
+ }
+ break;
+
+ case 6:
+ /* Domain Name servers */
+ if (len % 4)
+ panic ("bootpc: DNS Len is %d", len);
+ {
+ int dlen = 0;
+ while ((dlen < len) &&
+ (rtems_bsdnet_nameserver_count < sizeof rtems_bsdnet_config.name_server /
+ sizeof rtems_bsdnet_config.name_server[0])) {
+ bcopy (p+dlen,
+ &rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count],
+ 4);
+ printip("Domain Name Server",
+ rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count]);
+ rtems_bsdnet_nameserver_count++;
+ dlen += 4;
+ }
+ }
+ break;
+
+ case 12:
+ /* Host name */
+ if (len>=MAXHOSTNAMELEN)
+ panic ("bootpc: hostname >=%d bytes", MAXHOSTNAMELEN);
+ if (sethostname (p, len) < 0)
+ panic("Can't set host name");
+ printf("Hostname is %s\n", 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;
+ }
+ break;
+
+ case 15:
+ /* Domain name */
+ if (p[0]) {
+ rtems_bsdnet_domain_name = strdup (p);
+ printf("Domain name is %s\n", rtems_bsdnet_domain_name);
+ }
+ break;
+
+ case 16: /* Swap server IP address. unused */
+ break;
+
+ case 52:
+ /* DHCP option override */
+ if (len != 1)
+ panic ("bootpc: DHCP option overload len is %d", len);
+ dhcpOptionOverload = p[0];
+ break;
+
+ case 128: /* Site-specific option for DHCP servers that
+ * a) don't supply tag 54
+ * and
+ * b) don't supply the server address in siaddr
+ * For example, on Solaris 2.6 in.dhcpd, include in the dhcptab:
+ * Bootsrv s Site,128,IP,1,1
+ * and use that symbol in the macro that defines the client:
+ * Bootsrv=<tftp-server-ip-address>
+ */
+ 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;
+
+ case 66:
+ /* DHCP server name option */
+ if (p[0])
+ rtems_bsdnet_bootp_server_name = strdup (p);
+ break;
+
+ case 67:
+ /* DHCP bootfile option */
+ if (p[0])
+ rtems_bsdnet_bootp_boot_file_name = strdup (p);
+ break;
+
+ default:
+ printf ("Ignoring BOOTP/DHCP option code %d\n", code);
+ break;
+ }
+ }
+}
+
+#define EALEN 6
+
void
bootpc_init(void)
{
@@ -692,27 +848,9 @@ bootpc_init(void)
struct ifreq ireq;
struct ifnet *ifp;
struct socket *so;
- int error;
- int code,ncode,len;
int j;
- char *p;
- unsigned int ip;
-
+ int error;
struct sockaddr_in myaddr;
- struct sockaddr_in netmask;
- struct sockaddr_in gw;
- int gotgw=0;
- int gotnetmask=0;
-#if !defined(__rtems__)
- int gotrootpath=0;
- int gotswappath=0;
-#endif
- char lookup_path[24];
-
-#define EALEN 6
-#if !defined(__rtems__)
- unsigned char ea[EALEN];
-#endif
struct ifaddr *ifa;
struct sockaddr_dl *sdl = NULL;
char *delim;
@@ -725,12 +863,6 @@ bootpc_init(void)
return;
/*
- * Bump time if 0.
- if (!time.tv_sec)
- time.tv_sec++;
- */
-
- /*
* Find a network interface.
*/
for (ifp = ifnet; ifp != 0; ifp = ifp->if_next)
@@ -803,166 +935,77 @@ bootpc_init(void)
if (error)
panic("BOOTP call failed -- error %d", error);
+ /*
+ * Initialize network address structures
+ */
bzero(&myaddr,sizeof(myaddr));
- bzero(&netmask,sizeof(netmask));
- bzero(&gw,sizeof(gw));
-
+ bzero(&dhcp_netmask,sizeof(dhcp_netmask));
+ bzero(&dhcp_gw,sizeof(dhcp_gw));
myaddr.sin_len = sizeof(myaddr);
myaddr.sin_family = AF_INET;
+ dhcp_netmask.sin_len = sizeof(dhcp_netmask);
+ dhcp_netmask.sin_family = AF_INET;
+ dhcp_gw.sin_len = sizeof(dhcp_gw);
+ dhcp_gw.sin_family= AF_INET;
- netmask.sin_len = sizeof(netmask);
- netmask.sin_family = AF_INET;
-
- gw.sin_len = sizeof(gw);
- gw.sin_family= AF_INET;
-
- rtems_bsdnet_bootp_server_address = reply.siaddr;
- rtems_bsdnet_log_host_address = reply.siaddr;
-
+ /*
+ * Set our address
+ */
myaddr.sin_addr = reply.yiaddr;
-
- ip = ntohl(myaddr.sin_addr.s_addr);
- sprintf(lookup_path,"swap.%d.%d.%d.%d",
- ip >> 24, (ip >> 16) & 255 ,(ip >> 8) & 255 ,ip & 255 );
-
printip("My ip address",myaddr.sin_addr);
- printip("Server ip address",reply.siaddr);
-
- gw.sin_addr = reply.giaddr;
- printip("Gateway ip address",reply.giaddr);
-
- if (reply.sname[0])
- printf("Server name is %s\n",reply.sname);
- if (reply.file[0])
- printf("boot file is %s\n",reply.file);
- rtems_bsdnet_bootp_boot_file_name = strdup (reply.file);
+ /*
+ * Process BOOTP/DHCP options
+ */
if (reply.vend[0]==99 && reply.vend[1]==130 &&
reply.vend[2]==83 && reply.vend[3]==99) {
- j=4;
- ncode = reply.vend[j];
- while (j<sizeof(reply.vend)) {
- code = reply.vend[j] = ncode;
- if (code==255)
- break;
- if (code==0) {
- j++;
- continue;
- }
- len = reply.vend[j+1];
- j+=2;
- if (len+j>=sizeof(reply.vend)) {
- printf("Truncated field");
- break;
- }
- ncode = reply.vend[j+len];
- reply.vend[j+len]='\0';
- p = &reply.vend[j];
- switch (code) {
- case 1:
- if (len!=4)
- panic("bootpc: subnet mask len is %d",len);
- bcopy(&reply.vend[j],&netmask.sin_addr,4);
- gotnetmask=1;
- printip("Subnet mask",netmask.sin_addr);
- break;
- case 6:
- /* Domain Name servers */
- if (len % 4)
- panic("bootpc: DNS Len is %d",len);
- {
- int dlen = 0;
- while ((dlen < len) &&
- (rtems_bsdnet_nameserver_count < sizeof rtems_bsdnet_config.name_server /
- sizeof rtems_bsdnet_config.name_server[0])) {
- bcopy(&reply.vend[j+dlen],
- &rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count],
- 4);
- printip("Domain Name Server",
- rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count]);
- rtems_bsdnet_nameserver_count++;
- dlen += 4;
- }
- }
- break;
- case 16: /* Swap server IP address. unused */
- case 2:
- /* Time offset */
- break;
- case 3:
- /* Routers */
- if (len % 4)
- panic("bootpc: Router Len is %d",len);
- if (len > 0) {
- bcopy(&reply.vend[j],&gw.sin_addr,4);
- printip("Router",gw.sin_addr);
- gotgw=1;
- }
- break;
- case 7:
- /* Log servers */
- if (len % 4)
- panic("bootpc: Log server len is %d",len);
- if (len > 0) {
- bcopy(&reply.vend[j],&rtems_bsdnet_log_host_address,4);
- printip("Log server",rtems_bsdnet_log_host_address);
- }
- break;
- case 12:
- if (len>=MAXHOSTNAMELEN)
- panic("bootpc: hostname >=%d bytes",MAXHOSTNAMELEN);
- if (sethostname (&reply.vend[j], len) < 0)
- panic("Can't set host name");
- printf("Hostname is %.*s\n",len,&reply.vend[j]);
- break;
- case 15:
- /* Domain name */
- rtems_bsdnet_domain_name = strdup (&reply.vend[j]);
- if (rtems_bsdnet_domain_name)
- printf("Domain name is %s\n", rtems_bsdnet_domain_name);
- break;
- default:
- printf("Ignoring field type %d\n",code);
- }
- j+=len;
- }
+ processOptions (&reply.vend[4], sizeof(reply.vend) - 4);
+ }
+ if (dhcpOptionOverload & 1) {
+ processOptions (reply.file, sizeof reply.file);
+ }
+ else {
+ if (reply.file[0])
+ rtems_bsdnet_bootp_boot_file_name = strdup (reply.file);
+ }
+ if (dhcpOptionOverload & 2) {
+ processOptions (reply.sname, sizeof reply.sname);
}
+ else {
+ if (reply.sname[0])
+ rtems_bsdnet_bootp_server_name = strdup (reply.sname);
+ }
+ if (rtems_bsdnet_bootp_server_name)
+ printf ("Server name is %s\n", rtems_bsdnet_bootp_server_name);
+ if (rtems_bsdnet_bootp_boot_file_name)
+ printf ("Boot file is %s\n", rtems_bsdnet_bootp_boot_file_name);
- if (!gotnetmask) {
+ /*
+ * Use defaults if values were not supplied by BOOTP/DHCP options
+ */
+ if (!dhcp_gotnetmask) {
if (IN_CLASSA(ntohl(myaddr.sin_addr.s_addr)))
- netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
else if (IN_CLASSB(ntohl(myaddr.sin_addr.s_addr)))
- netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
else
- netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
- }
- if (!gotgw) {
- /* Use proxyarp */
- gw.sin_addr.s_addr = myaddr.sin_addr.s_addr;
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
}
+ printip ("Subnet mask", dhcp_netmask.sin_addr);
+ if (!dhcp_gotserver)
+ rtems_bsdnet_bootp_server_address = reply.siaddr;
+ printip ("Server ip address" ,rtems_bsdnet_bootp_server_address);
+ if (!dhcp_gotgw)
+ dhcp_gw.sin_addr = reply.giaddr;
+ printip ("Gateway ip address", dhcp_gw.sin_addr);
+ if (!dhcp_gotlogserver)
+ rtems_bsdnet_log_host_address = rtems_bsdnet_bootp_server_address;
+ printip ("Log server ip address", rtems_bsdnet_log_host_address);
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
+ /*
+ * Configure the interface with the new settings
+ */
error = bootpc_adjust_interface(&ireq,so,
- &myaddr,&netmask,&gw,procp);
-
+ &myaddr,&dhcp_netmask,&dhcp_gw,procp);
soclose(so);
-
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
-
-
-#if 0
- myaddr.sin_addr.s_addr | ~ netmask.sin_addr.s_addr;
-#endif
-
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
- return;
}
diff --git a/c/src/exec/libnetworking/rtems/rtems_bsdnet.h b/c/src/exec/libnetworking/rtems/rtems_bsdnet.h
index 73ad92fa30..6447749f80 100644
--- a/c/src/exec/libnetworking/rtems/rtems_bsdnet.h
+++ b/c/src/exec/libnetworking/rtems/rtems_bsdnet.h
@@ -11,6 +11,7 @@
* Values that may be obtained by BOOTP
*/
extern struct in_addr rtems_bsdnet_bootp_server_address;
+extern char *rtems_bsdnet_bootp_server_name;
extern char *rtems_bsdnet_bootp_boot_file_name;
/*
diff --git a/c/src/exec/libnetworking/rtems/rtems_glue.c b/c/src/exec/libnetworking/rtems/rtems_glue.c
index dd80a13d08..aea0a548b2 100644
--- a/c/src/exec/libnetworking/rtems/rtems_glue.c
+++ b/c/src/exec/libnetworking/rtems/rtems_glue.c
@@ -85,6 +85,7 @@ int nfs_diskless_valid;
struct in_addr rtems_bsdnet_log_host_address;
struct in_addr rtems_bsdnet_bootp_server_address;
char *rtems_bsdnet_bootp_boot_file_name;
+char *rtems_bsdnet_bootp_server_name;
char *rtems_bsdnet_domain_name;
struct in_addr rtems_bsdnet_nameserver[sizeof rtems_bsdnet_config.name_server /
sizeof rtems_bsdnet_config.name_server[0]];
diff --git a/c/src/exec/libnetworking/sys/socketvar.h b/c/src/exec/libnetworking/sys/socketvar.h
index 257fee012b..0eae3d4aa5 100644
--- a/c/src/exec/libnetworking/sys/socketvar.h
+++ b/c/src/exec/libnetworking/sys/socketvar.h
@@ -72,7 +72,7 @@ struct socket {
short so_incqlen; /* number of unaccepted incomplete
connections */
short so_qlimit; /* max number queued connections */
- short so_timeo; /* connection timeout */
+ u_long so_timeo; /* connection timeout */
u_short so_error; /* error affecting connection */
pid_t so_pgid; /* pgid for signals */
u_long so_oobmark; /* chars to oob mark */
@@ -88,7 +88,7 @@ struct socket {
struct mbuf *sb_mb; /* the mbuf chain */
struct selinfo sb_sel; /* process selecting read/write */
short sb_flags; /* flags, see below */
- short sb_timeo; /* timeout for read/write */
+ u_long sb_timeo; /* timeout for read/write */
} so_rcv, so_snd;
#define SB_MAX (256*1024) /* default for max chars in sockbuf */
#define SB_LOCK 0x01 /* lock on data queue */
diff --git a/c/src/exec/posix/src/psignal.c b/c/src/exec/posix/src/psignal.c
index 4037209009..5db634a924 100644
--- a/c/src/exec/posix/src/psignal.c
+++ b/c/src/exec/posix/src/psignal.c
@@ -207,7 +207,7 @@ void _POSIX_signals_Clear_process_signals(
_ISR_Disable( level );
_POSIX_signals_Pending &= ~mask;
- if ( !_POSIX_signals_Pending )
+ if ( !_POSIX_signals_Pending && _Thread_Do_post_task_switch_extension )
_Thread_Do_post_task_switch_extension--;
_ISR_Enable( level );
}
diff --git a/c/src/exec/score/headers/thread.h b/c/src/exec/score/headers/thread.h
index da6fa76bd0..7fc3361c39 100644
--- a/c/src/exec/score/headers/thread.h
+++ b/c/src/exec/score/headers/thread.h
@@ -177,6 +177,7 @@ struct Thread_Control_struct {
boolean do_post_task_switch_extension;
boolean is_preemptible;
+ void *rtems_ada_self;
unsigned32 cpu_time_budget;
Thread_CPU_budget_algorithms budget_algorithm;
Thread_CPU_budget_algorithm_callout budget_callout;
@@ -192,6 +193,12 @@ struct Thread_Control_struct {
};
/*
+ * Self for the GNU Ada Run-Time
+ */
+
+SCORE_EXTERN void *rtems_ada_self;
+
+/*
* The following defines the information control block used to
* manage this class of objects.
*/
diff --git a/c/src/exec/score/include/rtems/score/thread.h b/c/src/exec/score/include/rtems/score/thread.h
index da6fa76bd0..7fc3361c39 100644
--- a/c/src/exec/score/include/rtems/score/thread.h
+++ b/c/src/exec/score/include/rtems/score/thread.h
@@ -177,6 +177,7 @@ struct Thread_Control_struct {
boolean do_post_task_switch_extension;
boolean is_preemptible;
+ void *rtems_ada_self;
unsigned32 cpu_time_budget;
Thread_CPU_budget_algorithms budget_algorithm;
Thread_CPU_budget_algorithm_callout budget_callout;
@@ -192,6 +193,12 @@ struct Thread_Control_struct {
};
/*
+ * Self for the GNU Ada Run-Time
+ */
+
+SCORE_EXTERN void *rtems_ada_self;
+
+/*
* The following defines the information control block used to
* manage this class of objects.
*/
diff --git a/c/src/exec/score/src/thread.c b/c/src/exec/score/src/thread.c
index 4e44ac6f75..292e042d57 100644
--- a/c/src/exec/score/src/thread.c
+++ b/c/src/exec/score/src/thread.c
@@ -271,6 +271,8 @@ void _Thread_Dispatch( void )
_Thread_Dispatch_disable_level = 1;
_Context_Switch_necessary = FALSE;
_Thread_Executing = heir;
+ executing->rtems_ada_self = rtems_ada_self;
+ rtems_ada_self = heir->rtems_ada_self;
_ISR_Enable( level );
heir->ticks_executed++;
@@ -438,6 +440,12 @@ boolean _Thread_Initialize(
void *extensions_area;
/*
+ * Initialize the Ada self pointer
+ */
+
+ the_thread->rtems_ada_self = NULL;
+
+ /*
* Allocate and Initialize the stack for this thread.
*/
diff --git a/c/src/lib/libbsp/powerpc/psim/startup/device-tree b/c/src/lib/libbsp/powerpc/psim/startup/device-tree
index 29873839e5..bd2a2a56ef 100644
--- a/c/src/lib/libbsp/powerpc/psim/startup/device-tree
+++ b/c/src/lib/libbsp/powerpc/psim/startup/device-tree
@@ -1,3 +1,4 @@
#/openprom/init/register/pc 0
#/openprom/options/smp 2
-/openprom/options/oea-memory-size 4194304
+#/openprom/options/oea-memory-size 4194304
+/openprom/options/oea-memory-size 8388608
diff --git a/c/src/lib/libbsp/powerpc/psim/startup/linkcmds b/c/src/lib/libbsp/powerpc/psim/startup/linkcmds
index 61b61bf5c0..fd691586fb 100644
--- a/c/src/lib/libbsp/powerpc/psim/startup/linkcmds
+++ b/c/src/lib/libbsp/powerpc/psim/startup/linkcmds
@@ -19,9 +19,10 @@ ENTRY(_start)
/* Do we need any of these for elf?
__DYNAMIC = 0; */
PROVIDE (PSIM_INSTRUCTIONS_PER_MICROSECOND = 100);
+PROVIDE (CPU_PPC_CLICKS_PER_MS = 16667);
MEMORY
{
- RAM : ORIGIN = 0, LENGTH = 4M
+ RAM : ORIGIN = 0, LENGTH = 8M
EPROM : ORIGIN = 0xFFF00000, LENGTH = 0x20000
}
@@ -67,7 +68,7 @@ SECTIONS
.fini : { *(.fini) } >RAM
.rodata : { *(.rodata) *(.gnu.linkonce.r*) } >RAM
.rodata1 : { *(.rodata1) } >RAM
- _etext = .;
+ PROVIDE (_etext = .);
PROVIDE (etext = .);
PROVIDE (__SDATA2_START__ = .);
.sdata2 : { *(.sdata2) } >RAM
@@ -139,7 +140,7 @@ SECTIONS
_edata = .;
PROVIDE (edata = .);
- PROVIDE (RAM_END = 0x3f0000);
+ PROVIDE (RAM_END = 0x7f0000);
.sbss :
{
PROVIDE (__sbss_start = .);
diff --git a/c/src/lib/libnetworking/kern/uipc_socket.c b/c/src/lib/libnetworking/kern/uipc_socket.c
index 895d1c7d45..04489f4017 100644
--- a/c/src/lib/libnetworking/kern/uipc_socket.c
+++ b/c/src/lib/libnetworking/kern/uipc_socket.c
@@ -49,6 +49,7 @@
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
#include <sys/sysctl.h>
+#include <limits.h>
static int somaxconn = SOMAXCONN;
SYSCTL_INT(_kern, KERN_SOMAXCONN, somaxconn, CTLFLAG_RW, &somaxconn, 0, "");
@@ -948,14 +949,14 @@ sosetopt(so, level, optname, m0)
case SO_RCVTIMEO:
{
struct timeval *tv;
- short val;
+ unsigned long val;
if (m == NULL || m->m_len < sizeof (*tv)) {
error = EINVAL;
goto bad;
}
tv = mtod(m, struct timeval *);
- if (tv->tv_sec > SHRT_MAX / hz - hz) {
+ if (tv->tv_sec >= (ULONG_MAX - hz) / hz) {
error = EDOM;
goto bad;
}
@@ -1065,7 +1066,7 @@ sogetopt(so, level, optname, mp)
case SO_SNDTIMEO:
case SO_RCVTIMEO:
{
- int val = (optname == SO_SNDTIMEO ?
+ unsigned long val = (optname == SO_SNDTIMEO ?
so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
m->m_len = sizeof(struct timeval);
diff --git a/c/src/lib/libnetworking/nfs/bootp_subr.c b/c/src/lib/libnetworking/nfs/bootp_subr.c
index cb7d3d3407..f6831eed71 100644
--- a/c/src/lib/libnetworking/nfs/bootp_subr.c
+++ b/c/src/lib/libnetworking/nfs/bootp_subr.c
@@ -682,6 +682,162 @@ static void printip(char *prefix,struct in_addr addr)
ip >> 24, (ip >> 16) & 255 ,(ip >> 8) & 255 ,ip & 255 );
}
+static int dhcpOptionOverload = 0;
+static char dhcp_gotgw = 0;
+static char dhcp_gotnetmask = 0;
+static char dhcp_gotserver = 0;
+static char dhcp_gotlogserver = 0;
+static struct sockaddr_in dhcp_netmask;
+static struct sockaddr_in dhcp_gw;
+
+static void
+processOptions (unsigned char *optbuf, int optbufSize)
+{
+ int j = 0;
+ int len;
+ int code, ncode;
+ char *p;
+
+ ncode = optbuf[0];
+ while (j < optbufSize) {
+ code = optbuf[j] = ncode;
+ if (code == 255)
+ return;
+ if (code == 0) {
+ j++;
+ continue;
+ }
+ len = optbuf[j+1];
+ j += 2;
+ if ((len + j) >= optbufSize) {
+ printf ("Truncated field for code %d", code);
+ return;
+ }
+ ncode = optbuf[j+len];
+ optbuf[j+len] = '\0';
+ p = &optbuf[j];
+ j += len;
+
+ /*
+ * Process the option
+ */
+ 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, unused */
+ 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;
+ }
+ break;
+
+ case 6:
+ /* Domain Name servers */
+ if (len % 4)
+ panic ("bootpc: DNS Len is %d", len);
+ {
+ int dlen = 0;
+ while ((dlen < len) &&
+ (rtems_bsdnet_nameserver_count < sizeof rtems_bsdnet_config.name_server /
+ sizeof rtems_bsdnet_config.name_server[0])) {
+ bcopy (p+dlen,
+ &rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count],
+ 4);
+ printip("Domain Name Server",
+ rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count]);
+ rtems_bsdnet_nameserver_count++;
+ dlen += 4;
+ }
+ }
+ break;
+
+ case 12:
+ /* Host name */
+ if (len>=MAXHOSTNAMELEN)
+ panic ("bootpc: hostname >=%d bytes", MAXHOSTNAMELEN);
+ if (sethostname (p, len) < 0)
+ panic("Can't set host name");
+ printf("Hostname is %s\n", 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;
+ }
+ break;
+
+ case 15:
+ /* Domain name */
+ if (p[0]) {
+ rtems_bsdnet_domain_name = strdup (p);
+ printf("Domain name is %s\n", rtems_bsdnet_domain_name);
+ }
+ break;
+
+ case 16: /* Swap server IP address. unused */
+ break;
+
+ case 52:
+ /* DHCP option override */
+ if (len != 1)
+ panic ("bootpc: DHCP option overload len is %d", len);
+ dhcpOptionOverload = p[0];
+ break;
+
+ case 128: /* Site-specific option for DHCP servers that
+ * a) don't supply tag 54
+ * and
+ * b) don't supply the server address in siaddr
+ * For example, on Solaris 2.6 in.dhcpd, include in the dhcptab:
+ * Bootsrv s Site,128,IP,1,1
+ * and use that symbol in the macro that defines the client:
+ * Bootsrv=<tftp-server-ip-address>
+ */
+ 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;
+
+ case 66:
+ /* DHCP server name option */
+ if (p[0])
+ rtems_bsdnet_bootp_server_name = strdup (p);
+ break;
+
+ case 67:
+ /* DHCP bootfile option */
+ if (p[0])
+ rtems_bsdnet_bootp_boot_file_name = strdup (p);
+ break;
+
+ default:
+ printf ("Ignoring BOOTP/DHCP option code %d\n", code);
+ break;
+ }
+ }
+}
+
+#define EALEN 6
+
void
bootpc_init(void)
{
@@ -692,27 +848,9 @@ bootpc_init(void)
struct ifreq ireq;
struct ifnet *ifp;
struct socket *so;
- int error;
- int code,ncode,len;
int j;
- char *p;
- unsigned int ip;
-
+ int error;
struct sockaddr_in myaddr;
- struct sockaddr_in netmask;
- struct sockaddr_in gw;
- int gotgw=0;
- int gotnetmask=0;
-#if !defined(__rtems__)
- int gotrootpath=0;
- int gotswappath=0;
-#endif
- char lookup_path[24];
-
-#define EALEN 6
-#if !defined(__rtems__)
- unsigned char ea[EALEN];
-#endif
struct ifaddr *ifa;
struct sockaddr_dl *sdl = NULL;
char *delim;
@@ -725,12 +863,6 @@ bootpc_init(void)
return;
/*
- * Bump time if 0.
- if (!time.tv_sec)
- time.tv_sec++;
- */
-
- /*
* Find a network interface.
*/
for (ifp = ifnet; ifp != 0; ifp = ifp->if_next)
@@ -803,166 +935,77 @@ bootpc_init(void)
if (error)
panic("BOOTP call failed -- error %d", error);
+ /*
+ * Initialize network address structures
+ */
bzero(&myaddr,sizeof(myaddr));
- bzero(&netmask,sizeof(netmask));
- bzero(&gw,sizeof(gw));
-
+ bzero(&dhcp_netmask,sizeof(dhcp_netmask));
+ bzero(&dhcp_gw,sizeof(dhcp_gw));
myaddr.sin_len = sizeof(myaddr);
myaddr.sin_family = AF_INET;
+ dhcp_netmask.sin_len = sizeof(dhcp_netmask);
+ dhcp_netmask.sin_family = AF_INET;
+ dhcp_gw.sin_len = sizeof(dhcp_gw);
+ dhcp_gw.sin_family= AF_INET;
- netmask.sin_len = sizeof(netmask);
- netmask.sin_family = AF_INET;
-
- gw.sin_len = sizeof(gw);
- gw.sin_family= AF_INET;
-
- rtems_bsdnet_bootp_server_address = reply.siaddr;
- rtems_bsdnet_log_host_address = reply.siaddr;
-
+ /*
+ * Set our address
+ */
myaddr.sin_addr = reply.yiaddr;
-
- ip = ntohl(myaddr.sin_addr.s_addr);
- sprintf(lookup_path,"swap.%d.%d.%d.%d",
- ip >> 24, (ip >> 16) & 255 ,(ip >> 8) & 255 ,ip & 255 );
-
printip("My ip address",myaddr.sin_addr);
- printip("Server ip address",reply.siaddr);
-
- gw.sin_addr = reply.giaddr;
- printip("Gateway ip address",reply.giaddr);
-
- if (reply.sname[0])
- printf("Server name is %s\n",reply.sname);
- if (reply.file[0])
- printf("boot file is %s\n",reply.file);
- rtems_bsdnet_bootp_boot_file_name = strdup (reply.file);
+ /*
+ * Process BOOTP/DHCP options
+ */
if (reply.vend[0]==99 && reply.vend[1]==130 &&
reply.vend[2]==83 && reply.vend[3]==99) {
- j=4;
- ncode = reply.vend[j];
- while (j<sizeof(reply.vend)) {
- code = reply.vend[j] = ncode;
- if (code==255)
- break;
- if (code==0) {
- j++;
- continue;
- }
- len = reply.vend[j+1];
- j+=2;
- if (len+j>=sizeof(reply.vend)) {
- printf("Truncated field");
- break;
- }
- ncode = reply.vend[j+len];
- reply.vend[j+len]='\0';
- p = &reply.vend[j];
- switch (code) {
- case 1:
- if (len!=4)
- panic("bootpc: subnet mask len is %d",len);
- bcopy(&reply.vend[j],&netmask.sin_addr,4);
- gotnetmask=1;
- printip("Subnet mask",netmask.sin_addr);
- break;
- case 6:
- /* Domain Name servers */
- if (len % 4)
- panic("bootpc: DNS Len is %d",len);
- {
- int dlen = 0;
- while ((dlen < len) &&
- (rtems_bsdnet_nameserver_count < sizeof rtems_bsdnet_config.name_server /
- sizeof rtems_bsdnet_config.name_server[0])) {
- bcopy(&reply.vend[j+dlen],
- &rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count],
- 4);
- printip("Domain Name Server",
- rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count]);
- rtems_bsdnet_nameserver_count++;
- dlen += 4;
- }
- }
- break;
- case 16: /* Swap server IP address. unused */
- case 2:
- /* Time offset */
- break;
- case 3:
- /* Routers */
- if (len % 4)
- panic("bootpc: Router Len is %d",len);
- if (len > 0) {
- bcopy(&reply.vend[j],&gw.sin_addr,4);
- printip("Router",gw.sin_addr);
- gotgw=1;
- }
- break;
- case 7:
- /* Log servers */
- if (len % 4)
- panic("bootpc: Log server len is %d",len);
- if (len > 0) {
- bcopy(&reply.vend[j],&rtems_bsdnet_log_host_address,4);
- printip("Log server",rtems_bsdnet_log_host_address);
- }
- break;
- case 12:
- if (len>=MAXHOSTNAMELEN)
- panic("bootpc: hostname >=%d bytes",MAXHOSTNAMELEN);
- if (sethostname (&reply.vend[j], len) < 0)
- panic("Can't set host name");
- printf("Hostname is %.*s\n",len,&reply.vend[j]);
- break;
- case 15:
- /* Domain name */
- rtems_bsdnet_domain_name = strdup (&reply.vend[j]);
- if (rtems_bsdnet_domain_name)
- printf("Domain name is %s\n", rtems_bsdnet_domain_name);
- break;
- default:
- printf("Ignoring field type %d\n",code);
- }
- j+=len;
- }
+ processOptions (&reply.vend[4], sizeof(reply.vend) - 4);
+ }
+ if (dhcpOptionOverload & 1) {
+ processOptions (reply.file, sizeof reply.file);
+ }
+ else {
+ if (reply.file[0])
+ rtems_bsdnet_bootp_boot_file_name = strdup (reply.file);
+ }
+ if (dhcpOptionOverload & 2) {
+ processOptions (reply.sname, sizeof reply.sname);
}
+ else {
+ if (reply.sname[0])
+ rtems_bsdnet_bootp_server_name = strdup (reply.sname);
+ }
+ if (rtems_bsdnet_bootp_server_name)
+ printf ("Server name is %s\n", rtems_bsdnet_bootp_server_name);
+ if (rtems_bsdnet_bootp_boot_file_name)
+ printf ("Boot file is %s\n", rtems_bsdnet_bootp_boot_file_name);
- if (!gotnetmask) {
+ /*
+ * Use defaults if values were not supplied by BOOTP/DHCP options
+ */
+ if (!dhcp_gotnetmask) {
if (IN_CLASSA(ntohl(myaddr.sin_addr.s_addr)))
- netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
else if (IN_CLASSB(ntohl(myaddr.sin_addr.s_addr)))
- netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
else
- netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
- }
- if (!gotgw) {
- /* Use proxyarp */
- gw.sin_addr.s_addr = myaddr.sin_addr.s_addr;
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
}
+ printip ("Subnet mask", dhcp_netmask.sin_addr);
+ if (!dhcp_gotserver)
+ rtems_bsdnet_bootp_server_address = reply.siaddr;
+ printip ("Server ip address" ,rtems_bsdnet_bootp_server_address);
+ if (!dhcp_gotgw)
+ dhcp_gw.sin_addr = reply.giaddr;
+ printip ("Gateway ip address", dhcp_gw.sin_addr);
+ if (!dhcp_gotlogserver)
+ rtems_bsdnet_log_host_address = rtems_bsdnet_bootp_server_address;
+ printip ("Log server ip address", rtems_bsdnet_log_host_address);
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
+ /*
+ * Configure the interface with the new settings
+ */
error = bootpc_adjust_interface(&ireq,so,
- &myaddr,&netmask,&gw,procp);
-
+ &myaddr,&dhcp_netmask,&dhcp_gw,procp);
soclose(so);
-
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
-
-
-#if 0
- myaddr.sin_addr.s_addr | ~ netmask.sin_addr.s_addr;
-#endif
-
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
- return;
}
diff --git a/c/src/lib/libnetworking/rtems/rtems_bsdnet.h b/c/src/lib/libnetworking/rtems/rtems_bsdnet.h
index 73ad92fa30..6447749f80 100644
--- a/c/src/lib/libnetworking/rtems/rtems_bsdnet.h
+++ b/c/src/lib/libnetworking/rtems/rtems_bsdnet.h
@@ -11,6 +11,7 @@
* Values that may be obtained by BOOTP
*/
extern struct in_addr rtems_bsdnet_bootp_server_address;
+extern char *rtems_bsdnet_bootp_server_name;
extern char *rtems_bsdnet_bootp_boot_file_name;
/*
diff --git a/c/src/lib/libnetworking/rtems/rtems_glue.c b/c/src/lib/libnetworking/rtems/rtems_glue.c
index dd80a13d08..aea0a548b2 100644
--- a/c/src/lib/libnetworking/rtems/rtems_glue.c
+++ b/c/src/lib/libnetworking/rtems/rtems_glue.c
@@ -85,6 +85,7 @@ int nfs_diskless_valid;
struct in_addr rtems_bsdnet_log_host_address;
struct in_addr rtems_bsdnet_bootp_server_address;
char *rtems_bsdnet_bootp_boot_file_name;
+char *rtems_bsdnet_bootp_server_name;
char *rtems_bsdnet_domain_name;
struct in_addr rtems_bsdnet_nameserver[sizeof rtems_bsdnet_config.name_server /
sizeof rtems_bsdnet_config.name_server[0]];
diff --git a/c/src/lib/libnetworking/sys/socketvar.h b/c/src/lib/libnetworking/sys/socketvar.h
index 257fee012b..0eae3d4aa5 100644
--- a/c/src/lib/libnetworking/sys/socketvar.h
+++ b/c/src/lib/libnetworking/sys/socketvar.h
@@ -72,7 +72,7 @@ struct socket {
short so_incqlen; /* number of unaccepted incomplete
connections */
short so_qlimit; /* max number queued connections */
- short so_timeo; /* connection timeout */
+ u_long so_timeo; /* connection timeout */
u_short so_error; /* error affecting connection */
pid_t so_pgid; /* pgid for signals */
u_long so_oobmark; /* chars to oob mark */
@@ -88,7 +88,7 @@ struct socket {
struct mbuf *sb_mb; /* the mbuf chain */
struct selinfo sb_sel; /* process selecting read/write */
short sb_flags; /* flags, see below */
- short sb_timeo; /* timeout for read/write */
+ u_long sb_timeo; /* timeout for read/write */
} so_rcv, so_snd;
#define SB_MAX (256*1024) /* default for max chars in sockbuf */
#define SB_LOCK 0x01 /* lock on data queue */
diff --git a/c/src/libnetworking/kern/uipc_socket.c b/c/src/libnetworking/kern/uipc_socket.c
index 895d1c7d45..04489f4017 100644
--- a/c/src/libnetworking/kern/uipc_socket.c
+++ b/c/src/libnetworking/kern/uipc_socket.c
@@ -49,6 +49,7 @@
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
#include <sys/sysctl.h>
+#include <limits.h>
static int somaxconn = SOMAXCONN;
SYSCTL_INT(_kern, KERN_SOMAXCONN, somaxconn, CTLFLAG_RW, &somaxconn, 0, "");
@@ -948,14 +949,14 @@ sosetopt(so, level, optname, m0)
case SO_RCVTIMEO:
{
struct timeval *tv;
- short val;
+ unsigned long val;
if (m == NULL || m->m_len < sizeof (*tv)) {
error = EINVAL;
goto bad;
}
tv = mtod(m, struct timeval *);
- if (tv->tv_sec > SHRT_MAX / hz - hz) {
+ if (tv->tv_sec >= (ULONG_MAX - hz) / hz) {
error = EDOM;
goto bad;
}
@@ -1065,7 +1066,7 @@ sogetopt(so, level, optname, mp)
case SO_SNDTIMEO:
case SO_RCVTIMEO:
{
- int val = (optname == SO_SNDTIMEO ?
+ unsigned long val = (optname == SO_SNDTIMEO ?
so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
m->m_len = sizeof(struct timeval);
diff --git a/c/src/libnetworking/nfs/bootp_subr.c b/c/src/libnetworking/nfs/bootp_subr.c
index cb7d3d3407..f6831eed71 100644
--- a/c/src/libnetworking/nfs/bootp_subr.c
+++ b/c/src/libnetworking/nfs/bootp_subr.c
@@ -682,6 +682,162 @@ static void printip(char *prefix,struct in_addr addr)
ip >> 24, (ip >> 16) & 255 ,(ip >> 8) & 255 ,ip & 255 );
}
+static int dhcpOptionOverload = 0;
+static char dhcp_gotgw = 0;
+static char dhcp_gotnetmask = 0;
+static char dhcp_gotserver = 0;
+static char dhcp_gotlogserver = 0;
+static struct sockaddr_in dhcp_netmask;
+static struct sockaddr_in dhcp_gw;
+
+static void
+processOptions (unsigned char *optbuf, int optbufSize)
+{
+ int j = 0;
+ int len;
+ int code, ncode;
+ char *p;
+
+ ncode = optbuf[0];
+ while (j < optbufSize) {
+ code = optbuf[j] = ncode;
+ if (code == 255)
+ return;
+ if (code == 0) {
+ j++;
+ continue;
+ }
+ len = optbuf[j+1];
+ j += 2;
+ if ((len + j) >= optbufSize) {
+ printf ("Truncated field for code %d", code);
+ return;
+ }
+ ncode = optbuf[j+len];
+ optbuf[j+len] = '\0';
+ p = &optbuf[j];
+ j += len;
+
+ /*
+ * Process the option
+ */
+ 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, unused */
+ 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;
+ }
+ break;
+
+ case 6:
+ /* Domain Name servers */
+ if (len % 4)
+ panic ("bootpc: DNS Len is %d", len);
+ {
+ int dlen = 0;
+ while ((dlen < len) &&
+ (rtems_bsdnet_nameserver_count < sizeof rtems_bsdnet_config.name_server /
+ sizeof rtems_bsdnet_config.name_server[0])) {
+ bcopy (p+dlen,
+ &rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count],
+ 4);
+ printip("Domain Name Server",
+ rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count]);
+ rtems_bsdnet_nameserver_count++;
+ dlen += 4;
+ }
+ }
+ break;
+
+ case 12:
+ /* Host name */
+ if (len>=MAXHOSTNAMELEN)
+ panic ("bootpc: hostname >=%d bytes", MAXHOSTNAMELEN);
+ if (sethostname (p, len) < 0)
+ panic("Can't set host name");
+ printf("Hostname is %s\n", 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;
+ }
+ break;
+
+ case 15:
+ /* Domain name */
+ if (p[0]) {
+ rtems_bsdnet_domain_name = strdup (p);
+ printf("Domain name is %s\n", rtems_bsdnet_domain_name);
+ }
+ break;
+
+ case 16: /* Swap server IP address. unused */
+ break;
+
+ case 52:
+ /* DHCP option override */
+ if (len != 1)
+ panic ("bootpc: DHCP option overload len is %d", len);
+ dhcpOptionOverload = p[0];
+ break;
+
+ case 128: /* Site-specific option for DHCP servers that
+ * a) don't supply tag 54
+ * and
+ * b) don't supply the server address in siaddr
+ * For example, on Solaris 2.6 in.dhcpd, include in the dhcptab:
+ * Bootsrv s Site,128,IP,1,1
+ * and use that symbol in the macro that defines the client:
+ * Bootsrv=<tftp-server-ip-address>
+ */
+ 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;
+
+ case 66:
+ /* DHCP server name option */
+ if (p[0])
+ rtems_bsdnet_bootp_server_name = strdup (p);
+ break;
+
+ case 67:
+ /* DHCP bootfile option */
+ if (p[0])
+ rtems_bsdnet_bootp_boot_file_name = strdup (p);
+ break;
+
+ default:
+ printf ("Ignoring BOOTP/DHCP option code %d\n", code);
+ break;
+ }
+ }
+}
+
+#define EALEN 6
+
void
bootpc_init(void)
{
@@ -692,27 +848,9 @@ bootpc_init(void)
struct ifreq ireq;
struct ifnet *ifp;
struct socket *so;
- int error;
- int code,ncode,len;
int j;
- char *p;
- unsigned int ip;
-
+ int error;
struct sockaddr_in myaddr;
- struct sockaddr_in netmask;
- struct sockaddr_in gw;
- int gotgw=0;
- int gotnetmask=0;
-#if !defined(__rtems__)
- int gotrootpath=0;
- int gotswappath=0;
-#endif
- char lookup_path[24];
-
-#define EALEN 6
-#if !defined(__rtems__)
- unsigned char ea[EALEN];
-#endif
struct ifaddr *ifa;
struct sockaddr_dl *sdl = NULL;
char *delim;
@@ -725,12 +863,6 @@ bootpc_init(void)
return;
/*
- * Bump time if 0.
- if (!time.tv_sec)
- time.tv_sec++;
- */
-
- /*
* Find a network interface.
*/
for (ifp = ifnet; ifp != 0; ifp = ifp->if_next)
@@ -803,166 +935,77 @@ bootpc_init(void)
if (error)
panic("BOOTP call failed -- error %d", error);
+ /*
+ * Initialize network address structures
+ */
bzero(&myaddr,sizeof(myaddr));
- bzero(&netmask,sizeof(netmask));
- bzero(&gw,sizeof(gw));
-
+ bzero(&dhcp_netmask,sizeof(dhcp_netmask));
+ bzero(&dhcp_gw,sizeof(dhcp_gw));
myaddr.sin_len = sizeof(myaddr);
myaddr.sin_family = AF_INET;
+ dhcp_netmask.sin_len = sizeof(dhcp_netmask);
+ dhcp_netmask.sin_family = AF_INET;
+ dhcp_gw.sin_len = sizeof(dhcp_gw);
+ dhcp_gw.sin_family= AF_INET;
- netmask.sin_len = sizeof(netmask);
- netmask.sin_family = AF_INET;
-
- gw.sin_len = sizeof(gw);
- gw.sin_family= AF_INET;
-
- rtems_bsdnet_bootp_server_address = reply.siaddr;
- rtems_bsdnet_log_host_address = reply.siaddr;
-
+ /*
+ * Set our address
+ */
myaddr.sin_addr = reply.yiaddr;
-
- ip = ntohl(myaddr.sin_addr.s_addr);
- sprintf(lookup_path,"swap.%d.%d.%d.%d",
- ip >> 24, (ip >> 16) & 255 ,(ip >> 8) & 255 ,ip & 255 );
-
printip("My ip address",myaddr.sin_addr);
- printip("Server ip address",reply.siaddr);
-
- gw.sin_addr = reply.giaddr;
- printip("Gateway ip address",reply.giaddr);
-
- if (reply.sname[0])
- printf("Server name is %s\n",reply.sname);
- if (reply.file[0])
- printf("boot file is %s\n",reply.file);
- rtems_bsdnet_bootp_boot_file_name = strdup (reply.file);
+ /*
+ * Process BOOTP/DHCP options
+ */
if (reply.vend[0]==99 && reply.vend[1]==130 &&
reply.vend[2]==83 && reply.vend[3]==99) {
- j=4;
- ncode = reply.vend[j];
- while (j<sizeof(reply.vend)) {
- code = reply.vend[j] = ncode;
- if (code==255)
- break;
- if (code==0) {
- j++;
- continue;
- }
- len = reply.vend[j+1];
- j+=2;
- if (len+j>=sizeof(reply.vend)) {
- printf("Truncated field");
- break;
- }
- ncode = reply.vend[j+len];
- reply.vend[j+len]='\0';
- p = &reply.vend[j];
- switch (code) {
- case 1:
- if (len!=4)
- panic("bootpc: subnet mask len is %d",len);
- bcopy(&reply.vend[j],&netmask.sin_addr,4);
- gotnetmask=1;
- printip("Subnet mask",netmask.sin_addr);
- break;
- case 6:
- /* Domain Name servers */
- if (len % 4)
- panic("bootpc: DNS Len is %d",len);
- {
- int dlen = 0;
- while ((dlen < len) &&
- (rtems_bsdnet_nameserver_count < sizeof rtems_bsdnet_config.name_server /
- sizeof rtems_bsdnet_config.name_server[0])) {
- bcopy(&reply.vend[j+dlen],
- &rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count],
- 4);
- printip("Domain Name Server",
- rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count]);
- rtems_bsdnet_nameserver_count++;
- dlen += 4;
- }
- }
- break;
- case 16: /* Swap server IP address. unused */
- case 2:
- /* Time offset */
- break;
- case 3:
- /* Routers */
- if (len % 4)
- panic("bootpc: Router Len is %d",len);
- if (len > 0) {
- bcopy(&reply.vend[j],&gw.sin_addr,4);
- printip("Router",gw.sin_addr);
- gotgw=1;
- }
- break;
- case 7:
- /* Log servers */
- if (len % 4)
- panic("bootpc: Log server len is %d",len);
- if (len > 0) {
- bcopy(&reply.vend[j],&rtems_bsdnet_log_host_address,4);
- printip("Log server",rtems_bsdnet_log_host_address);
- }
- break;
- case 12:
- if (len>=MAXHOSTNAMELEN)
- panic("bootpc: hostname >=%d bytes",MAXHOSTNAMELEN);
- if (sethostname (&reply.vend[j], len) < 0)
- panic("Can't set host name");
- printf("Hostname is %.*s\n",len,&reply.vend[j]);
- break;
- case 15:
- /* Domain name */
- rtems_bsdnet_domain_name = strdup (&reply.vend[j]);
- if (rtems_bsdnet_domain_name)
- printf("Domain name is %s\n", rtems_bsdnet_domain_name);
- break;
- default:
- printf("Ignoring field type %d\n",code);
- }
- j+=len;
- }
+ processOptions (&reply.vend[4], sizeof(reply.vend) - 4);
+ }
+ if (dhcpOptionOverload & 1) {
+ processOptions (reply.file, sizeof reply.file);
+ }
+ else {
+ if (reply.file[0])
+ rtems_bsdnet_bootp_boot_file_name = strdup (reply.file);
+ }
+ if (dhcpOptionOverload & 2) {
+ processOptions (reply.sname, sizeof reply.sname);
}
+ else {
+ if (reply.sname[0])
+ rtems_bsdnet_bootp_server_name = strdup (reply.sname);
+ }
+ if (rtems_bsdnet_bootp_server_name)
+ printf ("Server name is %s\n", rtems_bsdnet_bootp_server_name);
+ if (rtems_bsdnet_bootp_boot_file_name)
+ printf ("Boot file is %s\n", rtems_bsdnet_bootp_boot_file_name);
- if (!gotnetmask) {
+ /*
+ * Use defaults if values were not supplied by BOOTP/DHCP options
+ */
+ if (!dhcp_gotnetmask) {
if (IN_CLASSA(ntohl(myaddr.sin_addr.s_addr)))
- netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
else if (IN_CLASSB(ntohl(myaddr.sin_addr.s_addr)))
- netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
else
- netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
- }
- if (!gotgw) {
- /* Use proxyarp */
- gw.sin_addr.s_addr = myaddr.sin_addr.s_addr;
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
}
+ printip ("Subnet mask", dhcp_netmask.sin_addr);
+ if (!dhcp_gotserver)
+ rtems_bsdnet_bootp_server_address = reply.siaddr;
+ printip ("Server ip address" ,rtems_bsdnet_bootp_server_address);
+ if (!dhcp_gotgw)
+ dhcp_gw.sin_addr = reply.giaddr;
+ printip ("Gateway ip address", dhcp_gw.sin_addr);
+ if (!dhcp_gotlogserver)
+ rtems_bsdnet_log_host_address = rtems_bsdnet_bootp_server_address;
+ printip ("Log server ip address", rtems_bsdnet_log_host_address);
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
+ /*
+ * Configure the interface with the new settings
+ */
error = bootpc_adjust_interface(&ireq,so,
- &myaddr,&netmask,&gw,procp);
-
+ &myaddr,&dhcp_netmask,&dhcp_gw,procp);
soclose(so);
-
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
-
-
-#if 0
- myaddr.sin_addr.s_addr | ~ netmask.sin_addr.s_addr;
-#endif
-
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
- return;
}
diff --git a/c/src/libnetworking/rtems/rtems_bsdnet.h b/c/src/libnetworking/rtems/rtems_bsdnet.h
index 73ad92fa30..6447749f80 100644
--- a/c/src/libnetworking/rtems/rtems_bsdnet.h
+++ b/c/src/libnetworking/rtems/rtems_bsdnet.h
@@ -11,6 +11,7 @@
* Values that may be obtained by BOOTP
*/
extern struct in_addr rtems_bsdnet_bootp_server_address;
+extern char *rtems_bsdnet_bootp_server_name;
extern char *rtems_bsdnet_bootp_boot_file_name;
/*
diff --git a/c/src/libnetworking/rtems/rtems_glue.c b/c/src/libnetworking/rtems/rtems_glue.c
index dd80a13d08..aea0a548b2 100644
--- a/c/src/libnetworking/rtems/rtems_glue.c
+++ b/c/src/libnetworking/rtems/rtems_glue.c
@@ -85,6 +85,7 @@ int nfs_diskless_valid;
struct in_addr rtems_bsdnet_log_host_address;
struct in_addr rtems_bsdnet_bootp_server_address;
char *rtems_bsdnet_bootp_boot_file_name;
+char *rtems_bsdnet_bootp_server_name;
char *rtems_bsdnet_domain_name;
struct in_addr rtems_bsdnet_nameserver[sizeof rtems_bsdnet_config.name_server /
sizeof rtems_bsdnet_config.name_server[0]];
diff --git a/c/src/libnetworking/sys/socketvar.h b/c/src/libnetworking/sys/socketvar.h
index 257fee012b..0eae3d4aa5 100644
--- a/c/src/libnetworking/sys/socketvar.h
+++ b/c/src/libnetworking/sys/socketvar.h
@@ -72,7 +72,7 @@ struct socket {
short so_incqlen; /* number of unaccepted incomplete
connections */
short so_qlimit; /* max number queued connections */
- short so_timeo; /* connection timeout */
+ u_long so_timeo; /* connection timeout */
u_short so_error; /* error affecting connection */
pid_t so_pgid; /* pgid for signals */
u_long so_oobmark; /* chars to oob mark */
@@ -88,7 +88,7 @@ struct socket {
struct mbuf *sb_mb; /* the mbuf chain */
struct selinfo sb_sel; /* process selecting read/write */
short sb_flags; /* flags, see below */
- short sb_timeo; /* timeout for read/write */
+ u_long sb_timeo; /* timeout for read/write */
} so_rcv, so_snd;
#define SB_MAX (256*1024) /* default for max chars in sockbuf */
#define SB_LOCK 0x01 /* lock on data queue */
diff --git a/cpukit/libnetworking/kern/uipc_socket.c b/cpukit/libnetworking/kern/uipc_socket.c
index 895d1c7d45..04489f4017 100644
--- a/cpukit/libnetworking/kern/uipc_socket.c
+++ b/cpukit/libnetworking/kern/uipc_socket.c
@@ -49,6 +49,7 @@
#include <sys/resourcevar.h>
#include <sys/signalvar.h>
#include <sys/sysctl.h>
+#include <limits.h>
static int somaxconn = SOMAXCONN;
SYSCTL_INT(_kern, KERN_SOMAXCONN, somaxconn, CTLFLAG_RW, &somaxconn, 0, "");
@@ -948,14 +949,14 @@ sosetopt(so, level, optname, m0)
case SO_RCVTIMEO:
{
struct timeval *tv;
- short val;
+ unsigned long val;
if (m == NULL || m->m_len < sizeof (*tv)) {
error = EINVAL;
goto bad;
}
tv = mtod(m, struct timeval *);
- if (tv->tv_sec > SHRT_MAX / hz - hz) {
+ if (tv->tv_sec >= (ULONG_MAX - hz) / hz) {
error = EDOM;
goto bad;
}
@@ -1065,7 +1066,7 @@ sogetopt(so, level, optname, mp)
case SO_SNDTIMEO:
case SO_RCVTIMEO:
{
- int val = (optname == SO_SNDTIMEO ?
+ unsigned long val = (optname == SO_SNDTIMEO ?
so->so_snd.sb_timeo : so->so_rcv.sb_timeo);
m->m_len = sizeof(struct timeval);
diff --git a/cpukit/libnetworking/nfs/bootp_subr.c b/cpukit/libnetworking/nfs/bootp_subr.c
index cb7d3d3407..f6831eed71 100644
--- a/cpukit/libnetworking/nfs/bootp_subr.c
+++ b/cpukit/libnetworking/nfs/bootp_subr.c
@@ -682,6 +682,162 @@ static void printip(char *prefix,struct in_addr addr)
ip >> 24, (ip >> 16) & 255 ,(ip >> 8) & 255 ,ip & 255 );
}
+static int dhcpOptionOverload = 0;
+static char dhcp_gotgw = 0;
+static char dhcp_gotnetmask = 0;
+static char dhcp_gotserver = 0;
+static char dhcp_gotlogserver = 0;
+static struct sockaddr_in dhcp_netmask;
+static struct sockaddr_in dhcp_gw;
+
+static void
+processOptions (unsigned char *optbuf, int optbufSize)
+{
+ int j = 0;
+ int len;
+ int code, ncode;
+ char *p;
+
+ ncode = optbuf[0];
+ while (j < optbufSize) {
+ code = optbuf[j] = ncode;
+ if (code == 255)
+ return;
+ if (code == 0) {
+ j++;
+ continue;
+ }
+ len = optbuf[j+1];
+ j += 2;
+ if ((len + j) >= optbufSize) {
+ printf ("Truncated field for code %d", code);
+ return;
+ }
+ ncode = optbuf[j+len];
+ optbuf[j+len] = '\0';
+ p = &optbuf[j];
+ j += len;
+
+ /*
+ * Process the option
+ */
+ 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, unused */
+ 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;
+ }
+ break;
+
+ case 6:
+ /* Domain Name servers */
+ if (len % 4)
+ panic ("bootpc: DNS Len is %d", len);
+ {
+ int dlen = 0;
+ while ((dlen < len) &&
+ (rtems_bsdnet_nameserver_count < sizeof rtems_bsdnet_config.name_server /
+ sizeof rtems_bsdnet_config.name_server[0])) {
+ bcopy (p+dlen,
+ &rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count],
+ 4);
+ printip("Domain Name Server",
+ rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count]);
+ rtems_bsdnet_nameserver_count++;
+ dlen += 4;
+ }
+ }
+ break;
+
+ case 12:
+ /* Host name */
+ if (len>=MAXHOSTNAMELEN)
+ panic ("bootpc: hostname >=%d bytes", MAXHOSTNAMELEN);
+ if (sethostname (p, len) < 0)
+ panic("Can't set host name");
+ printf("Hostname is %s\n", 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;
+ }
+ break;
+
+ case 15:
+ /* Domain name */
+ if (p[0]) {
+ rtems_bsdnet_domain_name = strdup (p);
+ printf("Domain name is %s\n", rtems_bsdnet_domain_name);
+ }
+ break;
+
+ case 16: /* Swap server IP address. unused */
+ break;
+
+ case 52:
+ /* DHCP option override */
+ if (len != 1)
+ panic ("bootpc: DHCP option overload len is %d", len);
+ dhcpOptionOverload = p[0];
+ break;
+
+ case 128: /* Site-specific option for DHCP servers that
+ * a) don't supply tag 54
+ * and
+ * b) don't supply the server address in siaddr
+ * For example, on Solaris 2.6 in.dhcpd, include in the dhcptab:
+ * Bootsrv s Site,128,IP,1,1
+ * and use that symbol in the macro that defines the client:
+ * Bootsrv=<tftp-server-ip-address>
+ */
+ 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;
+
+ case 66:
+ /* DHCP server name option */
+ if (p[0])
+ rtems_bsdnet_bootp_server_name = strdup (p);
+ break;
+
+ case 67:
+ /* DHCP bootfile option */
+ if (p[0])
+ rtems_bsdnet_bootp_boot_file_name = strdup (p);
+ break;
+
+ default:
+ printf ("Ignoring BOOTP/DHCP option code %d\n", code);
+ break;
+ }
+ }
+}
+
+#define EALEN 6
+
void
bootpc_init(void)
{
@@ -692,27 +848,9 @@ bootpc_init(void)
struct ifreq ireq;
struct ifnet *ifp;
struct socket *so;
- int error;
- int code,ncode,len;
int j;
- char *p;
- unsigned int ip;
-
+ int error;
struct sockaddr_in myaddr;
- struct sockaddr_in netmask;
- struct sockaddr_in gw;
- int gotgw=0;
- int gotnetmask=0;
-#if !defined(__rtems__)
- int gotrootpath=0;
- int gotswappath=0;
-#endif
- char lookup_path[24];
-
-#define EALEN 6
-#if !defined(__rtems__)
- unsigned char ea[EALEN];
-#endif
struct ifaddr *ifa;
struct sockaddr_dl *sdl = NULL;
char *delim;
@@ -725,12 +863,6 @@ bootpc_init(void)
return;
/*
- * Bump time if 0.
- if (!time.tv_sec)
- time.tv_sec++;
- */
-
- /*
* Find a network interface.
*/
for (ifp = ifnet; ifp != 0; ifp = ifp->if_next)
@@ -803,166 +935,77 @@ bootpc_init(void)
if (error)
panic("BOOTP call failed -- error %d", error);
+ /*
+ * Initialize network address structures
+ */
bzero(&myaddr,sizeof(myaddr));
- bzero(&netmask,sizeof(netmask));
- bzero(&gw,sizeof(gw));
-
+ bzero(&dhcp_netmask,sizeof(dhcp_netmask));
+ bzero(&dhcp_gw,sizeof(dhcp_gw));
myaddr.sin_len = sizeof(myaddr);
myaddr.sin_family = AF_INET;
+ dhcp_netmask.sin_len = sizeof(dhcp_netmask);
+ dhcp_netmask.sin_family = AF_INET;
+ dhcp_gw.sin_len = sizeof(dhcp_gw);
+ dhcp_gw.sin_family= AF_INET;
- netmask.sin_len = sizeof(netmask);
- netmask.sin_family = AF_INET;
-
- gw.sin_len = sizeof(gw);
- gw.sin_family= AF_INET;
-
- rtems_bsdnet_bootp_server_address = reply.siaddr;
- rtems_bsdnet_log_host_address = reply.siaddr;
-
+ /*
+ * Set our address
+ */
myaddr.sin_addr = reply.yiaddr;
-
- ip = ntohl(myaddr.sin_addr.s_addr);
- sprintf(lookup_path,"swap.%d.%d.%d.%d",
- ip >> 24, (ip >> 16) & 255 ,(ip >> 8) & 255 ,ip & 255 );
-
printip("My ip address",myaddr.sin_addr);
- printip("Server ip address",reply.siaddr);
-
- gw.sin_addr = reply.giaddr;
- printip("Gateway ip address",reply.giaddr);
-
- if (reply.sname[0])
- printf("Server name is %s\n",reply.sname);
- if (reply.file[0])
- printf("boot file is %s\n",reply.file);
- rtems_bsdnet_bootp_boot_file_name = strdup (reply.file);
+ /*
+ * Process BOOTP/DHCP options
+ */
if (reply.vend[0]==99 && reply.vend[1]==130 &&
reply.vend[2]==83 && reply.vend[3]==99) {
- j=4;
- ncode = reply.vend[j];
- while (j<sizeof(reply.vend)) {
- code = reply.vend[j] = ncode;
- if (code==255)
- break;
- if (code==0) {
- j++;
- continue;
- }
- len = reply.vend[j+1];
- j+=2;
- if (len+j>=sizeof(reply.vend)) {
- printf("Truncated field");
- break;
- }
- ncode = reply.vend[j+len];
- reply.vend[j+len]='\0';
- p = &reply.vend[j];
- switch (code) {
- case 1:
- if (len!=4)
- panic("bootpc: subnet mask len is %d",len);
- bcopy(&reply.vend[j],&netmask.sin_addr,4);
- gotnetmask=1;
- printip("Subnet mask",netmask.sin_addr);
- break;
- case 6:
- /* Domain Name servers */
- if (len % 4)
- panic("bootpc: DNS Len is %d",len);
- {
- int dlen = 0;
- while ((dlen < len) &&
- (rtems_bsdnet_nameserver_count < sizeof rtems_bsdnet_config.name_server /
- sizeof rtems_bsdnet_config.name_server[0])) {
- bcopy(&reply.vend[j+dlen],
- &rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count],
- 4);
- printip("Domain Name Server",
- rtems_bsdnet_nameserver[rtems_bsdnet_nameserver_count]);
- rtems_bsdnet_nameserver_count++;
- dlen += 4;
- }
- }
- break;
- case 16: /* Swap server IP address. unused */
- case 2:
- /* Time offset */
- break;
- case 3:
- /* Routers */
- if (len % 4)
- panic("bootpc: Router Len is %d",len);
- if (len > 0) {
- bcopy(&reply.vend[j],&gw.sin_addr,4);
- printip("Router",gw.sin_addr);
- gotgw=1;
- }
- break;
- case 7:
- /* Log servers */
- if (len % 4)
- panic("bootpc: Log server len is %d",len);
- if (len > 0) {
- bcopy(&reply.vend[j],&rtems_bsdnet_log_host_address,4);
- printip("Log server",rtems_bsdnet_log_host_address);
- }
- break;
- case 12:
- if (len>=MAXHOSTNAMELEN)
- panic("bootpc: hostname >=%d bytes",MAXHOSTNAMELEN);
- if (sethostname (&reply.vend[j], len) < 0)
- panic("Can't set host name");
- printf("Hostname is %.*s\n",len,&reply.vend[j]);
- break;
- case 15:
- /* Domain name */
- rtems_bsdnet_domain_name = strdup (&reply.vend[j]);
- if (rtems_bsdnet_domain_name)
- printf("Domain name is %s\n", rtems_bsdnet_domain_name);
- break;
- default:
- printf("Ignoring field type %d\n",code);
- }
- j+=len;
- }
+ processOptions (&reply.vend[4], sizeof(reply.vend) - 4);
+ }
+ if (dhcpOptionOverload & 1) {
+ processOptions (reply.file, sizeof reply.file);
+ }
+ else {
+ if (reply.file[0])
+ rtems_bsdnet_bootp_boot_file_name = strdup (reply.file);
+ }
+ if (dhcpOptionOverload & 2) {
+ processOptions (reply.sname, sizeof reply.sname);
}
+ else {
+ if (reply.sname[0])
+ rtems_bsdnet_bootp_server_name = strdup (reply.sname);
+ }
+ if (rtems_bsdnet_bootp_server_name)
+ printf ("Server name is %s\n", rtems_bsdnet_bootp_server_name);
+ if (rtems_bsdnet_bootp_boot_file_name)
+ printf ("Boot file is %s\n", rtems_bsdnet_bootp_boot_file_name);
- if (!gotnetmask) {
+ /*
+ * Use defaults if values were not supplied by BOOTP/DHCP options
+ */
+ if (!dhcp_gotnetmask) {
if (IN_CLASSA(ntohl(myaddr.sin_addr.s_addr)))
- netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSA_NET);
else if (IN_CLASSB(ntohl(myaddr.sin_addr.s_addr)))
- netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSB_NET);
else
- netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
- }
- if (!gotgw) {
- /* Use proxyarp */
- gw.sin_addr.s_addr = myaddr.sin_addr.s_addr;
+ dhcp_netmask.sin_addr.s_addr = htonl(IN_CLASSC_NET);
}
+ printip ("Subnet mask", dhcp_netmask.sin_addr);
+ if (!dhcp_gotserver)
+ rtems_bsdnet_bootp_server_address = reply.siaddr;
+ printip ("Server ip address" ,rtems_bsdnet_bootp_server_address);
+ if (!dhcp_gotgw)
+ dhcp_gw.sin_addr = reply.giaddr;
+ printip ("Gateway ip address", dhcp_gw.sin_addr);
+ if (!dhcp_gotlogserver)
+ rtems_bsdnet_log_host_address = rtems_bsdnet_bootp_server_address;
+ printip ("Log server ip address", rtems_bsdnet_log_host_address);
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
+ /*
+ * Configure the interface with the new settings
+ */
error = bootpc_adjust_interface(&ireq,so,
- &myaddr,&netmask,&gw,procp);
-
+ &myaddr,&dhcp_netmask,&dhcp_gw,procp);
soclose(so);
-
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
-
-
-#if 0
- myaddr.sin_addr.s_addr | ~ netmask.sin_addr.s_addr;
-#endif
-
-#if 0
- bootpboot_p_iflist();
- bootpboot_p_rtlist();
-#endif
- return;
}
diff --git a/cpukit/libnetworking/rtems/rtems_bsdnet.h b/cpukit/libnetworking/rtems/rtems_bsdnet.h
index 73ad92fa30..6447749f80 100644
--- a/cpukit/libnetworking/rtems/rtems_bsdnet.h
+++ b/cpukit/libnetworking/rtems/rtems_bsdnet.h
@@ -11,6 +11,7 @@
* Values that may be obtained by BOOTP
*/
extern struct in_addr rtems_bsdnet_bootp_server_address;
+extern char *rtems_bsdnet_bootp_server_name;
extern char *rtems_bsdnet_bootp_boot_file_name;
/*
diff --git a/cpukit/libnetworking/rtems/rtems_glue.c b/cpukit/libnetworking/rtems/rtems_glue.c
index dd80a13d08..aea0a548b2 100644
--- a/cpukit/libnetworking/rtems/rtems_glue.c
+++ b/cpukit/libnetworking/rtems/rtems_glue.c
@@ -85,6 +85,7 @@ int nfs_diskless_valid;
struct in_addr rtems_bsdnet_log_host_address;
struct in_addr rtems_bsdnet_bootp_server_address;
char *rtems_bsdnet_bootp_boot_file_name;
+char *rtems_bsdnet_bootp_server_name;
char *rtems_bsdnet_domain_name;
struct in_addr rtems_bsdnet_nameserver[sizeof rtems_bsdnet_config.name_server /
sizeof rtems_bsdnet_config.name_server[0]];
diff --git a/cpukit/libnetworking/sys/socketvar.h b/cpukit/libnetworking/sys/socketvar.h
index 257fee012b..0eae3d4aa5 100644
--- a/cpukit/libnetworking/sys/socketvar.h
+++ b/cpukit/libnetworking/sys/socketvar.h
@@ -72,7 +72,7 @@ struct socket {
short so_incqlen; /* number of unaccepted incomplete
connections */
short so_qlimit; /* max number queued connections */
- short so_timeo; /* connection timeout */
+ u_long so_timeo; /* connection timeout */
u_short so_error; /* error affecting connection */
pid_t so_pgid; /* pgid for signals */
u_long so_oobmark; /* chars to oob mark */
@@ -88,7 +88,7 @@ struct socket {
struct mbuf *sb_mb; /* the mbuf chain */
struct selinfo sb_sel; /* process selecting read/write */
short sb_flags; /* flags, see below */
- short sb_timeo; /* timeout for read/write */
+ u_long sb_timeo; /* timeout for read/write */
} so_rcv, so_snd;
#define SB_MAX (256*1024) /* default for max chars in sockbuf */
#define SB_LOCK 0x01 /* lock on data queue */
diff --git a/cpukit/posix/src/psignal.c b/cpukit/posix/src/psignal.c
index 4037209009..5db634a924 100644
--- a/cpukit/posix/src/psignal.c
+++ b/cpukit/posix/src/psignal.c
@@ -207,7 +207,7 @@ void _POSIX_signals_Clear_process_signals(
_ISR_Disable( level );
_POSIX_signals_Pending &= ~mask;
- if ( !_POSIX_signals_Pending )
+ if ( !_POSIX_signals_Pending && _Thread_Do_post_task_switch_extension )
_Thread_Do_post_task_switch_extension--;
_ISR_Enable( level );
}
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index da6fa76bd0..7fc3361c39 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -177,6 +177,7 @@ struct Thread_Control_struct {
boolean do_post_task_switch_extension;
boolean is_preemptible;
+ void *rtems_ada_self;
unsigned32 cpu_time_budget;
Thread_CPU_budget_algorithms budget_algorithm;
Thread_CPU_budget_algorithm_callout budget_callout;
@@ -192,6 +193,12 @@ struct Thread_Control_struct {
};
/*
+ * Self for the GNU Ada Run-Time
+ */
+
+SCORE_EXTERN void *rtems_ada_self;
+
+/*
* The following defines the information control block used to
* manage this class of objects.
*/
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c
index 4e44ac6f75..292e042d57 100644
--- a/cpukit/score/src/thread.c
+++ b/cpukit/score/src/thread.c
@@ -271,6 +271,8 @@ void _Thread_Dispatch( void )
_Thread_Dispatch_disable_level = 1;
_Context_Switch_necessary = FALSE;
_Thread_Executing = heir;
+ executing->rtems_ada_self = rtems_ada_self;
+ rtems_ada_self = heir->rtems_ada_self;
_ISR_Enable( level );
heir->ticks_executed++;
@@ -438,6 +440,12 @@ boolean _Thread_Initialize(
void *extensions_area;
/*
+ * Initialize the Ada self pointer
+ */
+
+ the_thread->rtems_ada_self = NULL;
+
+ /*
* Allocate and Initialize the stack for this thread.
*/