Author: cgutman
Date: Fri Jul 24 23:06:20 2009
New Revision: 42182
URL:
http://svn.reactos.org/svn/reactos?rev=42182&view=rev
Log:
- Add support for adapters added after DHCP is started
- Automatically request an IP address after an interface becomes ready (needed for DHCP
support on WLAN adapters)
Modified:
trunk/reactos/base/services/dhcp/adapter.c
trunk/reactos/base/services/dhcp/dhclient.c
trunk/reactos/base/services/dhcp/dispatch.c
trunk/reactos/base/services/dhcp/include/rosdhcp.h
Modified: trunk/reactos/base/services/dhcp/adapter.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/dhcp/adapter…
==============================================================================
--- trunk/reactos/base/services/dhcp/adapter.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/dhcp/adapter.c [iso-8859-1] Fri Jul 24 23:06:20 2009
@@ -198,28 +198,43 @@
(MID_TRACE,("Adapter Name: [%s] (Bind Status %x) (dynamic)\n",
Adapter->DhclientInfo.name,
Adapter->BindStatus));
+
+ add_protocol(Adapter->DhclientInfo.name, Adapter->DhclientInfo.rfdesc,
got_one, &Adapter->DhclientInfo);
+ Adapter->DhclientInfo.client->state = S_INIT;
+ state_reboot(&Adapter->DhclientInfo);
}
if( IPAddress ) free( IPAddress );
return TRUE;
+}
+
+void AdapterInit() {
+ WSAStartup(0x0101,&wsd);
+
+ InitializeListHead( &AdapterList );
+}
+
+int
+InterfaceConnected(MIB_IFROW IfEntry)
+{
+ if (IfEntry.dwOperStatus == IF_OPER_STATUS_CONNECTED ||
+ IfEntry.dwOperStatus == IF_OPER_STATUS_OPERATIONAL)
+ return 1;
+
+ return 0;
}
/*
* XXX Figure out the way to bind a specific adapter to a socket.
*/
-
-void AdapterInit() {
+void AdapterDiscover() {
PMIB_IFTABLE Table = (PMIB_IFTABLE) malloc(sizeof(MIB_IFTABLE));
DWORD Error, Size = sizeof(MIB_IFTABLE);
PDHCP_ADAPTER Adapter = NULL;
struct interface_info *ifi = NULL;
int i;
- WSAStartup(0x0101,&wsd);
-
- InitializeListHead( &AdapterList );
-
DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n"));
while( (Error = GetIfTable(Table, &Size, 0 )) ==
@@ -236,9 +251,25 @@
for( i = Table->dwNumEntries - 1; i >= 0; i-- ) {
DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n",
Table->table[i].dwIndex));
+
+ if (AdapterFindByHardwareAddress(Table->table[i].bPhysAddr,
Table->table[i].dwPhysAddrLen))
+ {
+ /* This is an existing adapter */
+ if (InterfaceConnected(Table->table[i])) {
+ /* We're still active so we stay in the list */
+ ifi = &Adapter->DhclientInfo;
+ } else {
+ /* We've lost our link so out we go */
+ RemoveEntryList(&Adapter->ListEntry);
+ free(Adapter);
+ }
+
+ continue;
+ }
+
Adapter = (DHCP_ADAPTER*) calloc( sizeof( DHCP_ADAPTER ) +
Table->table[i].dwMtu, 1 );
- if( Adapter && Table->table[i].dwType == MIB_IF_TYPE_ETHERNET ) {
+ if( Adapter && Table->table[i].dwType == MIB_IF_TYPE_ETHERNET
&& InterfaceConnected(Table->table[i])) {
memcpy( &Adapter->IfMib, &Table->table[i],
sizeof(Adapter->IfMib) );
Adapter->DhclientInfo.client = &Adapter->DhclientState;
@@ -287,6 +318,9 @@
if( PrepareAdapterForService( Adapter ) ) {
Adapter->DhclientInfo.next = ifi;
ifi = &Adapter->DhclientInfo;
+
+ read_client_conf(&Adapter->DhclientInfo);
+
InsertTailList( &AdapterList, &Adapter->ListEntry );
} else { free( Adapter ); Adapter = 0; }
} else { free( Adapter ); Adapter = 0; }
Modified: trunk/reactos/base/services/dhcp/dhclient.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/dhcp/dhclien…
==============================================================================
--- trunk/reactos/base/services/dhcp/dhclient.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/dhcp/dhclient.c [iso-8859-1] Fri Jul 24 23:06:20 2009
@@ -129,8 +129,6 @@
int
main(int argc, char *argv[])
{
- int i = 0;
- PDHCP_ADAPTER Adapter;
ApiInit();
AdapterInit();
PipeInit();
@@ -144,31 +142,6 @@
inaddr_any.s_addr = INADDR_ANY;
DH_DbgPrint(MID_TRACE,("DHCP Service Started\n"));
-
- for (Adapter = AdapterGetFirst();
- Adapter != NULL;
- Adapter = AdapterGetNext(Adapter))
- {
- read_client_conf(&Adapter->DhclientInfo);
-
- if (!interface_link_status(Adapter->DhclientInfo.name)) {
- DH_DbgPrint(MID_TRACE,("%s: no link ",
Adapter->DhclientInfo.name));
- Sleep(1000);
- while (!interface_link_status(Adapter->DhclientInfo.name)) {
- DH_DbgPrint(MID_TRACE,("."));
- if (++i > 10) {
- DH_DbgPrint(MID_TRACE,("Giving up for now on adapter
[%s]\n", Adapter->DhclientInfo.name));
- }
- Sleep(1000);
- }
- DH_DbgPrint(MID_TRACE,("Got link on [%s]\n",
Adapter->DhclientInfo.name));
- }
-
- DH_DbgPrint(MID_TRACE,("Discover Interfaces\n"));
-
- /* set up the interface */
- discover_interfaces(&Adapter->DhclientInfo);
- }
bootp_packet_handler = do_packet;
@@ -611,8 +584,6 @@
else warning("Could not find adapter for info %p\n", ip);
set_name_servers( Adapter, new_lease );
-
- reinitialize_interfaces();
}
/*
@@ -1102,7 +1073,6 @@
note("bound: immediate renewal.");
state_bound(ip);
}
- reinitialize_interfaces();
return;
}
Modified: trunk/reactos/base/services/dhcp/dispatch.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/dhcp/dispatc…
==============================================================================
--- trunk/reactos/base/services/dhcp/dispatch.c [iso-8859-1] (original)
+++ trunk/reactos/base/services/dhcp/dispatch.c [iso-8859-1] Fri Jul 24 23:06:20 2009
@@ -50,39 +50,9 @@
struct protocol *protocols = NULL;
struct timeout *timeouts = NULL;
static struct timeout *free_timeouts = NULL;
-static int interfaces_invalidated = FALSE;
void (*bootp_packet_handler)(struct interface_info *,
struct dhcp_packet *, int, unsigned int,
struct iaddr, struct hardware *);
-
-static int interface_status(struct interface_info *ifinfo);
-
-/*
- * Use getifaddrs() to get a list of all the attached interfaces. For
- * each interface that's of type INET and not the loopback interface,
- * register that interface with the network I/O software, figure out
- * what subnet it's on, and add it to the list of interfaces.
- */
-void
-discover_interfaces(struct interface_info *iface)
-{
- PDHCP_ADAPTER Adapter = AdapterFindInfo( iface );
-
- if_register_receive(iface);
- if_register_send(iface);
-
- if( Adapter->DhclientState.state != S_STATIC ) {
- add_protocol(iface->name, iface->rfdesc, got_one, iface);
- iface->client->state = S_INIT;
- state_reboot(iface);
- }
-}
-
-void
-reinitialize_interfaces(void)
-{
- interfaces_invalidated = 1;
-}
/*
* Wait for packets to come in using poll(). When a packet comes in,
@@ -93,18 +63,13 @@
void
dispatch(void)
{
- int count, i, to_msec, nfds = 0;
+ int count, i, to_msec, nfds;
struct protocol *l;
fd_set fds;
time_t howlong, cur_time;
struct timeval timeval;
ApiLock();
-
- for (l = protocols; l; l = l->next)
- nfds++;
-
- FD_ZERO(&fds);
do {
/*
@@ -112,6 +77,13 @@
* a timeout registered, time out the select call then.
*/
another:
+ AdapterDiscover();
+
+ for (l = protocols, nfds = 0; l; l = l->next)
+ nfds++;
+
+ FD_ZERO(&fds);
+
time(&cur_time);
if (timeouts) {
@@ -201,12 +173,9 @@
!ip->dead)) {
DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
(*(l->handler))(l);
- if (interfaces_invalidated)
- break;
}
i++;
}
- interfaces_invalidated = 0;
}
} while (1);
@@ -236,16 +205,18 @@
warning("receive_packet failed on %s: %s", ip->name,
strerror(errno));
ip->errors++;
- if ((!interface_status(ip)) ||
- (ip->noifmedia && ip->errors > 20)) {
+ if (ip->errors > 20) {
/* our interface has gone away. */
warning("Interface %s no longer appears valid.",
ip->name);
ip->dead = 1;
- interfaces_invalidated = 1;
close(l->fd);
remove_protocol(l);
- free(ip);
+ adapter = AdapterFindInfo(ip);
+ if (adapter) {
+ RemoveEntryList(&adapter->ListEntry);
+ free(adapter);
+ }
}
return;
}
@@ -269,75 +240,6 @@
from.sin_port, ifrom, &hfrom);
}
}
-
-#if 0
-int
-interface_status(struct interface_info *ifinfo)
-{
- char *ifname = ifinfo->name;
- int ifsock = ifinfo->rfdesc;
- struct ifreq ifr;
- struct ifmediareq ifmr;
-
- /* get interface flags */
- memset(&ifr, 0, sizeof(ifr));
- strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
- if (ioctl(ifsock, SIOCGIFFLAGS, &ifr) < 0) {
- syslog(LOG_ERR, "ioctl(SIOCGIFFLAGS) on %s: %m", ifname);
- goto inactive;
- }
-
- /*
- * if one of UP and RUNNING flags is dropped,
- * the interface is not active.
- */
- if ((ifr.ifr_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
- goto inactive;
-
- /* Next, check carrier on the interface, if possible */
- if (ifinfo->noifmedia)
- goto active;
- memset(&ifmr, 0, sizeof(ifmr));
- strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
- if (ioctl(ifsock, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
- if (errno != EINVAL) {
- syslog(LOG_DEBUG, "ioctl(SIOCGIFMEDIA) on %s: %m",
- ifname);
-
- ifinfo->noifmedia = 1;
- goto active;
- }
- /*
- * EINVAL (or ENOTTY) simply means that the interface
- * does not support the SIOCGIFMEDIA ioctl. We regard it alive.
- */
- ifinfo->noifmedia = 1;
- goto active;
- }
- if (ifmr.ifm_status & IFM_AVALID) {
- switch (ifmr.ifm_active & IFM_NMASK) {
- case IFM_ETHER:
- if (ifmr.ifm_status & IFM_ACTIVE)
- goto active;
- else
- goto inactive;
- break;
- default:
- goto inactive;
- }
- }
-inactive:
- return (0);
-active:
- return (1);
-}
-#else
-int
-interface_status(struct interface_info *ifinfo)
-{
- return (1);
-}
-#endif
void
add_timeout(time_t when, void (*where)(void *), void *what)
Modified: trunk/reactos/base/services/dhcp/include/rosdhcp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/services/dhcp/include…
==============================================================================
--- trunk/reactos/base/services/dhcp/include/rosdhcp.h [iso-8859-1] (original)
+++ trunk/reactos/base/services/dhcp/include/rosdhcp.h [iso-8859-1] Fri Jul 24 23:06:20
2009
@@ -73,6 +73,7 @@
#define srandom srand
void AdapterInit(VOID);
+void AdapterDiscover(VOID);
HANDLE PipeInit(VOID);
extern PDHCP_ADAPTER AdapterGetFirst();
extern PDHCP_ADAPTER AdapterGetNext(PDHCP_ADAPTER);