DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) { COMM_DHCP_REPLY Reply; PDHCP_ADAPTER Adapter; struct protocol* proto; ApiLock(); Adapter = AdapterFindIndex( Req->AdapterIndex ); if( !Adapter || Adapter->DhclientState.state == S_STATIC ) { Reply.Reply = 0; ApiUnlock(); return Send( &Reply ); } Reply.Reply = 1; proto = find_protocol_by_adapter( &Adapter->DhclientInfo ); if (proto) remove_protocol(proto); add_protocol( Adapter->DhclientInfo.name, Adapter->DhclientInfo.rfdesc, got_one, &Adapter->DhclientInfo ); Adapter->DhclientInfo.client->state = S_INIT; state_reboot(&Adapter->DhclientInfo); if (AdapterStateChangedEvent != NULL) SetEvent(AdapterStateChangedEvent); ApiUnlock(); return Send( &Reply ); }
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(); }
DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req ) { NTSTATUS Status; COMM_DHCP_REPLY Reply; PDHCP_ADAPTER Adapter; struct protocol* proto; ApiLock(); Adapter = AdapterFindIndex( Req->AdapterIndex ); Reply.Reply = Adapter ? 1 : 0; if( Adapter ) { if (Adapter->NteContext) { DeleteIPAddress( Adapter->NteContext ); Adapter->NteContext = 0; } if (Adapter->RouterMib.dwForwardNextHop) { DeleteIpForwardEntry( &Adapter->RouterMib ); Adapter->RouterMib.dwForwardNextHop = 0; } Adapter->DhclientState.state = S_STATIC; proto = find_protocol_by_adapter( &Adapter->DhclientInfo ); if (proto) remove_protocol(proto); Status = AddIPAddress( Req->Body.StaticRefreshParams.IPAddress, Req->Body.StaticRefreshParams.Netmask, Req->AdapterIndex, &Adapter->NteContext, &Adapter->NteInstance ); Reply.Reply = NT_SUCCESS(Status); if (AdapterStateChangedEvent != NULL) SetEvent(AdapterStateChangedEvent); } ApiUnlock(); return Send( &Reply ); }
DWORD DSQueryHWInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req ) { COMM_DHCP_REPLY Reply; PDHCP_ADAPTER Adapter; ApiLock(); Adapter = AdapterFindIndex( Req->AdapterIndex ); Reply.Reply = Adapter ? 1 : 0; if (Adapter) { Reply.QueryHWInfo.AdapterIndex = Req->AdapterIndex; Reply.QueryHWInfo.MediaType = Adapter->IfMib.dwType; Reply.QueryHWInfo.Mtu = Adapter->IfMib.dwMtu; Reply.QueryHWInfo.Speed = Adapter->IfMib.dwSpeed; } ApiUnlock(); return Send( &Reply ); }
DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) { COMM_DHCP_REPLY Reply; PDHCP_ADAPTER Adapter; struct protocol* proto; ApiLock(); Adapter = AdapterFindIndex( Req->AdapterIndex ); Reply.Reply = Adapter ? 1 : 0; if( Adapter ) { if (Adapter->NteContext) { DeleteIPAddress( Adapter->NteContext ); Adapter->NteContext = 0; } if (Adapter->RouterMib.dwForwardNextHop) { DeleteIpForwardEntry( &Adapter->RouterMib ); Adapter->RouterMib.dwForwardNextHop = 0; } proto = find_protocol_by_adapter( &Adapter->DhclientInfo ); if (proto) remove_protocol(proto); Adapter->DhclientInfo.client->active = NULL; Adapter->DhclientInfo.client->state = S_INIT; if (AdapterStateChangedEvent != NULL) SetEvent(AdapterStateChangedEvent); } ApiUnlock(); return Send( &Reply ); }
DWORD DSGetAdapterInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req ) { COMM_DHCP_REPLY Reply; PDHCP_ADAPTER Adapter; ApiLock(); Adapter = AdapterFindIndex( Req->AdapterIndex ); Reply.Reply = Adapter ? 1 : 0; if( Adapter ) { Reply.GetAdapterInfo.DhcpEnabled = (S_STATIC != Adapter->DhclientState.state); if (S_BOUND == Adapter->DhclientState.state) { if (sizeof(Reply.GetAdapterInfo.DhcpServer) == Adapter->DhclientState.active->serveraddress.len) { memcpy(&Reply.GetAdapterInfo.DhcpServer, Adapter->DhclientState.active->serveraddress.iabuf, Adapter->DhclientState.active->serveraddress.len); } else { DPRINT1("Unexpected server address len %d\n", Adapter->DhclientState.active->serveraddress.len); Reply.GetAdapterInfo.DhcpServer = htonl(INADDR_NONE); } Reply.GetAdapterInfo.LeaseObtained = Adapter->DhclientState.active->obtained; Reply.GetAdapterInfo.LeaseExpires = Adapter->DhclientState.active->expiry; } else { Reply.GetAdapterInfo.DhcpServer = htonl(INADDR_NONE); Reply.GetAdapterInfo.LeaseObtained = 0; Reply.GetAdapterInfo.LeaseExpires = 0; } } ApiUnlock(); return Send( &Reply ); }
/* * XXX Figure out the way to bind a specific adapter to a socket. */ 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; struct protocol *proto; int i, AdapterCount = 0, Broadcast; /* FIXME: Kill this thread when the service is stopped */ 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)); ApiLock(); if ((Adapter = AdapterFindByHardwareAddress(Table->table[i].bPhysAddr, Table->table[i].dwPhysAddrLen))) { proto = find_protocol_by_adapter(&Adapter->DhclientInfo); /* This is an existing adapter */ if (InterfaceConnected(&Table->table[i])) { /* We're still active so we stay in the list */ ifi = &Adapter->DhclientInfo; /* This is a hack because IP helper API sucks */ if (IsReconnectHackNeeded(Adapter, &Table->table[i])) { /* This handles a disconnect/reconnect */ if (proto) remove_protocol(proto); Adapter->DhclientInfo.client->state = S_INIT; /* These are already invalid since the media state change */ Adapter->RouterMib.dwForwardNextHop = 0; Adapter->NteContext = 0; add_protocol(Adapter->DhclientInfo.name, Adapter->DhclientInfo.rfdesc, got_one, &Adapter->DhclientInfo); state_init(&Adapter->DhclientInfo); SetEvent(AdapterStateChangedEvent); } } else { if (proto) remove_protocol(proto); /* We've lost our link so out we go */ RemoveEntryList(&Adapter->ListEntry); free(Adapter); } ApiUnlock(); 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) { /* Allow broadcast on this socket */ Broadcast = 1; setsockopt(DhcpSocket, SOL_SOCKET, SO_BROADCAST, (const char *)&Broadcast, sizeof(Broadcast)); 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 { 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; 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)); } #if 0 Error = NotifyAddrChange(NULL, NULL); if (Error != NO_ERROR) break; #else Sleep(3000); #endif } while (TRUE); DbgPrint("DHCPCSVC: Adapter discovery thread is terminating! (Error: %d)\n", Error); if( Table ) free( Table ); return Error; }
BOOL IsReconnectHackNeeded(PDHCP_ADAPTER Adapter, const MIB_IFROW* IfEntry) { struct protocol *proto; PIP_ADAPTER_INFO AdapterInfo, Orig; DWORD Size, Ret; char *ZeroAddress = "0.0.0.0"; proto = find_protocol_by_adapter(&Adapter->DhclientInfo); if (Adapter->DhclientInfo.client->state == S_BOUND && !proto) return FALSE; if (Adapter->DhclientInfo.client->state != S_BOUND && Adapter->DhclientInfo.client->state != S_STATIC) return FALSE; ApiUnlock(); Orig = AdapterInfo = HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO)); Size = sizeof(IP_ADAPTER_INFO); if (!AdapterInfo) { ApiLock(); return FALSE; } Ret = GetAdaptersInfo(AdapterInfo, &Size); if (Ret == ERROR_BUFFER_OVERFLOW) { HeapFree(GetProcessHeap(), 0, AdapterInfo); AdapterInfo = HeapAlloc(GetProcessHeap(), 0, Size); if (!AdapterInfo) { ApiLock(); return FALSE; } if (GetAdaptersInfo(AdapterInfo, &Size) != NO_ERROR) { ApiLock(); return FALSE; } Orig = AdapterInfo; for (; AdapterInfo != NULL; AdapterInfo = AdapterInfo->Next) { if (AdapterInfo->Index == IfEntry->dwIndex) break; } if (AdapterInfo == NULL) { HeapFree(GetProcessHeap(), 0, Orig); ApiLock(); return FALSE; } } else if (Ret != NO_ERROR) { HeapFree(GetProcessHeap(), 0, Orig); ApiLock(); return FALSE; } if (!strcmp(AdapterInfo->IpAddressList.IpAddress.String, ZeroAddress)) { HeapFree(GetProcessHeap(), 0, Orig); ApiLock(); return TRUE; } else { HeapFree(GetProcessHeap(), 0, Orig); ApiLock(); return FALSE; } }