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/dhclient... ============================================================================== --- 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/dispatch... ============================================================================== --- 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);