More cleaning. Mostly working DHCP. IP address is automatically discovered

and configured on the first ethernet adapter.

svn path=/trunk/; revision=14645
This commit is contained in:
Art Yerkes 2005-04-17 07:58:24 +00:00
parent aa0b005b38
commit 4c0e95ce09
5 changed files with 164 additions and 71 deletions

View file

@ -62,10 +62,11 @@ void AdapterInit() {
DH_DbgPrint(MID_TRACE,("Got Adapter List (%d entries)\n", Table->dwNumEntries)); DH_DbgPrint(MID_TRACE,("Got Adapter List (%d entries)\n", Table->dwNumEntries));
for( i = 0; i < Table->dwNumEntries; i++ ) { for( i = 0; i < Table->dwNumEntries; i++ ) {
DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n", i)); DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n",
Table->table[i].dwIndex));
Adapter = calloc( sizeof( DHCP_ADAPTER ) + Table->table[i].dwMtu, 1 ); Adapter = calloc( sizeof( DHCP_ADAPTER ) + Table->table[i].dwMtu, 1 );
if( Adapter ) { if( Adapter && Table->table[i].dwType ) {
memcpy( &Adapter->IfMib, &Table->table[i], memcpy( &Adapter->IfMib, &Table->table[i],
sizeof(Adapter->IfMib) ); sizeof(Adapter->IfMib) );
GetAddress( Adapter ); GetAddress( Adapter );
@ -93,6 +94,7 @@ void AdapterInit() {
Adapter->DhclientInfo.wfdesc = DhcpSocket; Adapter->DhclientInfo.wfdesc = DhcpSocket;
} }
Adapter->DhclientState.config = &Adapter->DhclientConfig; Adapter->DhclientState.config = &Adapter->DhclientConfig;
Adapter->DhclientConfig.timeout = DHCP_PANIC_TIMEOUT;
Adapter->DhclientConfig.initial_interval = DHCP_DISCOVER_INTERVAL; Adapter->DhclientConfig.initial_interval = DHCP_DISCOVER_INTERVAL;
Adapter->DhclientConfig.retry_interval = DHCP_DISCOVER_INTERVAL; Adapter->DhclientConfig.retry_interval = DHCP_DISCOVER_INTERVAL;
Adapter->DhclientConfig.select_interval = 1; Adapter->DhclientConfig.select_interval = 1;
@ -154,6 +156,20 @@ PDHCP_ADAPTER AdapterFindName( const WCHAR *name ) {
return NULL; return NULL;
} }
PDHCP_ADAPTER AdapterFindInfo( struct interface_info *ip ) {
PDHCP_ADAPTER Adapter;
PLIST_ENTRY ListEntry;
for( ListEntry = AdapterList.Flink;
ListEntry != &AdapterList;
ListEntry = ListEntry->Flink ) {
Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
if( ip == &Adapter->DhclientInfo ) return Adapter;
}
return NULL;
}
PDHCP_ADAPTER AdapterGetFirst() { PDHCP_ADAPTER AdapterGetFirst() {
if( IsListEmpty( &AdapterList ) ) return NULL; else { if( IsListEmpty( &AdapterList ) ) return NULL; else {
return CONTAINING_RECORD return CONTAINING_RECORD

View file

@ -85,6 +85,7 @@ int privfd;
struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } }; struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
struct in_addr inaddr_any; struct in_addr inaddr_any;
struct sockaddr_in sockaddr_broadcast; struct sockaddr_in sockaddr_broadcast;
unsigned long old_default_route = 0;
/* /*
* ASSERT_STATE() does nothing now; it used to be * ASSERT_STATE() does nothing now; it used to be
@ -437,20 +438,22 @@ state_selecting(void *ipp)
/* Check to see if we got an ARPREPLY for the address /* Check to see if we got an ARPREPLY for the address
in this particular lease. */ in this particular lease. */
if (!picked) { if (!picked) {
script_init("ARPCHECK", lp->medium); script_init("ARPCHECK", lp->medium);
script_write_params("check_", lp); script_write_params("check_", lp);
/* If the ARPCHECK code detects another /* If the ARPCHECK code detects another
machine using the offered address, it exits machine using the offered address, it exits
nonzero. We need to send a DHCPDECLINE and nonzero. We need to send a DHCPDECLINE and
toss the lease. */ toss the lease. */
if (script_go()) { #if 0 /* XXX Later check ARP. For now, trust leases */
make_decline(ip, lp); if (script_go()) {
send_decline(ip); make_decline(ip, lp);
goto freeit; send_decline(ip);
} goto freeit;
picked = lp; }
picked->next = NULL; #endif
picked = lp;
picked->next = NULL;
} else { } else {
freeit: freeit:
free_client_lease(lp); free_client_lease(lp);
@ -580,42 +583,121 @@ dhcpack(struct packet *packet)
bind_lease(ip); bind_lease(ip);
} }
void set_name_servers( struct client_lease *new_lease ) {
if( new_lease->options[DHO_NAME_SERVERS].len ) {
HKEY RegKey;
struct iaddr nameserver;
char *nsbuf;
int i, addrs =
new_lease->options[DHO_NAME_SERVERS].len / sizeof(ULONG);
nsbuf = malloc( addrs * sizeof(IP_ADDRESS_STRING) );
nsbuf[0] = 0;
if( nsbuf && !RegOpenKeyEx
( HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters",
0, KEY_WRITE, &RegKey ) ) {
for( i = 0; i < addrs; i++ ) {
memcpy( nameserver.iabuf,
new_lease->options[DHO_NAME_SERVERS].data +
(addrs * sizeof(ULONG)), sizeof(ULONG) );
strcat( nsbuf, piaddr(nameserver) );
if( i != addrs-1 ) strcat( nsbuf, "," );
}
DH_DbgPrint(MID_TRACE,("Setting Nameservers: %s\n", nsbuf));
RegSetValueEx( RegKey, "NameServer", 0, REG_SZ,
nsbuf, strlen(nsbuf) );
free( nsbuf );
}
}
}
void setup_adapter( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
struct iaddr netmask;
if( Adapter->NteContext )
DeleteIPAddress( Adapter->NteContext );
if( new_lease->options[DHO_SUBNET_MASK].len ) {
NTSTATUS Status;
memcpy( netmask.iabuf,
new_lease->options[DHO_SUBNET_MASK].data,
new_lease->options[DHO_SUBNET_MASK].len );
Status = AddIPAddress
( *((ULONG*)new_lease->address.iabuf),
*((ULONG*)netmask.iabuf),
Adapter->IfMib.dwIndex,
&Adapter->NteContext,
&Adapter->NteInstance );
if( !NT_SUCCESS(Status) )
warning("AddIPAddress: %x\n", Status);
}
if( new_lease->options[DHO_ROUTERS].len ) {
MIB_IPFORWARDROW RouterMib;
NTSTATUS Status;
struct iaddr router;
memcpy( netmask.iabuf,
new_lease->options[DHO_ROUTERS].data,
new_lease->options[DHO_ROUTERS].len );
RouterMib.dwForwardDest = 0; /* Default route */
RouterMib.dwForwardMask = 0;
RouterMib.dwForwardMetric1 = 1;
if( old_default_route ) {
RouterMib.dwForwardDest = old_default_route;
DeleteIpForwardEntry( &RouterMib );
}
RouterMib.dwForwardNextHop = *((ULONG*)router.iabuf);
Status = CreateIpForwardEntry( &RouterMib );
if( !NT_SUCCESS(Status) )
warning("CreateIpForwardEntry: %x\n", Status);
else
old_default_route = RouterMib.dwForwardNextHop;
}
}
void void
bind_lease(struct interface_info *ip) bind_lease(struct interface_info *ip)
{ {
/* Remember the medium. */ PDHCP_ADAPTER Adapter;
ip->client->new->medium = ip->client->medium; struct client_lease *new_lease = ip->client->new;
/* Write out the new lease. */ /* Remember the medium. */
write_client_lease(ip, ip->client->new, 0); ip->client->new->medium = ip->client->medium;
ip->client->active = ip->client->new;
ip->client->new = NULL;
/* Run the client script with the new parameters. */ /* Set up a timeout to start the renewal process. */
script_init((ip->client->state == S_REQUESTING ? "BOUND" : add_timeout(ip->client->active->renewal, state_bound, ip);
(ip->client->state == S_RENEWING ? "RENEW" :
(ip->client->state == S_REBOOTING ? "REBOOT" : "REBIND"))),
ip->client->new->medium);
if (ip->client->active && ip->client->state != S_REBOOTING)
script_write_params("old_", ip->client->active);
script_write_params("new_", ip->client->new);
if (ip->client->alias)
script_write_params("alias_", ip->client->alias);
script_go();
/* Replace the old active lease with the new one. */ note("bound to %s -- renewal in %d seconds.",
if (ip->client->active) piaddr(ip->client->active->address),
free_client_lease(ip->client->active); ip->client->active->renewal - cur_time);
ip->client->active = ip->client->new;
ip->client->new = NULL;
/* Set up a timeout to start the renewal process. */ ip->client->state = S_BOUND;
add_timeout(ip->client->active->renewal, state_bound, ip);
Adapter = AdapterFindInfo( ip );
note("bound to %s -- renewal in %d seconds.", if( Adapter ) setup_adapter( Adapter, new_lease );
piaddr(ip->client->active->address), else warning("Could not find adapter for info %p\n", ip);
ip->client->active->renewal - cur_time);
ip->client->state = S_BOUND; set_name_servers( new_lease );
reinitialize_interfaces();
// go_daemon(); reinitialize_interfaces();
} }
/* /*
@ -1588,8 +1670,6 @@ rewrite_client_leases(void)
write_client_lease(ifi, ifi->client->active, 1); write_client_lease(ifi, ifi->client->active, 1);
fflush(leaseFile); fflush(leaseFile);
// ftruncate(fileno(leaseFile), ftello(leaseFile));
// fsync(fileno(leaseFile));
} }
void void

View file

@ -206,27 +206,16 @@ dispatch(void)
FD_ZERO(&fds); FD_ZERO(&fds);
// fds = malloc(nfds * sizeof(struct pollfd));
// if (fds == NULL)
// error("Can't allocate poll structures.");
do { do {
DH_DbgPrint(MID_TRACE,("Cycling dispatch()\n"));
/* /*
* Call any expired timeouts, and then if there's still * Call any expired timeouts, and then if there's still
* a timeout registered, time out the select call then. * a timeout registered, time out the select call then.
*/ */
another: another:
if (timeouts) { if (timeouts) {
DH_DbgPrint(MID_TRACE,("Some timeouts are available\n"));
struct timeout *t; struct timeout *t;
if (timeouts->when <= cur_time) { if (timeouts->when <= cur_time) {
DH_DbgPrint(MID_TRACE,("Calling timeout %x %p %x\n",
timeouts->when,
timeouts->func,
timeouts->what));
t = timeouts; t = timeouts;
timeouts = timeouts->next; timeouts = timeouts->next;
(*(t->func))(t->what); (*(t->func))(t->what);
@ -253,12 +242,7 @@ dispatch(void)
struct interface_info *ip = l->local; struct interface_info *ip = l->local;
if (ip && (l->handler != got_one || !ip->dead)) { if (ip && (l->handler != got_one || !ip->dead)) {
DH_DbgPrint(MID_TRACE,("l->fd %d\n", l->fd));
FD_SET(l->fd, &fds); FD_SET(l->fd, &fds);
// fds[i].fd = l->fd;
// fds[i].events = POLLIN;
// fds[i].revents = 0;
i++; i++;
} }
} }
@ -269,13 +253,26 @@ dispatch(void)
/* Wait for a packet or a timeout... XXX */ /* Wait for a packet or a timeout... XXX */
timeval.tv_sec = to_msec / 1000; timeval.tv_sec = to_msec / 1000;
timeval.tv_usec = (to_msec % 1000) * 1000; timeval.tv_usec = (to_msec % 1000) * 1000;
DH_DbgPrint(MID_TRACE,("select(%d,%d.%03d) =>\n",
nfds,timeval.tv_sec,timeval.tv_usec/1000));
ApiUnlock(); ApiUnlock();
count = select(nfds, &fds, NULL, NULL, &timeval); count = select(nfds, &fds, NULL, NULL, &timeval);
DH_DbgPrint(MID_TRACE,(" => %d\n", count));
DH_DbgPrint(MID_TRACE,("Select: %d\n", count));
/* Review poll output */
for (i = 0, l = protocols; l; l = l->next) {
struct interface_info *ip = l->local;
if (ip && (l->handler != got_one || !ip->dead)) {
DH_DbgPrint
(MID_TRACE,
("set(%d) -> %s\n",
l->fd, FD_ISSET(l->fd, &fds) ? "true" : "false"));
i++;
}
}
ApiLock(); ApiLock();
@ -295,9 +292,7 @@ dispatch(void)
for (l = protocols; l; l = l->next) { for (l = protocols; l; l = l->next) {
struct interface_info *ip; struct interface_info *ip;
ip = l->local; ip = l->local;
if (!FD_ISSET(l->fd, &fds)) { if (FD_ISSET(l->fd, &fds)) {
//.revents & (POLLIN | POLLHUP))) {
// fds[i].revents = 0;
if (ip && (l->handler != got_one || if (ip && (l->handler != got_one ||
!ip->dead)) { !ip->dead)) {
DH_DbgPrint(MID_TRACE,("Handling %x\n", l)); DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
@ -309,7 +304,6 @@ dispatch(void)
} }
interfaces_invalidated = 0; interfaces_invalidated = 0;
} }
DH_DbgPrint(MID_TRACE,("Done\n"));
} while (1); } while (1);
ApiUnlock(); /* Not reached currently */ ApiUnlock(); /* Not reached currently */

View file

@ -21,6 +21,7 @@
#undef PREFER #undef PREFER
#define DHCP_DISCOVER_INTERVAL 15 #define DHCP_DISCOVER_INTERVAL 15
#define DHCP_REBOOT_TIMEOUT 300 #define DHCP_REBOOT_TIMEOUT 300
#define DHCP_PANIC_TIMEOUT DHCP_REBOOT_TIMEOUT * 3
#define DHCP_BACKOFF_MAX 300 #define DHCP_BACKOFF_MAX 300
#define _PATH_DHCLIENT_PID "\\systemroot\\system32\\drivers\\etc\\dhclient.pid" #define _PATH_DHCLIENT_PID "\\systemroot\\system32\\drivers\\etc\\dhclient.pid"
@ -59,6 +60,7 @@ typedef DWORD (*PipeSendFunc)( COMM_DHCP_REPLY *Reply );
#define srandom srand #define srandom srand
extern PDHCP_ADAPTER AdapterFindIndex( unsigned int AdapterIndex ); extern PDHCP_ADAPTER AdapterFindIndex( unsigned int AdapterIndex );
extern PDHCP_ADAPTER AdapterFindInfo( struct interface_info *info );
extern VOID ApiInit(); extern VOID ApiInit();
extern VOID ApiLock(); extern VOID ApiLock();
extern VOID ApiUnlock(); extern VOID ApiUnlock();

View file

@ -2,8 +2,9 @@
#include "rosdhcp.h" #include "rosdhcp.h"
char *piaddr( struct iaddr addr ) { char *piaddr( struct iaddr addr ) {
struct sockaddr_in *sa = (struct sockaddr_in *)addr.iabuf; struct sockaddr_in sa;
return inet_ntoa( sa->sin_addr ); memcpy(&sa.sin_addr,addr.iabuf,sizeof(sa.sin_addr));
return inet_ntoa( sa.sin_addr );
} }
int note( char *format, ... ) { int note( char *format, ... ) {