mirror of
https://github.com/reactos/reactos.git
synced 2025-06-05 01:10:26 +00:00
- 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) svn path=/trunk/; revision=42182
This commit is contained in:
parent
15a5343ec1
commit
f9fe2ff6a8
4 changed files with 56 additions and 149 deletions
|
@ -198,6 +198,10 @@ BOOL PrepareAdapterForService( PDHCP_ADAPTER Adapter ) {
|
||||||
(MID_TRACE,("Adapter Name: [%s] (Bind Status %x) (dynamic)\n",
|
(MID_TRACE,("Adapter Name: [%s] (Bind Status %x) (dynamic)\n",
|
||||||
Adapter->DhclientInfo.name,
|
Adapter->DhclientInfo.name,
|
||||||
Adapter->BindStatus));
|
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 );
|
if( IPAddress ) free( IPAddress );
|
||||||
|
@ -205,21 +209,32 @@ BOOL PrepareAdapterForService( PDHCP_ADAPTER Adapter ) {
|
||||||
return TRUE;
|
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.
|
* XXX Figure out the way to bind a specific adapter to a socket.
|
||||||
*/
|
*/
|
||||||
|
void AdapterDiscover() {
|
||||||
void AdapterInit() {
|
|
||||||
PMIB_IFTABLE Table = (PMIB_IFTABLE) malloc(sizeof(MIB_IFTABLE));
|
PMIB_IFTABLE Table = (PMIB_IFTABLE) malloc(sizeof(MIB_IFTABLE));
|
||||||
DWORD Error, Size = sizeof(MIB_IFTABLE);
|
DWORD Error, Size = sizeof(MIB_IFTABLE);
|
||||||
PDHCP_ADAPTER Adapter = NULL;
|
PDHCP_ADAPTER Adapter = NULL;
|
||||||
struct interface_info *ifi = NULL;
|
struct interface_info *ifi = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
WSAStartup(0x0101,&wsd);
|
|
||||||
|
|
||||||
InitializeListHead( &AdapterList );
|
|
||||||
|
|
||||||
DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n"));
|
DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n"));
|
||||||
|
|
||||||
while( (Error = GetIfTable(Table, &Size, 0 )) ==
|
while( (Error = GetIfTable(Table, &Size, 0 )) ==
|
||||||
|
@ -236,9 +251,25 @@ void AdapterInit() {
|
||||||
for( i = Table->dwNumEntries - 1; i >= 0; i-- ) {
|
for( i = Table->dwNumEntries - 1; i >= 0; i-- ) {
|
||||||
DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n",
|
DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n",
|
||||||
Table->table[i].dwIndex));
|
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 );
|
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],
|
memcpy( &Adapter->IfMib, &Table->table[i],
|
||||||
sizeof(Adapter->IfMib) );
|
sizeof(Adapter->IfMib) );
|
||||||
Adapter->DhclientInfo.client = &Adapter->DhclientState;
|
Adapter->DhclientInfo.client = &Adapter->DhclientState;
|
||||||
|
@ -287,6 +318,9 @@ void AdapterInit() {
|
||||||
if( PrepareAdapterForService( Adapter ) ) {
|
if( PrepareAdapterForService( Adapter ) ) {
|
||||||
Adapter->DhclientInfo.next = ifi;
|
Adapter->DhclientInfo.next = ifi;
|
||||||
ifi = &Adapter->DhclientInfo;
|
ifi = &Adapter->DhclientInfo;
|
||||||
|
|
||||||
|
read_client_conf(&Adapter->DhclientInfo);
|
||||||
|
|
||||||
InsertTailList( &AdapterList, &Adapter->ListEntry );
|
InsertTailList( &AdapterList, &Adapter->ListEntry );
|
||||||
} else { free( Adapter ); Adapter = 0; }
|
} else { free( Adapter ); Adapter = 0; }
|
||||||
} else { free( Adapter ); Adapter = 0; }
|
} else { free( Adapter ); Adapter = 0; }
|
||||||
|
|
|
@ -129,8 +129,6 @@ static SERVICE_TABLE_ENTRY ServiceTable[2] =
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
int i = 0;
|
|
||||||
PDHCP_ADAPTER Adapter;
|
|
||||||
ApiInit();
|
ApiInit();
|
||||||
AdapterInit();
|
AdapterInit();
|
||||||
PipeInit();
|
PipeInit();
|
||||||
|
@ -145,31 +143,6 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
DH_DbgPrint(MID_TRACE,("DHCP Service Started\n"));
|
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;
|
bootp_packet_handler = do_packet;
|
||||||
|
|
||||||
DH_DbgPrint(MID_TRACE,("Going into dispatch()\n"));
|
DH_DbgPrint(MID_TRACE,("Going into dispatch()\n"));
|
||||||
|
@ -611,8 +584,6 @@ bind_lease(struct interface_info *ip)
|
||||||
else warning("Could not find adapter for info %p\n", ip);
|
else warning("Could not find adapter for info %p\n", ip);
|
||||||
|
|
||||||
set_name_servers( Adapter, new_lease );
|
set_name_servers( Adapter, new_lease );
|
||||||
|
|
||||||
reinitialize_interfaces();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1102,7 +1073,6 @@ state_panic(void *ipp)
|
||||||
note("bound: immediate renewal.");
|
note("bound: immediate renewal.");
|
||||||
state_bound(ip);
|
state_bound(ip);
|
||||||
}
|
}
|
||||||
reinitialize_interfaces();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,40 +50,10 @@
|
||||||
struct protocol *protocols = NULL;
|
struct protocol *protocols = NULL;
|
||||||
struct timeout *timeouts = NULL;
|
struct timeout *timeouts = NULL;
|
||||||
static struct timeout *free_timeouts = NULL;
|
static struct timeout *free_timeouts = NULL;
|
||||||
static int interfaces_invalidated = FALSE;
|
|
||||||
void (*bootp_packet_handler)(struct interface_info *,
|
void (*bootp_packet_handler)(struct interface_info *,
|
||||||
struct dhcp_packet *, int, unsigned int,
|
struct dhcp_packet *, int, unsigned int,
|
||||||
struct iaddr, struct hardware *);
|
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,
|
* Wait for packets to come in using poll(). When a packet comes in,
|
||||||
* call receive_packet to receive the packet and possibly strip hardware
|
* call receive_packet to receive the packet and possibly strip hardware
|
||||||
|
@ -93,7 +63,7 @@ reinitialize_interfaces(void)
|
||||||
void
|
void
|
||||||
dispatch(void)
|
dispatch(void)
|
||||||
{
|
{
|
||||||
int count, i, to_msec, nfds = 0;
|
int count, i, to_msec, nfds;
|
||||||
struct protocol *l;
|
struct protocol *l;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
time_t howlong, cur_time;
|
time_t howlong, cur_time;
|
||||||
|
@ -101,17 +71,19 @@ dispatch(void)
|
||||||
|
|
||||||
ApiLock();
|
ApiLock();
|
||||||
|
|
||||||
for (l = protocols; l; l = l->next)
|
|
||||||
nfds++;
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/*
|
/*
|
||||||
* 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:
|
||||||
|
AdapterDiscover();
|
||||||
|
|
||||||
|
for (l = protocols, nfds = 0; l; l = l->next)
|
||||||
|
nfds++;
|
||||||
|
|
||||||
|
FD_ZERO(&fds);
|
||||||
|
|
||||||
time(&cur_time);
|
time(&cur_time);
|
||||||
|
|
||||||
if (timeouts) {
|
if (timeouts) {
|
||||||
|
@ -201,12 +173,9 @@ dispatch(void)
|
||||||
!ip->dead)) {
|
!ip->dead)) {
|
||||||
DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
|
DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
|
||||||
(*(l->handler))(l);
|
(*(l->handler))(l);
|
||||||
if (interfaces_invalidated)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
interfaces_invalidated = 0;
|
|
||||||
}
|
}
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
|
@ -236,16 +205,18 @@ got_one(struct protocol *l)
|
||||||
warning("receive_packet failed on %s: %s", ip->name,
|
warning("receive_packet failed on %s: %s", ip->name,
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
ip->errors++;
|
ip->errors++;
|
||||||
if ((!interface_status(ip)) ||
|
if (ip->errors > 20) {
|
||||||
(ip->noifmedia && ip->errors > 20)) {
|
|
||||||
/* our interface has gone away. */
|
/* our interface has gone away. */
|
||||||
warning("Interface %s no longer appears valid.",
|
warning("Interface %s no longer appears valid.",
|
||||||
ip->name);
|
ip->name);
|
||||||
ip->dead = 1;
|
ip->dead = 1;
|
||||||
interfaces_invalidated = 1;
|
|
||||||
close(l->fd);
|
close(l->fd);
|
||||||
remove_protocol(l);
|
remove_protocol(l);
|
||||||
free(ip);
|
adapter = AdapterFindInfo(ip);
|
||||||
|
if (adapter) {
|
||||||
|
RemoveEntryList(&adapter->ListEntry);
|
||||||
|
free(adapter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -270,75 +241,6 @@ got_one(struct protocol *l)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#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
|
void
|
||||||
add_timeout(time_t when, void (*where)(void *), void *what)
|
add_timeout(time_t when, void (*where)(void *), void *what)
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,6 +73,7 @@ typedef DWORD (*PipeSendFunc)( COMM_DHCP_REPLY *Reply );
|
||||||
#define srandom srand
|
#define srandom srand
|
||||||
|
|
||||||
void AdapterInit(VOID);
|
void AdapterInit(VOID);
|
||||||
|
void AdapterDiscover(VOID);
|
||||||
HANDLE PipeInit(VOID);
|
HANDLE PipeInit(VOID);
|
||||||
extern PDHCP_ADAPTER AdapterGetFirst();
|
extern PDHCP_ADAPTER AdapterGetFirst();
|
||||||
extern PDHCP_ADAPTER AdapterGetNext(PDHCP_ADAPTER);
|
extern PDHCP_ADAPTER AdapterGetNext(PDHCP_ADAPTER);
|
||||||
|
|
Loading…
Reference in a new issue