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" );
128 !strcmp( DriverDesc
, Adapter
->DhclientInfo
.name
) ) {
130 malloc( strlen( TargetKeyNameStart
) +
131 strlen( RootDevice
) +
132 strlen( TargetKeyNameEnd
) + 1 );
133 if( !TargetKeyName
) goto cleanup
;
134 sprintf( TargetKeyName
, "%s%s%s",
135 TargetKeyNameStart
, RootDevice
, TargetKeyNameEnd
);
136 Error
= RegOpenKey( HKEY_LOCAL_MACHINE
, TargetKeyName
, &OutKey
);
139 free( RootDevice
); RootDevice
= 0;
140 free( DriverDesc
); DriverDesc
= 0;
145 if( RootDevice
) free( RootDevice
);
146 if( DriverDesc
) free( DriverDesc
);
147 if( EnumKeysLinkage
) free( EnumKeysLinkage
);
148 if( EnumKeysTop
) free( EnumKeysTop
);
149 if( TargetKeyName
) free( TargetKeyName
);
154 BOOL
PrepareAdapterForService( PDHCP_ADAPTER Adapter
) {
155 HKEY AdapterKey
= NULL
;
156 PCHAR IPAddress
= NULL
, Netmask
= NULL
, DefaultGateway
= NULL
;
157 NTSTATUS Status
= STATUS_SUCCESS
;
158 DWORD Error
= ERROR_SUCCESS
;
159 MIB_IPFORWARDROW DefGatewayRow
;
161 Adapter
->DhclientState
.config
= &Adapter
->DhclientConfig
;
162 strncpy(Adapter
->DhclientInfo
.name
, (char*)Adapter
->IfMib
.bDescr
,
163 sizeof(Adapter
->DhclientInfo
.name
));
165 AdapterKey
= FindAdapterKey( Adapter
);
167 IPAddress
= RegReadString( AdapterKey
, NULL
, "IPAddress" );
169 if( IPAddress
&& strcmp( IPAddress
, "0.0.0.0" ) ) {
170 /* Non-automatic case */
172 (MID_TRACE
,("Adapter Name: [%s] (Bind Status %x) (static %s)\n",
173 Adapter
->DhclientInfo
.name
,
177 Adapter
->DhclientState
.state
= S_STATIC
;
179 Netmask
= RegReadString( AdapterKey
, NULL
, "Subnetmask" );
180 if( !Netmask
) Netmask
= "255.255.255.0";
182 Status
= AddIPAddress( inet_addr( IPAddress
),
183 inet_addr( Netmask
),
184 Adapter
->IfMib
.dwIndex
,
185 &Adapter
->NteContext
,
186 &Adapter
->NteInstance
);
188 DefaultGateway
= RegReadString( AdapterKey
, NULL
, "DefaultGateway" );
190 if( DefaultGateway
) {
191 DefGatewayRow
.dwForwardDest
= 0;
192 DefGatewayRow
.dwForwardMask
= 0;
193 DefGatewayRow
.dwForwardMetric1
= 1;
194 DefGatewayRow
.dwForwardNextHop
= inet_addr(DefaultGateway
);
195 Error
= CreateIpForwardEntry( &DefGatewayRow
);
197 warning("Failed to set default gateway %s: %ld\n",
198 DefaultGateway
, Error
);
201 if( DefaultGateway
) free( DefaultGateway
);
202 if( Netmask
) free( Netmask
);
206 (MID_TRACE
,("Adapter Name: [%s] (Bind Status %x) (dynamic)\n",
207 Adapter
->DhclientInfo
.name
,
208 Adapter
->BindStatus
));
211 if( IPAddress
) free( IPAddress
);
217 * XXX Figure out the way to bind a specific adapter to a socket.
221 PMIB_IFTABLE Table
= malloc(sizeof(MIB_IFTABLE
));
222 DWORD Error
, Size
, i
;
223 PDHCP_ADAPTER Adapter
= NULL
;
225 WSAStartup(0x0101,&wsd
);
227 InitializeListHead( &AdapterList
);
229 DH_DbgPrint(MID_TRACE
,("Getting Adapter List...\n"));
231 while( (Error
= GetIfTable(Table
, &Size
, 0 )) ==
232 ERROR_INSUFFICIENT_BUFFER
) {
233 DH_DbgPrint(MID_TRACE
,("Error %d, New Buffer Size: %d\n", Error
, Size
));
235 Table
= malloc( Size
);
238 if( Error
!= NO_ERROR
) goto term
;
240 DH_DbgPrint(MID_TRACE
,("Got Adapter List (%d entries)\n", Table
->dwNumEntries
));
242 for( i
= 0; i
< Table
->dwNumEntries
; i
++ ) {
243 DH_DbgPrint(MID_TRACE
,("Getting adapter %d attributes\n",
244 Table
->table
[i
].dwIndex
));
245 Adapter
= calloc( sizeof( DHCP_ADAPTER
) + Table
->table
[i
].dwMtu
, 1 );
247 if( Adapter
&& Table
->table
[i
].dwType
== MIB_IF_TYPE_ETHERNET
) {
248 memcpy( &Adapter
->IfMib
, &Table
->table
[i
],
249 sizeof(Adapter
->IfMib
) );
250 Adapter
->DhclientInfo
.client
= &Adapter
->DhclientState
;
251 Adapter
->DhclientInfo
.rbuf
= Adapter
->recv_buf
;
252 Adapter
->DhclientInfo
.rbuf_max
= Table
->table
[i
].dwMtu
;
253 Adapter
->DhclientInfo
.rbuf_len
=
254 Adapter
->DhclientInfo
.rbuf_offset
= 0;
255 memcpy(Adapter
->DhclientInfo
.hw_address
.haddr
,
256 Adapter
->IfMib
.bPhysAddr
,
257 Adapter
->IfMib
.dwPhysAddrLen
);
258 Adapter
->DhclientInfo
.hw_address
.hlen
=
259 Adapter
->IfMib
.dwPhysAddrLen
;
261 if( DhcpSocket
== INVALID_SOCKET
) {
263 Adapter
->DhclientInfo
.rfdesc
=
264 Adapter
->DhclientInfo
.wfdesc
=
265 socket( AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
266 Adapter
->ListenAddr
.sin_family
= AF_INET
;
267 Adapter
->ListenAddr
.sin_port
= htons(LOCAL_PORT
);
268 Adapter
->BindStatus
=
269 (bind( Adapter
->DhclientInfo
.rfdesc
,
270 (struct sockaddr
*)&Adapter
->ListenAddr
,
271 sizeof(Adapter
->ListenAddr
) ) == 0) ?
272 0 : WSAGetLastError();
274 Adapter
->DhclientInfo
.rfdesc
=
275 Adapter
->DhclientInfo
.wfdesc
= DhcpSocket
;
278 Adapter
->DhclientConfig
.timeout
= DHCP_PANIC_TIMEOUT
;
279 Adapter
->DhclientConfig
.initial_interval
= DHCP_DISCOVER_INTERVAL
;
280 Adapter
->DhclientConfig
.retry_interval
= DHCP_DISCOVER_INTERVAL
;
281 Adapter
->DhclientConfig
.select_interval
= 1;
282 Adapter
->DhclientConfig
.reboot_timeout
= DHCP_REBOOT_TIMEOUT
;
283 Adapter
->DhclientConfig
.backoff_cutoff
= DHCP_BACKOFF_MAX
;
284 Adapter
->DhclientState
.interval
=
285 Adapter
->DhclientConfig
.retry_interval
;
287 if( PrepareAdapterForService( Adapter
) ) {
288 Adapter
->DhclientInfo
.next
= ifi
;
289 ifi
= &Adapter
->DhclientInfo
;
290 InsertTailList( &AdapterList
, &Adapter
->ListEntry
);
291 } else { free( Adapter
); Adapter
= 0; }
292 } else { free( Adapter
); Adapter
= 0; }
295 DH_DbgPrint(MID_TRACE
,("Adapter %d was rejected\n",
296 Table
->table
[i
].dwIndex
));
299 DH_DbgPrint(MID_TRACE
,("done with AdapterInit\n"));
302 if( Table
) free( Table
);
306 PLIST_ENTRY ListEntry
;
307 PDHCP_ADAPTER Adapter
;
308 while( !IsListEmpty( &AdapterList
) ) {
309 ListEntry
= (PLIST_ENTRY
)RemoveHeadList( &AdapterList
);
310 Adapter
= CONTAINING_RECORD( ListEntry
, DHCP_ADAPTER
, ListEntry
);
316 PDHCP_ADAPTER
AdapterFindIndex( unsigned int indx
) {
317 PDHCP_ADAPTER Adapter
;
318 PLIST_ENTRY ListEntry
;
320 for( ListEntry
= AdapterList
.Flink
;
321 ListEntry
!= &AdapterList
;
322 ListEntry
= ListEntry
->Flink
) {
323 Adapter
= CONTAINING_RECORD( ListEntry
, DHCP_ADAPTER
, ListEntry
);
324 if( Adapter
->IfMib
.dwIndex
== indx
) return Adapter
;
330 PDHCP_ADAPTER
AdapterFindName( const WCHAR
*name
) {
331 PDHCP_ADAPTER Adapter
;
332 PLIST_ENTRY ListEntry
;
334 for( ListEntry
= AdapterList
.Flink
;
335 ListEntry
!= &AdapterList
;
336 ListEntry
= ListEntry
->Flink
) {
337 Adapter
= CONTAINING_RECORD( ListEntry
, DHCP_ADAPTER
, ListEntry
);
338 if( !wcsicmp( Adapter
->IfMib
.wszName
, name
) ) return Adapter
;
344 PDHCP_ADAPTER
AdapterFindInfo( struct interface_info
*ip
) {
345 PDHCP_ADAPTER Adapter
;
346 PLIST_ENTRY ListEntry
;
348 for( ListEntry
= AdapterList
.Flink
;
349 ListEntry
!= &AdapterList
;
350 ListEntry
= ListEntry
->Flink
) {
351 Adapter
= CONTAINING_RECORD( ListEntry
, DHCP_ADAPTER
, ListEntry
);
352 if( ip
== &Adapter
->DhclientInfo
) return Adapter
;
358 PDHCP_ADAPTER
AdapterGetFirst() {
359 if( IsListEmpty( &AdapterList
) ) return NULL
; else {
360 return CONTAINING_RECORD
361 ( AdapterList
.Flink
, DHCP_ADAPTER
, ListEntry
);
365 PDHCP_ADAPTER
AdapterGetNext( PDHCP_ADAPTER This
)
367 if( This
->ListEntry
.Flink
== &AdapterList
) return NULL
;
368 return CONTAINING_RECORD
369 ( This
->ListEntry
.Flink
, DHCP_ADAPTER
, ListEntry
);
372 void if_register_send(struct interface_info
*ip
) {
376 void if_register_receive(struct interface_info
*ip
) {