3 static SOCKET DhcpSocket
= INVALID_SOCKET
;
4 static LIST_ENTRY AdapterList
;
6 extern struct interface_info
*ifi
;
8 PCHAR
*GetSubkeyNames( PCHAR MainKeyName
, PCHAR Append
) {
12 PCHAR
*Out
, OutKeyName
;
13 DWORD CharTotal
= 0, AppendLen
= 1 + strlen(Append
);
14 DWORD MaxSubKeyLen
= 0, MaxSubKeys
= 0;
16 Error
= RegOpenKey( HKEY_LOCAL_MACHINE
, MainKeyName
, &MainKey
);
18 if( Error
) return NULL
;
20 Error
= RegQueryInfoKey
23 &MaxSubKeys
, &MaxSubKeyLen
,
24 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
26 DH_DbgPrint(MID_TRACE
,("MaxSubKeys: %d, MaxSubKeyLen %d\n",
27 MaxSubKeys
, MaxSubKeyLen
));
29 CharTotal
= (sizeof(PCHAR
) + MaxSubKeyLen
+ AppendLen
) * (MaxSubKeys
+ 1);
31 DH_DbgPrint(MID_TRACE
,("AppendLen: %d, CharTotal: %d\n",
32 AppendLen
, CharTotal
));
34 Out
= malloc( CharTotal
);
35 OutKeyName
= ((PCHAR
)&Out
[MaxSubKeys
+1]);
37 if( !Out
) { RegCloseKey( MainKey
); return NULL
; }
42 Error
= RegEnumKey( MainKey
, i
, OutKeyName
, MaxSubKeyLen
);
44 strcat( OutKeyName
, Append
);
45 DH_DbgPrint(MID_TRACE
,("[%d]: %s\n", i
, OutKeyName
));
46 OutKeyName
+= strlen(OutKeyName
) + 1;
49 } while( Error
== ERROR_SUCCESS
);
51 RegCloseKey( MainKey
);
56 PCHAR
RegReadString( HKEY Root
, PCHAR Subkey
, PCHAR Value
) {
58 DWORD SubOutLen
= 0, Error
= 0;
61 DH_DbgPrint(MID_TRACE
,("Looking in %x:%s:%s\n", Root
, Subkey
, Value
));
63 if( Subkey
&& strlen(Subkey
) ) {
64 if( RegOpenKey( Root
, Subkey
, &ValueKey
) != ERROR_SUCCESS
)
66 } else ValueKey
= Root
;
68 DH_DbgPrint(MID_TRACE
,("Got Key %x\n", ValueKey
));
70 if( (Error
= RegQueryValueEx( ValueKey
, Value
, NULL
, NULL
,
71 (LPBYTE
)SubOut
, &SubOutLen
)) != ERROR_SUCCESS
)
74 DH_DbgPrint(MID_TRACE
,("Value %s has size %d\n", Value
, SubOutLen
));
76 if( !(SubOut
= malloc(SubOutLen
)) )
79 if( (Error
= RegQueryValueEx( ValueKey
, Value
, NULL
, NULL
,
80 (LPBYTE
)SubOut
, &SubOutLen
)) != ERROR_SUCCESS
)
83 DH_DbgPrint(MID_TRACE
,("Value %s is %s\n", Value
, SubOut
));
88 if( SubOut
) free( SubOut
);
90 if( ValueKey
&& ValueKey
!= Root
) {
91 DH_DbgPrint(MID_TRACE
,("Closing key %x\n", ValueKey
));
92 RegCloseKey( ValueKey
);
95 DH_DbgPrint(MID_TRACE
,("Returning %x with error %d\n", SubOut
, Error
));
100 HKEY
FindAdapterKey( PDHCP_ADAPTER Adapter
) {
103 "SYSTEM\\CurrentControlSet\\Control\\Class\\"
104 "{4D36E972-E325-11CE-BFC1-08002BE10318}";
105 PCHAR TargetKeyNameStart
=
106 "SYSTEM\\CurrentControlSet\\Services\\";
107 PCHAR TargetKeyNameEnd
= "\\Parameters\\Tcpip";
108 PCHAR TargetKeyName
= NULL
;
109 PCHAR
*EnumKeysLinkage
= GetSubkeyNames( EnumKeyName
, "\\Linkage" );
110 PCHAR
*EnumKeysTop
= GetSubkeyNames( EnumKeyName
, "" );
111 PCHAR RootDevice
= NULL
, DriverDesc
= NULL
;
112 HKEY EnumKey
, OutKey
= NULL
;
113 DWORD Error
= ERROR_SUCCESS
;
115 if( !EnumKeysLinkage
|| !EnumKeysTop
) goto cleanup
;
117 Error
= RegOpenKey( HKEY_LOCAL_MACHINE
, EnumKeyName
, &EnumKey
);
119 if( Error
) goto cleanup
;
121 for( i
= 0; EnumKeysLinkage
[i
]; i
++ ) {
122 RootDevice
= RegReadString
123 ( EnumKey
, EnumKeysLinkage
[i
], "RootDevice" );
124 DriverDesc
= RegReadString
125 ( EnumKey
, EnumKeysTop
[i
], "DriverDesc" );
129 !strcmp( DriverDesc
, Adapter
->DhclientInfo
.name
) ) {
131 malloc( strlen( TargetKeyNameStart
) +
132 strlen( RootDevice
) +
133 strlen( TargetKeyNameEnd
) + 1 );
134 if( !TargetKeyName
) goto cleanup
;
135 sprintf( TargetKeyName
, "%s%s%s",
136 TargetKeyNameStart
, RootDevice
, TargetKeyNameEnd
);
137 Error
= RegOpenKey( HKEY_LOCAL_MACHINE
, TargetKeyName
, &OutKey
);
140 free( RootDevice
); RootDevice
= 0;
141 free( DriverDesc
); DriverDesc
= 0;
146 if( RootDevice
) free( RootDevice
);
147 if( DriverDesc
) free( DriverDesc
);
148 if( EnumKeysLinkage
) free( EnumKeysLinkage
);
149 if( EnumKeysTop
) free( EnumKeysTop
);
150 if( TargetKeyName
) free( TargetKeyName
);
155 BOOL
PrepareAdapterForService( PDHCP_ADAPTER Adapter
) {
156 HKEY AdapterKey
= NULL
;
157 PCHAR IPAddress
= NULL
, Netmask
= NULL
, DefaultGateway
= NULL
;
158 NTSTATUS Status
= STATUS_SUCCESS
;
159 DWORD Error
= ERROR_SUCCESS
;
160 MIB_IPFORWARDROW DefGatewayRow
;
162 Adapter
->DhclientState
.config
= &Adapter
->DhclientConfig
;
163 strncpy(Adapter
->DhclientInfo
.name
, (char*)Adapter
->IfMib
.bDescr
,
164 sizeof(Adapter
->DhclientInfo
.name
));
166 AdapterKey
= FindAdapterKey( Adapter
);
168 IPAddress
= RegReadString( AdapterKey
, NULL
, "IPAddress" );
170 if( IPAddress
&& strcmp( IPAddress
, "0.0.0.0" ) ) {
171 /* Non-automatic case */
173 (MID_TRACE
,("Adapter Name: [%s] (Bind Status %x) (static %s)\n",
174 Adapter
->DhclientInfo
.name
,
178 Adapter
->DhclientState
.state
= S_STATIC
;
180 Netmask
= RegReadString( AdapterKey
, NULL
, "Subnetmask" );
181 if( !Netmask
) Netmask
= "255.255.255.0";
183 Status
= AddIPAddress( inet_addr( IPAddress
),
184 inet_addr( Netmask
),
185 Adapter
->IfMib
.dwIndex
,
186 &Adapter
->NteContext
,
187 &Adapter
->NteInstance
);
189 DefaultGateway
= RegReadString( AdapterKey
, NULL
, "DefaultGateway" );
191 if( DefaultGateway
) {
192 DefGatewayRow
.dwForwardDest
= 0;
193 DefGatewayRow
.dwForwardMask
= 0;
194 DefGatewayRow
.dwForwardMetric1
= 1;
195 DefGatewayRow
.dwForwardNextHop
= inet_addr(DefaultGateway
);
196 Error
= CreateIpForwardEntry( &DefGatewayRow
);
198 warning("Failed to set default gateway %s: %ld\n",
199 DefaultGateway
, Error
);
202 if( DefaultGateway
) free( DefaultGateway
);
203 if( Netmask
) free( Netmask
);
207 (MID_TRACE
,("Adapter Name: [%s] (Bind Status %x) (dynamic)\n",
208 Adapter
->DhclientInfo
.name
,
209 Adapter
->BindStatus
));
212 if( IPAddress
) free( IPAddress
);
218 * XXX Figure out the way to bind a specific adapter to a socket.
222 PMIB_IFTABLE Table
= malloc(sizeof(MIB_IFTABLE
));
223 DWORD Error
, Size
, i
;
224 PDHCP_ADAPTER Adapter
= NULL
;
226 WSAStartup(0x0101,&wsd
);
228 InitializeListHead( &AdapterList
);
230 DH_DbgPrint(MID_TRACE
,("Getting Adapter List...\n"));
232 while( (Error
= GetIfTable(Table
, &Size
, 0 )) ==
233 ERROR_INSUFFICIENT_BUFFER
) {
234 DH_DbgPrint(MID_TRACE
,("Error %d, New Buffer Size: %d\n", Error
, Size
));
236 Table
= malloc( Size
);
239 if( Error
!= NO_ERROR
) goto term
;
241 DH_DbgPrint(MID_TRACE
,("Got Adapter List (%d entries)\n", Table
->dwNumEntries
));
243 for( i
= 0; i
< Table
->dwNumEntries
; i
++ ) {
244 DH_DbgPrint(MID_TRACE
,("Getting adapter %d attributes\n",
245 Table
->table
[i
].dwIndex
));
246 Adapter
= calloc( sizeof( DHCP_ADAPTER
) + Table
->table
[i
].dwMtu
, 1 );
248 if( Adapter
&& Table
->table
[i
].dwType
== MIB_IF_TYPE_ETHERNET
) {
249 memcpy( &Adapter
->IfMib
, &Table
->table
[i
],
250 sizeof(Adapter
->IfMib
) );
251 Adapter
->DhclientInfo
.client
= &Adapter
->DhclientState
;
252 Adapter
->DhclientInfo
.rbuf
= Adapter
->recv_buf
;
253 Adapter
->DhclientInfo
.rbuf_max
= Table
->table
[i
].dwMtu
;
254 Adapter
->DhclientInfo
.rbuf_len
=
255 Adapter
->DhclientInfo
.rbuf_offset
= 0;
256 memcpy(Adapter
->DhclientInfo
.hw_address
.haddr
,
257 Adapter
->IfMib
.bPhysAddr
,
258 Adapter
->IfMib
.dwPhysAddrLen
);
259 Adapter
->DhclientInfo
.hw_address
.hlen
=
260 Adapter
->IfMib
.dwPhysAddrLen
;
262 if( DhcpSocket
== INVALID_SOCKET
) {
264 Adapter
->DhclientInfo
.rfdesc
=
265 Adapter
->DhclientInfo
.wfdesc
=
266 socket( AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
267 Adapter
->ListenAddr
.sin_family
= AF_INET
;
268 Adapter
->ListenAddr
.sin_port
= htons(LOCAL_PORT
);
269 Adapter
->BindStatus
=
270 (bind( Adapter
->DhclientInfo
.rfdesc
,
271 (struct sockaddr
*)&Adapter
->ListenAddr
,
272 sizeof(Adapter
->ListenAddr
) ) == 0) ?
273 0 : WSAGetLastError();
275 Adapter
->DhclientInfo
.rfdesc
=
276 Adapter
->DhclientInfo
.wfdesc
= DhcpSocket
;
279 Adapter
->DhclientConfig
.timeout
= DHCP_PANIC_TIMEOUT
;
280 Adapter
->DhclientConfig
.initial_interval
= DHCP_DISCOVER_INTERVAL
;
281 Adapter
->DhclientConfig
.retry_interval
= DHCP_DISCOVER_INTERVAL
;
282 Adapter
->DhclientConfig
.select_interval
= 1;
283 Adapter
->DhclientConfig
.reboot_timeout
= DHCP_REBOOT_TIMEOUT
;
284 Adapter
->DhclientConfig
.backoff_cutoff
= DHCP_BACKOFF_MAX
;
285 Adapter
->DhclientState
.interval
=
286 Adapter
->DhclientConfig
.retry_interval
;
288 if( PrepareAdapterForService( Adapter
) ) {
289 Adapter
->DhclientInfo
.next
= ifi
;
290 ifi
= &Adapter
->DhclientInfo
;
291 InsertTailList( &AdapterList
, &Adapter
->ListEntry
);
292 } else { free( Adapter
); Adapter
= 0; }
293 } else { free( Adapter
); Adapter
= 0; }
296 DH_DbgPrint(MID_TRACE
,("Adapter %d was rejected\n",
297 Table
->table
[i
].dwIndex
));
300 DH_DbgPrint(MID_TRACE
,("done with AdapterInit\n"));
303 if( Table
) free( Table
);
307 PLIST_ENTRY ListEntry
;
308 PDHCP_ADAPTER Adapter
;
309 while( !IsListEmpty( &AdapterList
) ) {
310 ListEntry
= (PLIST_ENTRY
)RemoveHeadList( &AdapterList
);
311 Adapter
= CONTAINING_RECORD( ListEntry
, DHCP_ADAPTER
, ListEntry
);
317 PDHCP_ADAPTER
AdapterFindIndex( unsigned int indx
) {
318 PDHCP_ADAPTER Adapter
;
319 PLIST_ENTRY ListEntry
;
321 for( ListEntry
= AdapterList
.Flink
;
322 ListEntry
!= &AdapterList
;
323 ListEntry
= ListEntry
->Flink
) {
324 Adapter
= CONTAINING_RECORD( ListEntry
, DHCP_ADAPTER
, ListEntry
);
325 if( Adapter
->IfMib
.dwIndex
== indx
) return Adapter
;
331 PDHCP_ADAPTER
AdapterFindName( const WCHAR
*name
) {
332 PDHCP_ADAPTER Adapter
;
333 PLIST_ENTRY ListEntry
;
335 for( ListEntry
= AdapterList
.Flink
;
336 ListEntry
!= &AdapterList
;
337 ListEntry
= ListEntry
->Flink
) {
338 Adapter
= CONTAINING_RECORD( ListEntry
, DHCP_ADAPTER
, ListEntry
);
339 if( !wcsicmp( Adapter
->IfMib
.wszName
, name
) ) return Adapter
;
345 PDHCP_ADAPTER
AdapterFindInfo( struct interface_info
*ip
) {
346 PDHCP_ADAPTER Adapter
;
347 PLIST_ENTRY ListEntry
;
349 for( ListEntry
= AdapterList
.Flink
;
350 ListEntry
!= &AdapterList
;
351 ListEntry
= ListEntry
->Flink
) {
352 Adapter
= CONTAINING_RECORD( ListEntry
, DHCP_ADAPTER
, ListEntry
);
353 if( ip
== &Adapter
->DhclientInfo
) return Adapter
;
359 PDHCP_ADAPTER
AdapterGetFirst() {
360 if( IsListEmpty( &AdapterList
) ) return NULL
; else {
361 return CONTAINING_RECORD
362 ( AdapterList
.Flink
, DHCP_ADAPTER
, ListEntry
);
366 PDHCP_ADAPTER
AdapterGetNext( PDHCP_ADAPTER This
)
368 if( This
->ListEntry
.Flink
== &AdapterList
) return NULL
;
369 return CONTAINING_RECORD
370 ( This
->ListEntry
.Flink
, DHCP_ADAPTER
, ListEntry
);
373 void if_register_send(struct interface_info
*ip
) {
377 void if_register_receive(struct interface_info
*ip
) {