@ -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 , SIOCG IFADDR , & ifr ) = = 0 )
if ( ioctl ( fd , SIOCA IFADDR , & 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 ( " SIOCG IFADDR failed, is the interface up and configured? \n " ) ;
PERROR ( " SIOCA IFADDR 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,8 +252,12 @@ 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 )
@ -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,11 +280,19 @@ 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 ;
tmo < < = 1 ;
if ( tmo > = MAXTMO )
{
if ( loop + + < JTLOOP )
tmo = MINTMO ;
else
{
dhcp_request = 0 ;
@ -258,6 +301,8 @@ tryagain:
return 0 ;
}
}
goto tryagain ;
}
size = sizeof ( from ) ;
if ( recvfrom ( fd , buf , sizeof ( struct dhcp_packet ) , ( struct sockaddr * ) 0 , & from , & size ) < 0 )
@ -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,11 +338,19 @@ 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 ;
tmo < < = 1 ;
if ( tmo > = MAXTMO )
{
if ( loop + + < JTLOOP )
tmo = MINTMO ;
else
{
dhcp_request = 0 ;
@ -305,6 +359,8 @@ tryagain:
return 0 ;
}
}
goto tryagain ;
}
//get_raw_packet(buf, fd);
@ -313,6 +369,8 @@ tryagain:
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