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));
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 );
if( Adapter ) {
if( Adapter && Table->table[i].dwType ) {
memcpy( &Adapter->IfMib, &Table->table[i],
sizeof(Adapter->IfMib) );
GetAddress( Adapter );
@ -93,6 +94,7 @@ void AdapterInit() {
Adapter->DhclientInfo.wfdesc = DhcpSocket;
}
Adapter->DhclientState.config = &Adapter->DhclientConfig;
Adapter->DhclientConfig.timeout = DHCP_PANIC_TIMEOUT;
Adapter->DhclientConfig.initial_interval = DHCP_DISCOVER_INTERVAL;
Adapter->DhclientConfig.retry_interval = DHCP_DISCOVER_INTERVAL;
Adapter->DhclientConfig.select_interval = 1;
@ -154,6 +156,20 @@ PDHCP_ADAPTER AdapterFindName( const WCHAR *name ) {
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() {
if( IsListEmpty( &AdapterList ) ) return NULL; else {
return CONTAINING_RECORD

View file

@ -85,6 +85,7 @@ int privfd;
struct iaddr iaddr_broadcast = { 4, { 255, 255, 255, 255 } };
struct in_addr inaddr_any;
struct sockaddr_in sockaddr_broadcast;
unsigned long old_default_route = 0;
/*
* 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
in this particular lease. */
if (!picked) {
script_init("ARPCHECK", lp->medium);
script_write_params("check_", lp);
/* If the ARPCHECK code detects another
machine using the offered address, it exits
nonzero. We need to send a DHCPDECLINE and
toss the lease. */
if (script_go()) {
make_decline(ip, lp);
send_decline(ip);
goto freeit;
}
picked = lp;
picked->next = NULL;
script_init("ARPCHECK", lp->medium);
script_write_params("check_", lp);
/* If the ARPCHECK code detects another
machine using the offered address, it exits
nonzero. We need to send a DHCPDECLINE and
toss the lease. */
#if 0 /* XXX Later check ARP. For now, trust leases */
if (script_go()) {
make_decline(ip, lp);
send_decline(ip);
goto freeit;
}
#endif
picked = lp;
picked->next = NULL;
} else {
freeit:
free_client_lease(lp);
@ -580,42 +583,121 @@ dhcpack(struct packet *packet)
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
bind_lease(struct interface_info *ip)
{
/* Remember the medium. */
ip->client->new->medium = ip->client->medium;
PDHCP_ADAPTER Adapter;
struct client_lease *new_lease = ip->client->new;
/* Write out the new lease. */
write_client_lease(ip, ip->client->new, 0);
/* Remember the medium. */
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. */
script_init((ip->client->state == S_REQUESTING ? "BOUND" :
(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();
/* Set up a timeout to start the renewal process. */
add_timeout(ip->client->active->renewal, state_bound, ip);
/* Replace the old active lease with the new one. */
if (ip->client->active)
free_client_lease(ip->client->active);
ip->client->active = ip->client->new;
ip->client->new = NULL;
note("bound to %s -- renewal in %d seconds.",
piaddr(ip->client->active->address),
ip->client->active->renewal - cur_time);
/* Set up a timeout to start the renewal process. */
add_timeout(ip->client->active->renewal, state_bound, ip);
ip->client->state = S_BOUND;
Adapter = AdapterFindInfo( ip );
note("bound to %s -- renewal in %d seconds.",
piaddr(ip->client->active->address),
ip->client->active->renewal - cur_time);
ip->client->state = S_BOUND;
reinitialize_interfaces();
// go_daemon();
if( Adapter ) setup_adapter( Adapter, new_lease );
else warning("Could not find adapter for info %p\n", ip);
set_name_servers( new_lease );
reinitialize_interfaces();
}
/*
@ -1588,8 +1670,6 @@ rewrite_client_leases(void)
write_client_lease(ifi, ifi->client->active, 1);
fflush(leaseFile);
// ftruncate(fileno(leaseFile), ftello(leaseFile));
// fsync(fileno(leaseFile));
}
void

View file

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

View file

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

View file

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