Browse Source

Modified the 'lwdhcp' command to implement the function of dhcp

Modify the code of command "ifaddr rte0 lwdhcp" in order to implement the function of
obtaining ip address automatically. This command will be executed before load kernel.
(First, you must configure one dhcp server.)
master
xuhaoyu 13 years ago
committed by mengxiaofu
parent
commit
73a879f783
  1. 3
      Targets/Bonito3a780e/conf/Bonito.3a780e
  2. 3
      Targets/Bonito3aserver/conf/Bonito.3aserver
  3. 190
      pmon/cmds/lwdhcp/lwdhcp.c
  4. 41
      pmon/cmds/lwdhcp/packet.c
  5. 26
      pmon/common/main.c
  6. 25
      pmon/netio/ifconfig.c
  7. 2
      sys/dev/pci/rtl8168.c
  8. 2
      sys/dev/pci/rtl8169.c

3
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

3
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

190
pmon/cmds/lwdhcp/lwdhcp.c

@ -11,11 +11,12 @@
#include <sys/endian.h>
#ifdef PMON
#ifdef KERNEL
#undef KERNEL
#ifdef _KERNEL
#undef _KERNEL
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#define _KERNEL
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
@ -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

41
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,

26
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"));

25
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)

2
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);

2
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);

Loading…
Cancel
Save