"SYSTEM\\CurrentControlSet\\Control\\Class\\"
"{4D36E972-E325-11CE-BFC1-08002BE10318}";
PCHAR TargetKeyNameStart =
- "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
+ "SYSTEM\\CurrentControlSet\\Services\\";
+ PCHAR TargetKeyNameEnd = "\\Parameters\\Tcpip";
PCHAR TargetKeyName = NULL;
PCHAR *EnumKeysLinkage = GetSubkeyNames( EnumKeyName, "\\Linkage" );
PCHAR *EnumKeysTop = GetSubkeyNames( EnumKeyName, "" );
!strcmp( RootDevice, Adapter->DhclientInfo.name ) ) {
TargetKeyName =
(CHAR*) malloc( strlen( TargetKeyNameStart ) +
- strlen( RootDevice ) + 1);
+ strlen( RootDevice ) + strlen( TargetKeyNameEnd ) + 1);
if( !TargetKeyName ) goto cleanup;
- sprintf( TargetKeyName, "%s%s",
- TargetKeyNameStart, RootDevice );
+ sprintf( TargetKeyName, "%s%s%s",
+ TargetKeyNameStart, RootDevice, TargetKeyNameEnd );
Error = RegCreateKeyExA( HKEY_LOCAL_MACHINE, TargetKeyName, 0, NULL, 0, KEY_READ, NULL, &OutKey, NULL );
break;
} else {
}
BOOL PrepareAdapterForService( PDHCP_ADAPTER Adapter ) {
- HKEY AdapterKey = NULL;
- PCHAR IPAddress = NULL, Netmask = NULL, DefaultGateway = NULL;
- NTSTATUS Status = STATUS_SUCCESS;
- DWORD Error = ERROR_SUCCESS;
+ HKEY AdapterKey;
+ DWORD Error = ERROR_SUCCESS, DhcpEnabled, Length;
Adapter->DhclientState.config = &Adapter->DhclientConfig;
strncpy(Adapter->DhclientInfo.name, (char*)Adapter->IfMib.bDescr,
AdapterKey = FindAdapterKey( Adapter );
if( AdapterKey )
- IPAddress = RegReadString( AdapterKey, NULL, "IPAddress" );
+ {
+ Error = RegQueryValueEx(AdapterKey, "EnableDHCP", NULL, NULL, (LPBYTE)&DhcpEnabled, &Length);
- if( IPAddress && strcmp( IPAddress, "0.0.0.0" ) ) {
- /* Non-automatic case */
- DH_DbgPrint
- (MID_TRACE,("Adapter Name: [%s] (Bind Status %x) (static %s)\n",
- Adapter->DhclientInfo.name,
- Adapter->BindStatus,
- IPAddress));
+ if (Error != ERROR_SUCCESS || Length != sizeof(DWORD))
+ DhcpEnabled = 1;
- Adapter->DhclientState.state = S_STATIC;
+ CloseHandle(AdapterKey);
+ }
+ else
+ {
+ /* DHCP enabled by default */
+ DhcpEnabled = 1;
+ }
- Netmask = RegReadString( AdapterKey, NULL, "Subnetmask" );
-
- Status = AddIPAddress( inet_addr( IPAddress ),
- inet_addr( Netmask ? Netmask : "255.255.255.0" ),
- Adapter->IfMib.dwIndex,
- &Adapter->NteContext,
- &Adapter->NteInstance );
-
- DefaultGateway = RegReadString( AdapterKey, NULL, "DefaultGateway" );
-
- if( DefaultGateway ) {
- Adapter->RouterMib.dwForwardDest = 0;
- Adapter->RouterMib.dwForwardMask = 0;
- Adapter->RouterMib.dwForwardMetric1 = 1;
- Adapter->RouterMib.dwForwardIfIndex = Adapter->IfMib.dwIndex;
- Adapter->RouterMib.dwForwardNextHop = inet_addr(DefaultGateway);
- Error = CreateIpForwardEntry( &Adapter->RouterMib );
- if( Error )
- warning("Failed to set default gateway %s: %ld\n",
- DefaultGateway, Error);
- }
+ if( !DhcpEnabled ) {
+ /* Non-automatic case */
+ DbgPrint("DHCPCSVC: Adapter Name: [%s] (static)\n", Adapter->DhclientInfo.name);
- if( DefaultGateway ) free( DefaultGateway );
- if( Netmask ) free( Netmask );
+ Adapter->DhclientState.state = S_STATIC;
} else {
/* Automatic case */
- DH_DbgPrint
- (MID_TRACE,("Adapter Name: [%s] (Bind Status %x) (dynamic)\n",
- Adapter->DhclientInfo.name,
- Adapter->BindStatus));
+ DbgPrint("DHCPCSVC: Adapter Name: [%s] (dynamic)\n", Adapter->DhclientInfo.name);
Adapter->DhclientInfo.client->state = S_INIT;
}
- if( IPAddress ) free( IPAddress );
-
return TRUE;
}
/*
* XXX Figure out the way to bind a specific adapter to a socket.
*/
-BOOLEAN AdapterDiscover() {
+DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
PMIB_IFTABLE Table = (PMIB_IFTABLE) malloc(sizeof(MIB_IFTABLE));
DWORD Error, Size = sizeof(MIB_IFTABLE);
PDHCP_ADAPTER Adapter = NULL;
+ HANDLE AdapterStateChangedEvent = (HANDLE)Context;
struct interface_info *ifi = NULL;
- int i;
- BOOLEAN ret = TRUE;
+ int i, AdapterCount = 0;
- DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n"));
+ /* FIXME: Kill this thread when the service is stopped */
- while( (Error = GetIfTable(Table, &Size, 0 )) ==
- ERROR_INSUFFICIENT_BUFFER ) {
- DH_DbgPrint(MID_TRACE,("Error %d, New Buffer Size: %d\n", Error, Size));
- free( Table );
- Table = (PMIB_IFTABLE) malloc( Size );
- }
+ do {
+ DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n"));
+
+ while( (Error = GetIfTable(Table, &Size, 0 )) ==
+ ERROR_INSUFFICIENT_BUFFER ) {
+ DH_DbgPrint(MID_TRACE,("Error %d, New Buffer Size: %d\n", Error, Size));
+ free( Table );
+ Table = (PMIB_IFTABLE) malloc( Size );
+ }
+
+ if( Error != NO_ERROR )
+ {
+ /* HACK: We are waiting until TCP/IP starts */
+ Sleep(2000);
+ continue;
+ }
+
+ DH_DbgPrint(MID_TRACE,("Got Adapter List (%d entries)\n", Table->dwNumEntries));
+
+ for( i = Table->dwNumEntries - 1; i >= 0; i-- ) {
+ DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n",
+ Table->table[i].dwIndex));
- if( Error != NO_ERROR ) {
- ret = FALSE;
- goto term;
- }
+ ApiLock();
- DH_DbgPrint(MID_TRACE,("Got Adapter List (%d entries)\n", Table->dwNumEntries));
-
- for( i = Table->dwNumEntries - 1; i >= 0; i-- ) {
- DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n",
- Table->table[i].dwIndex));
-
- if ((Adapter = 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);
- }
+ if ((Adapter = 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;
- }
+ ApiUnlock();
- Adapter = (DHCP_ADAPTER*) calloc( sizeof( DHCP_ADAPTER ) + Table->table[i].dwMtu, 1 );
-
- 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;
- Adapter->DhclientInfo.rbuf = Adapter->recv_buf;
- Adapter->DhclientInfo.rbuf_max = Table->table[i].dwMtu;
- Adapter->DhclientInfo.rbuf_len =
- Adapter->DhclientInfo.rbuf_offset = 0;
- memcpy(Adapter->DhclientInfo.hw_address.haddr,
- Adapter->IfMib.bPhysAddr,
- Adapter->IfMib.dwPhysAddrLen);
- Adapter->DhclientInfo.hw_address.hlen =
- Adapter->IfMib.dwPhysAddrLen;
- /* I'm not sure where else to set this, but
- some DHCP servers won't take a zero.
- We checked the hardware type earlier in
- the if statement. */
- Adapter->DhclientInfo.hw_address.htype =
- HTYPE_ETHER;
-
- if( DhcpSocket == INVALID_SOCKET ) {
- DhcpSocket =
- Adapter->DhclientInfo.rfdesc =
- Adapter->DhclientInfo.wfdesc =
- socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
-
- if (DhcpSocket != INVALID_SOCKET) {
- Adapter->ListenAddr.sin_family = AF_INET;
- Adapter->ListenAddr.sin_port = htons(LOCAL_PORT);
- Adapter->BindStatus =
- (bind( Adapter->DhclientInfo.rfdesc,
- (struct sockaddr *)&Adapter->ListenAddr,
- sizeof(Adapter->ListenAddr) ) == 0) ?
- 0 : WSAGetLastError();
+ continue;
+ }
+
+ ApiUnlock();
+
+ Adapter = (DHCP_ADAPTER*) calloc( sizeof( DHCP_ADAPTER ) + Table->table[i].dwMtu, 1 );
+
+ 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;
+ Adapter->DhclientInfo.rbuf = Adapter->recv_buf;
+ Adapter->DhclientInfo.rbuf_max = Table->table[i].dwMtu;
+ Adapter->DhclientInfo.rbuf_len =
+ Adapter->DhclientInfo.rbuf_offset = 0;
+ memcpy(Adapter->DhclientInfo.hw_address.haddr,
+ Adapter->IfMib.bPhysAddr,
+ Adapter->IfMib.dwPhysAddrLen);
+ Adapter->DhclientInfo.hw_address.hlen = Adapter->IfMib.dwPhysAddrLen;
+
+ /* I'm not sure where else to set this, but
+ some DHCP servers won't take a zero.
+ We checked the hardware type earlier in
+ the if statement. */
+ Adapter->DhclientInfo.hw_address.htype = HTYPE_ETHER;
+
+ if( DhcpSocket == INVALID_SOCKET ) {
+ DhcpSocket =
+ Adapter->DhclientInfo.rfdesc =
+ Adapter->DhclientInfo.wfdesc =
+ socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
+
+ if (DhcpSocket != INVALID_SOCKET) {
+ Adapter->ListenAddr.sin_family = AF_INET;
+ Adapter->ListenAddr.sin_port = htons(LOCAL_PORT);
+ Adapter->BindStatus =
+ (bind( Adapter->DhclientInfo.rfdesc,
+ (struct sockaddr *)&Adapter->ListenAddr,
+ sizeof(Adapter->ListenAddr) ) == 0) ?
+ 0 : WSAGetLastError();
+ } else {
+ error("socket() failed: %d\n", WSAGetLastError());
+ }
} else {
- error("socket() failed: %d\n", WSAGetLastError());
+ Adapter->DhclientInfo.rfdesc =
+ Adapter->DhclientInfo.wfdesc = DhcpSocket;
}
- } else {
- Adapter->DhclientInfo.rfdesc =
- Adapter->DhclientInfo.wfdesc = DhcpSocket;
- }
- 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;
- Adapter->DhclientConfig.reboot_timeout = DHCP_REBOOT_TIMEOUT;
- Adapter->DhclientConfig.backoff_cutoff = DHCP_BACKOFF_MAX;
- Adapter->DhclientState.interval =
- Adapter->DhclientConfig.retry_interval;
+ 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;
+ Adapter->DhclientConfig.reboot_timeout = DHCP_REBOOT_TIMEOUT;
+ Adapter->DhclientConfig.backoff_cutoff = DHCP_BACKOFF_MAX;
+ Adapter->DhclientState.interval =
+ Adapter->DhclientConfig.retry_interval;
+
+ if( PrepareAdapterForService( Adapter ) ) {
+ Adapter->DhclientInfo.next = ifi;
+ ifi = &Adapter->DhclientInfo;
+
+ read_client_conf(&Adapter->DhclientInfo);
+
+ if (Adapter->DhclientInfo.client->state == S_INIT)
+ {
+ add_protocol(Adapter->DhclientInfo.name,
+ Adapter->DhclientInfo.rfdesc,
+ got_one, &Adapter->DhclientInfo);
+
+ state_init(&Adapter->DhclientInfo);
+ }
+
+ ApiLock();
+ InsertTailList( &AdapterList, &Adapter->ListEntry );
+ AdapterCount++;
+ SetEvent(AdapterStateChangedEvent);
+ ApiUnlock();
+ } else { free( Adapter ); Adapter = 0; }
+ } else { free( Adapter ); Adapter = 0; }
+
+ if( !Adapter )
+ DH_DbgPrint(MID_TRACE,("Adapter %d was rejected\n",
+ Table->table[i].dwIndex));
+ }
+ Error = NotifyAddrChange(NULL, NULL);
+#if 0
+ if (Error != NO_ERROR)
+ break;
+#else
+ if (AdapterCount)
+ break;
+ else
+ Sleep(3000);
+#endif
+ } while (TRUE);
- if( PrepareAdapterForService( Adapter ) ) {
- Adapter->DhclientInfo.next = ifi;
- ifi = &Adapter->DhclientInfo;
+ DbgPrint("DHCPCSVC: Adapter discovery thread is terminating! (Error: %d)\n", Error);
- read_client_conf(&Adapter->DhclientInfo);
+ if( Table ) free( Table );
+ return Error;
+}
- if (Adapter->DhclientInfo.client->state == S_INIT)
- {
- add_protocol(Adapter->DhclientInfo.name,
- Adapter->DhclientInfo.rfdesc,
- got_one, &Adapter->DhclientInfo);
+HANDLE StartAdapterDiscovery(VOID) {
+ HANDLE /* ThreadHandle, */ EventHandle;
- state_init(&Adapter->DhclientInfo);
- }
+ EventHandle = CreateEvent(NULL,
+ FALSE,
+ FALSE,
+ NULL);
- InsertTailList( &AdapterList, &Adapter->ListEntry );
- } else { free( Adapter ); Adapter = 0; }
- } else { free( Adapter ); Adapter = 0; }
+#if 0
+ ThreadHandle = CreateThread(NULL,
+ 0,
+ AdapterDiscoveryThread,
+ (LPVOID)EventHandle,
+ 0,
+ NULL);
- if( !Adapter )
- DH_DbgPrint(MID_TRACE,("Adapter %d was rejected\n",
- Table->table[i].dwIndex));
- }
+ if (ThreadHandle == NULL)
+ return NULL;
- DH_DbgPrint(MID_TRACE,("done with AdapterInit\n"));
+ CloseHandle(ThreadHandle);
+#else
+ AdapterDiscoveryThread((LPVOID)EventHandle);
+#endif
-term:
- if( Table ) free( Table );
- return ret;
+ return EventHandle;
}
void AdapterStop() {
PLIST_ENTRY ListEntry;
PDHCP_ADAPTER Adapter;
+ ApiLock();
while( !IsListEmpty( &AdapterList ) ) {
ListEntry = (PLIST_ENTRY)RemoveHeadList( &AdapterList );
Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry );
free( Adapter );
}
+ ApiUnlock();
WSACleanup();
}