diff --git a/Targets/Bonito3a780e/conf/Bonito.3a780e b/Targets/Bonito3a780e/conf/Bonito.3a780e index 62d3e609..f59b650d 100644 --- a/Targets/Bonito3a780e/conf/Bonito.3a780e +++ b/Targets/Bonito3a780e/conf/Bonito.3a780e @@ -46,6 +46,8 @@ select amd_780e ## VGA option ## option SERVER_3A option RS780E +option DHCP_3A780E +#option DHCP_3ASERVER option USE_780E_VGA option VGA_NO_ROM option VGA_BASE=0xbe000000 @@ -208,6 +210,7 @@ option HAVE_NB_SERIAL #option USE_ENVMAC #option LOOKLIKE_PC #select cmd_lwdhcp +option cmd_lwdhcp #select cmd_bootp option FOR_GXEMUL select fatfs diff --git a/Targets/Bonito3aserver/conf/Bonito.3aserver b/Targets/Bonito3aserver/conf/Bonito.3aserver index 598c49a7..00011225 100644 --- a/Targets/Bonito3aserver/conf/Bonito.3aserver +++ b/Targets/Bonito3aserver/conf/Bonito.3aserver @@ -37,6 +37,8 @@ select amd_780e ## VGA option ## option SERVER_3A option RS780E +#option DHCP_3A780E +option DHCP_3ASERVER option USE_780E_VGA option VGA_NO_ROM option VGA_BASE=0xbe000000 @@ -198,6 +200,7 @@ option HAVE_NB_SERIAL #option USE_ENVMAC #option LOOKLIKE_PC #select cmd_lwdhcp +option cmd_lwdhcp #select cmd_bootp option FOR_GXEMUL select fatfs diff --git a/pmon/cmds/lwdhcp/lwdhcp.c b/pmon/cmds/lwdhcp/lwdhcp.c index 59f28b6c..50ea502f 100644 --- a/pmon/cmds/lwdhcp/lwdhcp.c +++ b/pmon/cmds/lwdhcp/lwdhcp.c @@ -11,11 +11,12 @@ #include #ifdef PMON - #ifdef KERNEL - #undef KERNEL + #ifdef _KERNEL + #undef _KERNEL #include #include #include + #define _KERNEL #else #include #include @@ -41,6 +42,7 @@ #include "lwdhcp.h" #include "packet.h" #include "options.h" +#include "pmon/netio/bootparams.h" struct client_config_t client_config; int dhcp_request; @@ -60,11 +62,11 @@ static void terminate() longjmp(jmpb, 1); } -static void init() +static void init(char *ifname) { memset((void *)&client_config, 0, sizeof(struct client_config_t)); - strcpy(client_config.interface, "rtl0"); + strcpy(client_config.interface, ifname); pre_handler = signal(SIGINT, (sig_t)terminate); } @@ -104,7 +106,26 @@ int listen_socket() return sock; } +int del_dummy_addr(char *interface) +{ + int fd; + struct ifreq ifr; + + memset(&ifr, 0, sizeof(struct ifreq)); + if((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) + { + ifr.ifr_addr.sa_family = AF_INET; + strncpy(ifr.ifr_name, interface, IFNAMSIZ-1); + (void)ioctl(fd, SIOCDIFADDR, &ifr); + } + else{ + PERROR("socket failed!\n"); + return -1; + } + close(fd); + return 0; +} int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp) { int fd; @@ -120,14 +141,14 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp) if (addr) { - if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) + if (ioctl(fd, SIOCAIFADDR, &ifr) == 0) { our_ip = (struct sockaddr_in *) &ifr.ifr_addr; *addr = our_ip->sin_addr.s_addr; DbgPrint("%s (our ip) = %s\n", ifr.ifr_name, inet_ntoa(our_ip->sin_addr)); } else { - PERROR("SIOCGIFADDR failed, is the interface up and configured?\n"); + PERROR("SIOCAIFADDR failed, is the interface up and configured?\n"); close(fd); return -1; } @@ -178,8 +199,13 @@ int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp) return 0; } - -int lwdhcp(int argc, char* argv[]) +extern char dhcp_c_ip_string[15]; +extern char dhcp_s_ip_string[15]; +extern char dhcp_sname[65]; +extern char dhcp_file[129]; +extern char dhcp_host_name[309]; +extern char dhcp_root_path[309]; +int mylwdhcp(struct bootparams *bootp, char *ifname) { int xid; fd_set fs; @@ -190,6 +216,11 @@ int lwdhcp(int argc, char* argv[]) struct dhcp_packet* p; uint8_t* dhcp_message_type; struct timeval tv; + static struct in_addr nmask; + long tmo, loop; +#define JTLOOP 20 /* loop test*/ +#define MAXTMO 20 /* seconds*/ +#define MINTMO 20 /* seconds*/ if(getuid()) { @@ -198,7 +229,7 @@ int lwdhcp(int argc, char* argv[]) } DbgPrint("Light weight DHCP client starts...\n"); - init(); + init(ifname); if(setjmp(jmpb)) { @@ -221,9 +252,13 @@ int lwdhcp(int argc, char* argv[]) } //srand(time(NULL)); - //xid = rand(); + srand(client_config.arp[5]); + xid = rand(); + DbgPrint("xid = %d\n", xid); totimes = 3; - + tmo = MINTMO; + loop = 0; + tryagain: if(send_discover(xid) < 0) if(--totimes > 0) @@ -236,7 +271,7 @@ tryagain: FD_ZERO(&fs); FD_SET(fd, &fs); - tv.tv_sec = 3; + tv.tv_sec = tmo; tv.tv_usec = 0; //receiving DHCPOFFER while(1) @@ -245,18 +280,28 @@ tryagain: ret = select(fd + 1, &fs, NULL, NULL, &tv); if(ret == -1) + { PERROR("select error"); + dhcp_request = 0; + close(fd); + return 0; + } else if(ret == 0) { - if(--totimes > 0) - goto tryagain; - else + tmo <<= 1; + if(tmo >= MAXTMO) { - dhcp_request = 0; - DbgPrint("Fail to get IP from DHCP server, it seems that there is no DHCP server.\n"); - close(fd); - return 0; + if(loop++ < JTLOOP) + tmo = MINTMO; + else + { + dhcp_request = 0; + DbgPrint("Fail to get IP from DHCP server, it seems that there is no DHCP server.\n"); + close(fd); + return 0; + } } + goto tryagain; } size = sizeof(from); @@ -277,6 +322,7 @@ tryagain: continue; DbgPrint("DHCPOFFER received...\n"); + DbgPrint("IP %s obtained from the DHCP server.\n", inet_ntoa(p->yiaddr)); break; } @@ -292,18 +338,28 @@ tryagain: ret = select(fd + 1, &fs, NULL, NULL, &tv); if(ret == -1) + { PERROR("select error"); + dhcp_request = 0; + close(fd); + return 0; + } else if(ret == 0) { - if(--totimes > 0) - goto tryagain; - else - { - dhcp_request = 0; - DbgPrint("Fail to get IP from DHCP server, no ACK from DHCP server.\n"); - close(fd); - return 0; + tmo <<= 1; + if(tmo >= MAXTMO) + { + if(loop++ < JTLOOP) + tmo = MINTMO; + else + { + dhcp_request = 0; + DbgPrint("Fail to get IP from DHCP server, no ACK from DHCP server.\n"); + close(fd); + return 0; + } } + goto tryagain; } //get_raw_packet(buf, fd); @@ -312,6 +368,8 @@ tryagain: recvfrom(fd, buf, sizeof(struct dhcp_packet), 0, (struct sockaddr*)&from, &size); dhcp_request = 0; + + p = (struct dhcp_packet *)buf; if(p->xid != xid) continue; @@ -324,15 +382,91 @@ tryagain: DbgPrint("DHCPACK received...\n"); DbgPrint("IP %s obtained from the DHCP server.\n", inet_ntoa(p->yiaddr)); + sprintf(dhcp_c_ip_string, "%s", inet_ntoa(p->yiaddr)); + sprintf(dhcp_s_ip_string, "%s", inet_ntoa(p->siaddr)); + sprintf(dhcp_sname, "%s", p->sname); + sprintf(dhcp_file, "%s", p->file); + if(p->yiaddr.s_addr != 0 && (bootp->have & BOOT_ADDR) == 0) + { + u_long addr; + bootp->have |= BOOT_ADDR; + bootp->addr = p->yiaddr; + printf("our ip address is %s\n", inet_ntoa(bootp->addr)); + + addr = ntohl(bootp->addr.s_addr); + addr = (bootp->addr.s_addr); + if(IN_CLASSA(addr)) + nmask.s_addr = htonl(IN_CLASSA_NET); + else if(IN_CLASSB(addr)) + nmask.s_addr = htonl(IN_CLASSB_NET); + else + nmask.s_addr = htonl(IN_CLASSC_NET); + printf("'native netmask' is %s\n", inet_ntoa(nmask)); + } + if(p->siaddr.s_addr !=0 && (bootp->have & BOOT_BOOTIP) == 0) + { + bootp->have |= BOOT_BOOTIP; + bootp->bootip = p->siaddr; + } + if (p->file[0] != 0 && (bootp->have & BOOT_BOOTFILE) == 0) + { + bootp->have |= BOOT_BOOTFILE; + strncpy (bootp->bootfile, p->file, sizeof (p->file)); + } + if ((bootp->have & BOOT_MASK) != 0 && (nmask.s_addr & bootp->mask.s_addr) != nmask.s_addr) + { + printf("subnet mask (%s) bad\n", inet_ntoa(bootp->mask)); + bootp->have &= ~BOOT_MASK; + } + /* Get subnet (or natural net) mask */ + if ((bootp->have & BOOT_MASK) == 0) + bootp->mask = nmask; + dhcp_message_type = get_dhcp_option(p, DHCP_HOST_NAME); + if(dhcp_message_type) + { + int size = dhcp_message_type[-1]; + strncpy(dhcp_host_name, dhcp_message_type, size); + dhcp_host_name[size] = '\0'; + if (size < sizeof (bootp->hostname)&& (bootp->have & BOOT_HOSTNAME) == 0) + { + bootp->have |= BOOT_HOSTNAME; + strcpy(bootp->hostname, dhcp_host_name); + } + } + dhcp_message_type = get_dhcp_option(p, DHCP_ROOT_PATH); + if(dhcp_message_type) + { + strncpy(dhcp_root_path, dhcp_message_type, dhcp_message_type[-1]); + dhcp_root_path[dhcp_message_type[-1]] = '\0'; + } + + DbgPrint("dhcp_c_ip_string = %s\n", dhcp_c_ip_string); + DbgPrint("dhcp_s_ip_string = %s\n", dhcp_s_ip_string); +// DbgPrint("dhcp_sname = %s\n", dhcp_sname); +// DbgPrint("dhcp_file = %s\n", dhcp_file); +// DbgPrint("host name = %s\n", dhcp_host_name); +// DbgPrint("root-path = %s\n", dhcp_root_path); break; } close(fd); + del_dummy_addr(client_config.interface); return 0; } - +int lwdhcp(int argc, char *argv[]) +{ + struct bootparams bootp; +#ifdef DHCP_3A780E + char *ifname = "rte0"; +#elif defined DHCP_3ASERVER + char *ifname = "em0"; +#endif + memset(&bootp, 0, sizeof(struct bootparams)); + + return mylwdhcp(&bootp, ifname); +} /* * Command table registration diff --git a/pmon/cmds/lwdhcp/packet.c b/pmon/cmds/lwdhcp/packet.c index 7ac03598..dc4eab10 100644 --- a/pmon/cmds/lwdhcp/packet.c +++ b/pmon/cmds/lwdhcp/packet.c @@ -161,17 +161,17 @@ int raw_packet(struct dhcp_packet *payload, uint32_t source_ip, int source_port, close (sock); return -1; } - /* + if (setsockopt (sock, SOL_SOCKET, SO_DONTROUTE, &n, sizeof (n)) < 0) { perror ("bootp setsockopt(DONTROUTE)"); close (sock); return -1; - }*/ + } - bzero((char *)&clnt, sizeof(clnt)); - clnt.sin_family = AF_INET; - clnt.sin_port = htons(CLIENT_PORT+2); - clnt.sin_addr.s_addr = INADDR_ANY; + bzero((char *)&clnt, sizeof(clnt)); + clnt.sin_family = AF_INET; + clnt.sin_port = htons(CLIENT_PORT+2); + clnt.sin_addr.s_addr = INADDR_ANY; if (bind (sock, (struct sockaddr *)&clnt, sizeof(clnt)) < 0) { PERROR ("bind failed"); @@ -219,6 +219,16 @@ static void add_requests(struct dhcp_packet *packet) } +static void add_1_request(struct dhcp_packet *packet, uint8_t option) +{ + int end = end_option(packet->options); + + packet->options[end + OPT_CODE] = DHCP_PARAM_REQ; + packet->options[end + OPT_DATA] = option; + packet->options[end + OPT_LEN] = 1; + packet->options[end + OPT_DATA + 1] = DHCP_END; +} + int send_request(unsigned long xid, uint32_t server, uint32_t requested_ip) { struct dhcp_packet packet; @@ -227,8 +237,25 @@ int send_request(unsigned long xid, uint32_t server, uint32_t requested_ip) packet.xid = xid; add_simple_option(packet.options, DHCP_SERVER_ID, server); - add_simple_option(packet.options, DHCP_REQUESTED_IP, requested_ip); + add_simple_option(packet.options, DHCP_REQUESTED_IP, requested_ip); + add_requests(&packet); + DbgPrint("Sending DHCPREQUEST...\n"); + + return raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, + SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex); +} + +int send_1_request(unsigned long xid, uint32_t server, uint32_t requested_ip, uint8_t option) +{ + struct dhcp_packet packet; + init_packet(&packet, DHCPREQUEST); + packet.xid = xid; + + add_simple_option(packet.options, DHCP_SERVER_ID, server); + add_simple_option(packet.options, DHCP_REQUESTED_IP, requested_ip); + + add_1_request(&packet, option); DbgPrint("Sending DHCPREQUEST...\n"); return raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, diff --git a/pmon/common/main.c b/pmon/common/main.c index 459439a9..08c79787 100644 --- a/pmon/common/main.c +++ b/pmon/common/main.c @@ -499,6 +499,19 @@ if(!run) return(0); } +char bootp_c_ip_string[15]; +char bootp_s_ip_string[15]; +char bootp_file[129]; +char bootp_opt[129]; + +char dhcp_netmask[16]; +char dhcp_c_ip_string[16]; +char dhcp_s_ip_string[16]; +char dhcp_sname[65]; +char dhcp_file[129]; +char dhcp_host_name[309]; +char dhcp_root_path[309]; + #ifdef AUTOLOAD static int autoload(char *s) { @@ -536,6 +549,19 @@ static int autoload(char *s) putchar ('\n'); if(cnt == 0) { +#define IDHCP 1 +#define IBOOTP 0 +#ifdef IDHCP +oh_yeah_one_more: + strcpy(buf, "ifaddr rte0 lwdhcp"); + printf("========> %s\n",buf); + ret = do_cmd(buf); +#elif IBOOTP + strcpy(buf, "ifaddr rte0 bootp"); + printf("========> %s\n",buf); + delay(500000); + do_cmd(buf); +#endif if(getenv("autocmd")) { strcpy(buf,getenv("autocmd")); diff --git a/pmon/netio/ifconfig.c b/pmon/netio/ifconfig.c index 554b2890..fbd4afbb 100644 --- a/pmon/netio/ifconfig.c +++ b/pmon/netio/ifconfig.c @@ -93,7 +93,8 @@ ifconfig (ifname, ipaddr) struct bootparams bootp; struct ifaliasreq addreq; char *gw; - int s, bootplev; + int s, bootplev, lwdhcplev; + char cmdbuf[LINESZ]; if (ifname == NULL) { printf("ifconfig: no ifc name\n"); @@ -116,9 +117,13 @@ ifconfig (ifname, ipaddr) */ #if 1 bootplev = matchenv ("bootp"); - if (strncmp(ipaddr, "bootp", 5) == 0) { + lwdhcplev = 0; + if (strncmp(ipaddr, "lwdhcp", 6) == 0) { bootplev = 2; - } else { + lwdhcplev = 1; + } else if(strncmp(ipaddr, "bootp", 5) == 0){ + bootplev = 2; + } else{ boot_parsecfg(&bootp, ipaddr); } #endif @@ -134,12 +139,15 @@ ifconfig (ifname, ipaddr) } if (bootplev >= 1) { + if(lwdhcplev == 0) + { /* Enable interface with an initial dummy net address. Note ipintr() has been kludged to route all input packets to an interface on the loopback net. */ bzero (&addreq, sizeof(addreq)); strncpy(addreq.ifra_name, ifname, IFNAMSIZ); - setsin (SIN(addreq.ifra_addr), AF_INET, htonl (0x7f000002)); + //setsin (SIN(addreq.ifra_addr), AF_INET, htonl (0x7f000002)); + setsin (SIN(addreq.ifra_addr), AF_INET, INADDR_ANY); setsin (SIN(addreq.ifra_broadaddr), AF_INET, INADDR_ANY); if (ioctl(s, SIOCAIFADDR, &addreq) < 0) { perror("ioctl (SIOCAIFADDR) dummy"); @@ -155,7 +163,14 @@ ifconfig (ifname, ipaddr) /* get any remaining unknown parameters from environment */ boot_getenv (&bootp, ifname); - } + } + else{ +#ifdef cmd_lwdhcp + mylwdhcp(&bootp, ifname); + boot_getenv(&bootp, ifname); +#endif + } + } if (!(bootp.have & BOOT_ADDR)) { if (bootplev >= 1) diff --git a/sys/dev/pci/rtl8168.c b/sys/dev/pci/rtl8168.c index 36fc0021..d99275da 100644 --- a/sys/dev/pci/rtl8168.c +++ b/sys/dev/pci/rtl8168.c @@ -2204,7 +2204,7 @@ static int rtl8168_open(struct rtl8168_private *tp) rtl8168_hw_start(tp); rtl8168_check_link_status(tp); - tp->arpcom.ac_if.if_flags |= IFF_RUNNING; + tp->arpcom.ac_if.if_flags |= IFF_RUNNING | IFF_BROADCAST | IFF_SIMPLEX; status = RTL_R16(tp, IntrStatus); diff --git a/sys/dev/pci/rtl8169.c b/sys/dev/pci/rtl8169.c index 4efc4cb5..61cb0204 100644 --- a/sys/dev/pci/rtl8169.c +++ b/sys/dev/pci/rtl8169.c @@ -2003,7 +2003,7 @@ static int rtl8169_open(struct rtl8169_private *tp) status = RTL_R16(tp, IntrStatus); rtl8169_check_link_status(tp); - tp->arpcom.ac_if.if_flags |= IFF_RUNNING; + tp->arpcom.ac_if.if_flags |= IFF_RUNNING | IFF_BROADCAST | IFF_SIMPLEX;; status = RTL_R16(tp, IntrStatus);