diff options
Diffstat (limited to 'c')
21 files changed, 689 insertions, 527 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 */ |