@@ -227,6 +227,28 @@ state_init(void *ipp)
227227 send_discover (ip );
228228}
229229
230+ void
231+ state_release (void * ipp )
232+ {
233+ struct interface_info * ip = ipp ;
234+ ULONG foo = (ULONG ) GetTickCount ();
235+
236+ ASSERT_STATE (state , S_BOUND );
237+
238+ /* Make a DHCPRELEASE packet, and set appropriate per-interface
239+ flags. */
240+ make_release (ip , ip -> client -> active );
241+
242+ /* make_request doesn't initialize xid because it normally comes
243+ from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,
244+ so pick an xid now. */
245+ ip -> client -> xid = RtlRandom (& foo );
246+ send_release (ip );
247+
248+ ip -> client -> state = S_RELEASED ;
249+ unbind_lease (ip );
250+ }
251+
230252/*
231253 * state_selecting is called when one or more DHCPOFFER packets
232254 * have been received and a configurable period of time has passed.
@@ -379,6 +401,7 @@ dhcpack(struct packet *packet)
379401 ip -> client -> new -> renewal / 2 + ip -> client -> new -> renewal / 4 ;
380402
381403#ifdef __REACTOS__
404+ ip -> client -> new -> lease = ip -> client -> new -> expiry ;
382405 ip -> client -> new -> obtained = cur_time ;
383406#endif
384407 ip -> client -> new -> expiry += cur_time ;
@@ -439,6 +462,23 @@ void set_name_servers( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
439462
440463}
441464
465+ void
466+ unset_name_servers (
467+ PDHCP_ADAPTER Adapter )
468+ {
469+ CHAR Buffer [200 ] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\" ;
470+ HKEY RegKey ;
471+
472+ strcat (Buffer , Adapter -> DhclientInfo .name );
473+ if (RegOpenKeyExA (HKEY_LOCAL_MACHINE , Buffer , 0 , KEY_WRITE , & RegKey ) != ERROR_SUCCESS )
474+ return ;
475+
476+ RegDeleteValueW ( RegKey , L"DhcpNameServer" );
477+
478+ RegCloseKey ( RegKey );
479+ }
480+
481+
442482void
443483set_domain (PDHCP_ADAPTER Adapter ,
444484 struct client_lease * new_lease )
@@ -489,12 +529,40 @@ set_domain(PDHCP_ADAPTER Adapter,
489529
490530}
491531
532+ void
533+ unset_domain (
534+ PDHCP_ADAPTER Adapter )
535+ {
536+ CHAR Buffer1 [MAX_PATH ] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\" ;
537+ CHAR Buffer2 [MAX_PATH ] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" ;
538+ HKEY RegKey1 , RegKey2 ;
539+
540+ strcat (Buffer1 , Adapter -> DhclientInfo .name );
541+
542+ if (RegOpenKeyExA (HKEY_LOCAL_MACHINE , Buffer1 , 0 , KEY_WRITE , & RegKey1 ) != ERROR_SUCCESS )
543+ {
544+ return ;
545+ }
546+
547+ if (RegOpenKeyExA (HKEY_LOCAL_MACHINE , Buffer2 , 0 , KEY_WRITE , & RegKey2 ) != ERROR_SUCCESS )
548+ {
549+ RegCloseKey (RegKey1 );
550+ return ;
551+ }
552+
553+ RegDeleteValueW (RegKey1 , L"DhcpDomain" );
554+ RegDeleteValueW (RegKey2 , L"DhcpDomain" );
555+
556+ RegCloseKey (RegKey1 );
557+ RegCloseKey (RegKey2 );
558+ }
559+
560+
492561void setup_adapter ( PDHCP_ADAPTER Adapter , struct client_lease * new_lease ) {
493562 CHAR Buffer [200 ] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\" ;
494563 struct iaddr netmask ;
495564 HKEY hkey ;
496565 int i ;
497- DWORD dwEnableDHCP ;
498566
499567 strcat (Buffer , Adapter -> DhclientInfo .name );
500568 if (RegOpenKeyExA (HKEY_LOCAL_MACHINE , Buffer , 0 , KEY_WRITE , & hkey ) != ERROR_SUCCESS )
@@ -530,12 +598,13 @@ void setup_adapter( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
530598 strcat (Buffer , "." );
531599 }
532600 RegSetValueExA (hkey , "DhcpSubnetMask" , 0 , REG_SZ , (LPBYTE )Buffer , strlen (Buffer )+ 1 );
533- dwEnableDHCP = 1 ;
534- RegSetValueExA (hkey , "EnableDHCP" , 0 , REG_DWORD , (LPBYTE )& dwEnableDHCP , sizeof (DWORD ));
601+ RegSetValueExA (hkey , "DhcpServer" , 0 , REG_SZ , (LPBYTE )piaddr (new_lease -> serveraddress ), strlen (piaddr (new_lease -> serveraddress ))+ 1 );
535602
603+ RegSetValueExA (hkey , "Lease" , 0 , REG_DWORD , (LPBYTE )& new_lease -> lease , sizeof (DWORD ));
536604 RegSetValueExA (hkey , "LeaseObtainedTime" , 0 , REG_DWORD , (LPBYTE )& new_lease -> obtained , sizeof (DWORD ));
537605 RegSetValueExA (hkey , "LeaseTerminatesTime" , 0 , REG_DWORD , (LPBYTE )& new_lease -> expiry , sizeof (DWORD ));
538- RegSetValueExA (hkey , "DhcpServer" , 0 , REG_SZ , (LPBYTE )piaddr (new_lease -> serveraddress ), strlen (piaddr (new_lease -> serveraddress ))+ 1 );
606+ RegSetValueExA (hkey , "T1" , 0 , REG_DWORD , (LPBYTE )& new_lease -> renewal , sizeof (DWORD ));
607+ RegSetValueExA (hkey , "T2" , 0 , REG_DWORD , (LPBYTE )& new_lease -> rebind , sizeof (DWORD ));
539608 }
540609
541610 if ( !NT_SUCCESS (Status ) )
@@ -579,6 +648,56 @@ void setup_adapter( PDHCP_ADAPTER Adapter, struct client_lease *new_lease ) {
579648 RegCloseKey (hkey );
580649}
581650
651+ void
652+ reset_adapter ( PDHCP_ADAPTER Adapter ) {
653+ CHAR Buffer [200 ] = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\" ;
654+ CHAR IpAddress [] = "0.0.0.0" ;
655+ CHAR SubnetMask [] = "255.0.0.0" ;
656+ CHAR Server [] = "255.255.255.255" ;
657+ HKEY hkey ;
658+ DWORD lease ;
659+ time_t cur_time , new_time ;
660+
661+ time (& cur_time );
662+
663+ strcat (Buffer , Adapter -> DhclientInfo .name );
664+ if (RegOpenKeyExA (HKEY_LOCAL_MACHINE , Buffer , 0 , KEY_WRITE , & hkey ) != ERROR_SUCCESS )
665+ hkey = NULL ;
666+
667+ if ( Adapter -> NteContext )
668+ {
669+ DeleteIPAddress ( Adapter -> NteContext );
670+ Adapter -> NteContext = 0 ;
671+ }
672+
673+ if (hkey ) {
674+ RegSetValueExA (hkey , "DhcpIPAddress" , 0 , REG_SZ , (LPBYTE )IpAddress , strlen (IpAddress )+ 1 );
675+ RegSetValueExA (hkey , "DhcpSubnetMask" , 0 , REG_SZ , (LPBYTE )SubnetMask , strlen (SubnetMask )+ 1 );
676+ RegSetValueExA (hkey , "DhcpServer" , 0 , REG_SZ , (LPBYTE )Server , strlen (Server )+ 1 );
677+
678+ lease = 3600 ;
679+ RegSetValueExA (hkey , "Lease" , 0 , REG_DWORD , (LPBYTE )& lease , sizeof (DWORD ));
680+ RegSetValueExA (hkey , "LeaseObtainedTime" , 0 , REG_DWORD , (LPBYTE )& cur_time , sizeof (DWORD ));
681+ new_time = cur_time + lease ;
682+ RegSetValueExA (hkey , "LeaseTerminatesTime" , 0 , REG_DWORD , (LPBYTE )& new_time , sizeof (DWORD ));
683+ new_time = cur_time + (lease / 2 );
684+ RegSetValueExA (hkey , "T1" , 0 , REG_DWORD , (LPBYTE )& new_time , sizeof (DWORD ));
685+ new_time = cur_time + lease - (lease / 8 );
686+ RegSetValueExA (hkey , "T2" , 0 , REG_DWORD , (LPBYTE )& new_time , sizeof (DWORD ));
687+ }
688+
689+ if ( Adapter -> RouterMib .dwForwardNextHop ) {
690+ DeleteIpForwardEntry ( & Adapter -> RouterMib );
691+ }
692+
693+ if (hkey ) {
694+ RegDeleteValueA (hkey , "DhcpDefaultGateway" );
695+ }
696+
697+ if (hkey )
698+ RegCloseKey (hkey );
699+ }
700+
582701
583702void
584703bind_lease (struct interface_info * ip )
@@ -622,6 +741,28 @@ bind_lease(struct interface_info *ip)
622741 set_domain ( Adapter , new_lease );
623742}
624743
744+ void
745+ unbind_lease (struct interface_info * ip )
746+ {
747+ PDHCP_ADAPTER Adapter ;
748+
749+ if (ip -> client -> active ) {
750+ free_client_lease (ip -> client -> active );
751+ ip -> client -> active = NULL ;
752+ }
753+
754+ Adapter = AdapterFindInfo ( ip );
755+ if (Adapter ) {
756+ reset_adapter (Adapter );
757+ unset_name_servers (Adapter );
758+ unset_domain (Adapter );
759+ }
760+ else {
761+ warning ("Could not find adapter for info %p\n" , ip );
762+ return ;
763+ }
764+ }
765+
625766/*
626767 * state_bound is called when we've successfully bound to a particular
627768 * lease, but the renewal time on that lease has expired. We are
@@ -874,8 +1015,16 @@ packet_to_lease(struct packet *packet)
8741015 lease -> address .len = sizeof (packet -> raw -> yiaddr );
8751016 memcpy (lease -> address .iabuf , & packet -> raw -> yiaddr , lease -> address .len );
8761017#ifdef __REACTOS__
877- lease -> serveraddress .len = sizeof (packet -> raw -> siaddr );
878- memcpy (lease -> serveraddress .iabuf , & packet -> raw -> siaddr , lease -> address .len );
1018+ if (packet -> raw -> siaddr .S_un .S_addr == 0 )
1019+ {
1020+ lease -> serveraddress .len = packet -> client_addr .len ;
1021+ memcpy (lease -> serveraddress .iabuf , & packet -> client_addr .iabuf , packet -> client_addr .len );
1022+ }
1023+ else
1024+ {
1025+ lease -> serveraddress .len = sizeof (packet -> raw -> siaddr );
1026+ memcpy (lease -> serveraddress .iabuf , & packet -> raw -> siaddr , lease -> serveraddress .len );
1027+ }
8791028#endif
8801029
8811030 /* If the server name was filled out, copy it. */
@@ -1256,6 +1405,31 @@ send_decline(void *ipp)
12561405 inaddr_any , & sockaddr_broadcast , NULL );
12571406}
12581407
1408+ void
1409+ send_release (void * ipp )
1410+ {
1411+ struct interface_info * ip = ipp ;
1412+ struct sockaddr_in destination ;
1413+ struct in_addr from ;
1414+
1415+ memset (& destination , 0 , sizeof (destination ));
1416+ memcpy (& destination .sin_addr .s_addr ,
1417+ ip -> client -> destination .iabuf ,
1418+ sizeof (destination .sin_addr .s_addr ));
1419+ destination .sin_port = htons (REMOTE_PORT );
1420+ destination .sin_family = AF_INET ;
1421+
1422+ memcpy (& from , ip -> client -> active -> address .iabuf ,
1423+ sizeof (from ));
1424+
1425+ note ("DHCPRELEASE on %s to %s port %d" , ip -> name ,
1426+ inet_ntoa (destination .sin_addr ), ntohs (destination .sin_port ));
1427+
1428+ /* Send out a packet. */
1429+ (void ) send_packet (ip , & ip -> client -> packet , ip -> client -> packet_length ,
1430+ from , & destination , NULL );
1431+ }
1432+
12591433void
12601434make_discover (struct interface_info * ip , struct client_lease * lease )
12611435{
@@ -1515,6 +1689,70 @@ make_decline(struct interface_info *ip, struct client_lease *lease)
15151689 ip -> hw_address .haddr , ip -> hw_address .hlen );
15161690}
15171691
1692+ void
1693+ make_release (struct interface_info * ip , struct client_lease * lease )
1694+ {
1695+ struct tree_cache * options [256 ], message_type_tree ;
1696+ struct tree_cache server_id_tree , client_id_tree ;
1697+ unsigned char release = DHCPRELEASE ;
1698+ int i ;
1699+
1700+ memset (options , 0 , sizeof (options ));
1701+ memset (& ip -> client -> packet , 0 , sizeof (ip -> client -> packet ));
1702+
1703+ /* Set DHCP_MESSAGE_TYPE to DHCPRELEASE */
1704+ i = DHO_DHCP_MESSAGE_TYPE ;
1705+ options [i ] = & message_type_tree ;
1706+ options [i ]-> value = & release ;
1707+ options [i ]-> len = sizeof (release );
1708+ options [i ]-> buf_size = sizeof (release );
1709+ options [i ]-> timeout = 0xFFFFFFFF ;
1710+
1711+ /* Send back the server identifier... */
1712+ i = DHO_DHCP_SERVER_IDENTIFIER ;
1713+ options [i ] = & server_id_tree ;
1714+ options [i ]-> value = lease -> options [i ].data ;
1715+ options [i ]-> len = lease -> options [i ].len ;
1716+ options [i ]-> buf_size = lease -> options [i ].len ;
1717+ options [i ]-> timeout = 0xFFFFFFFF ;
1718+
1719+ /* Send the uid if the user supplied one. */
1720+ i = DHO_DHCP_CLIENT_IDENTIFIER ;
1721+ if (ip -> client -> config -> send_options [i ].len )
1722+ {
1723+ options [i ] = & client_id_tree ;
1724+ options [i ]-> value = ip -> client -> config -> send_options [i ].data ;
1725+ options [i ]-> len = ip -> client -> config -> send_options [i ].len ;
1726+ options [i ]-> buf_size = ip -> client -> config -> send_options [i ].len ;
1727+ options [i ]-> timeout = 0xFFFFFFFF ;
1728+ }
1729+
1730+ /* Set up the option buffer... */
1731+ ip -> client -> packet_length = cons_options (NULL , & ip -> client -> packet , 0 , options );
1732+ if (ip -> client -> packet_length < BOOTP_MIN_LEN )
1733+ ip -> client -> packet_length = BOOTP_MIN_LEN ;
1734+
1735+ ip -> client -> packet .op = BOOTREQUEST ;
1736+ ip -> client -> packet .htype = ip -> hw_address .htype ;
1737+ ip -> client -> packet .hlen = ip -> hw_address .hlen ;
1738+ ip -> client -> packet .hops = 0 ;
1739+ ip -> client -> packet .xid = 0 ;
1740+ ip -> client -> packet .secs = 0 ;
1741+ ip -> client -> packet .flags = 0 ;
1742+
1743+ /* ciaddr is the address to be released */
1744+ memcpy (& ip -> client -> packet .ciaddr ,
1745+ lease -> address .iabuf , lease -> address .len );
1746+ memset (& ip -> client -> packet .yiaddr , 0 ,
1747+ sizeof (ip -> client -> packet .yiaddr ));
1748+ memset (& ip -> client -> packet .siaddr , 0 ,
1749+ sizeof (ip -> client -> packet .siaddr ));
1750+ memset (& ip -> client -> packet .giaddr , 0 ,
1751+ sizeof (ip -> client -> packet .giaddr ));
1752+ memcpy (ip -> client -> packet .chaddr ,
1753+ ip -> hw_address .haddr , ip -> hw_address .hlen );
1754+ }
1755+
15181756void
15191757free_client_lease (struct client_lease * lease )
15201758{
0 commit comments