amel27 Posted June 22, 2008 Share Posted June 22, 2008 (edited) expandcollapse popup#include <Date.au3> ;=============================================================================== ; ; Description: Get DHCP Client Attributes by IP Address, MAC or Name ; Parameter(s): $sDHCP - IP Address of DHCP Server ; $ClientID - Client IP, MAC or Name (String or Native Format) ; Integer - native format for IP Address/Mask ; Binary - native format for MAC Address (6 bytes) ; $iIDType - type of ClientID information: ; 0 - Auto-define by value ; 1 - Client IP address ; 2 - Client Hardware (MAC) address ; 3 - Client Name ; $iFlags - Config Flags: ; 0x1- Output Format (0-Text, 1-Native) ; Requirement(s): Testing ; Return Value(s): On Success - The array of parameters with indexes ; 0 - Client IP address ; 1 - Client IP subnet mask ; 2 - Client MAC address ; 3 - Client Name ; 4 - Client Comment ; 5 - Client Lease Expires Time ; On Failure - Null, @error set to ; 1 - Client not found on DHCP server ; 2 - Invalid ClientID parameter ; 3 - Operating System not supported ; 4 - Any Runtime Error, API Error Code set to @extended ; Author(s): amel27 (Alexander Melnichuk) ; Note(s): Client Name is case sensitive ; ;=============================================================================== Func _DHCP_GetClientInfo($sDHCP, $ClientID, $iIDType=0, $iFlags=0) ; Create DHCP_SEARCH_INFO Structure Local $tSearchInfo= DllStructCreate("int SearchType;int DataLength;ptr DataPtr") Local $iSearchInfoPtr = DllStructGetPtr($tSearchInfo), $aSubnets[2]=[1,0], $iType=0 Local $tBinaryData = DllStructCreate("dword SubnetIPAddress;ubyte HardwareID;ubyte MACAddress[6]") ; Check Client ID Parameter and Define SearchInfo Type If IsInt($ClientID) Then If $iIDType=0 Or $iIDType=1 Then $iType = 1 ElseIf IsBinary($ClientID) Then If BinaryLen($ClientID)=6 And ($iIDType=0 Or $iIDType=2) Then $iType = 2 ElseIf IsString($ClientID) Then If StringRegExp($ClientID, "^(\d+\.){3}\d+$") Then ; Get IP DWord type from String Local $aOctets = StringSplit($ClientID, "."), $iClientIP = 0 For $i=1 To 4 If BitAND($aOctets[$i], 0xFFFFFF00) Then Return SetError(2) ; ERR: Invalid Client IP Address $iClientIP = BitOR(BitRotate($iClientIP, 8, "D"), $aOctets[$i]) Next $ClientID = $iClientIP If $iIDType=0 Or $iIDType=1 Then $iType = 1 ElseIf StringRegExp($ClientID,"^(0[xX])?[[:xdigit:]]{2}((:|-)?[[:xdigit:]]{2}){5}$") Then $ClientID = Binary("0x"& StringRegExpReplace($ClientID,"(0[xX]|:|-)","")) If $iIDType=0 Or $iIDType=2 Then $iType = 2 Else If $iIDType=0 Or $iIDType=3 Then $iType = 3 EndIf EndIf If $iType =0 Then Return SetError(2) ; Route the filling of DHCP_SEARCH_INFO structure Switch $iType Case 1 ; Filling DHCP_SEARCH_INFO for search by client IP address Local $tSearchInfo_IP = DllStructCreate("int SearchType;dword ClientIPAddress", $iSearchInfoPtr) DllStructSetData($tSearchInfo_IP, "SearchType", 0) DllStructSetData($tSearchInfo_IP, "ClientIPAddress", $ClientID) Case 2 ; Filling DHCP_SEARCH_INFO for search by client MAC address DllStructSetData($tSearchInfo, "SearchType", 1) DllStructSetData($tSearchInfo, "DataLength", 11) DllStructSetData($tSearchInfo, "DataPtr", DllStructGetPtr($tBinaryData)) ; Filling DHCP_BINARY_DATA DllStructSetData($tBinaryData, "HardwareID", 0x01) DllStructSetData($tBinaryData, "MACAddress", $ClientID) ; Get Array of DHCP Subnets $aSubnets = _DHCP_EnumSubnets($sDHCP, 1) If @error=1 Then Return SetError(1) If @error=2 Then Return SetError(4, @extended) Case 3 ; Filling DHCP_SEARCH_INFO for search by client Name Local $tSearchInfo_Name = DllStructCreate("int SearchType;ptr ClientNamePtr", $iSearchInfoPtr) Local $tClientNameString= DllStructCreate("wchar ClientName["& StringLen($ClientID)+1 &"]") DllStructSetData($tSearchInfo_Name, "SearchType", 2) DllStructSetData($tSearchInfo_Name, "ClientNamePtr", DllStructGetPtr($tClientNameString)) DllStructSetData($tClientNameString, "ClientName", $ClientID) EndSwitch ; Call DhcpGetClientInfo API function Local $tClientInfo_Ptr = DllStructCreate("ptr"), $aRet, $aRes[6] For $i=1 To $aSubnets[0] DllStructSetData($tBinaryData, "SubnetIPAddress", $aSubnets[$i]) $aRet = DllCall("Dhcpsapi.dll", "int", "DhcpGetClientInfo", _ "wstr", $sDHCP, _ "ptr", $iSearchInfoPtr, _ "ptr", DllStructGetPtr($tClientInfo_Ptr) ) If @error Then Return SetError(3, @error) ; ERR: Invalid DLL or Function Name If $aRet[0]<>20013 Then ExitLoop Next If $aRet[0]=20013 Then Return SetError(1, $aRet[0]) ; ERR: Client not found If $aRet[0] Then Return SetError(4, $aRet[0]) ; ERR: Any runtime errors ; DHCP_CLIENT_INFO structure Local $tClientInfo = DllStructCreate("dword ClientIpAddress;dword SubnetMask;int BinaryLen;ptr BinaryPtr;" & _ "ptr ClientNamePtr;ptr ClientCommentPtr;ubyte ClientLeaseExpires[8];dword OwnerHostIPAddress;" & _ "ptr OwnerHostNetBiosNamePtr;ptr OwnerHostNamePtr", DllStructGetData($tClientInfo_Ptr,1)) Local $tClientBinary = DllStructCreate("ubyte BinaryData[6]", DllStructGetData($tClientInfo, "BinaryPtr")) ; Get IP Address $aRes[0] = DllStructGetData($tClientInfo, "ClientIpAddress") If BitAND($iFlags,1)=0 Then $aRes[0] = BitRotate(BitAND($aRes[0],0xFF000000), 8,"D") &"."& _ BitRotate(BitAND($aRes[0],0x00FF0000),16,"D") &"."& _ BitRotate(BitAND($aRes[0],0x0000FF00),-8,"W") &"."& BitAND($aRes[0],0x000000FF) ; Get IP Mask $aRes[1] = DllStructGetData($tClientInfo, "SubnetMask") If BitAND($iFlags,1)=0 Then $aRes[1]=BitRotate(BitAND($aRes[1],0xFF000000), 8,"D") &"."& _ BitRotate(BitAND($aRes[1],0x00FF0000),16,"D") &"."& _ BitRotate(BitAND($aRes[1],0x0000FF00),-8,"W") &"."& BitAND($aRes[1],0x000000FF) ; Get MAC Address $aRes[2] = DllStructGetData($tClientBinary, "BinaryData") If BitAND($iFlags,1)=0 Then $aRes[2] = String($aRes[2]) ; Get Client Name Local $tClientNameString = DllStructCreate("wchar ClientName[255]", DllStructGetData($tClientInfo, "ClientNamePtr")) $aRes[3] = DllStructGetData($tClientNameString, "ClientName") ; Get Client Comment Local $tClientNameString = DllStructCreate("wchar ClientComment[255]", DllStructGetData($tClientInfo, "ClientCommentPtr")) $aRes[4] = DllStructGetData($tClientNameString, "ClientComment") ; Get Client Lease Expire Time $aRes[5] = DllStructGetData($tClientInfo, "ClientLeaseExpires") If BitAND($iFlags,1)=0 Then $aRes[5] = _Date_Time_FileTimeToLocalFileTime(DllStructGetPtr($tClientInfo, "ClientLeaseExpires")) $aRes[5] = _Date_Time_FileTimeToStr($aRes[5]) EndIf ; Freeing a memory DllCall("Dhcpsapi.dll", "none", "DhcpRpcFreeMemory", "ptr", DllStructGetData($tClientInfo_Ptr,1)) Return $aRes EndFunc ;==> _DHCP_GetClientInfo ;=============================================================================== ; ; Description: Get List of DHCP Scopes ; Parameter(s): $sDHCP - IP Address of DHCP Server ; $iFlags - Config Flags: ; 0x1- Output Format (0-Text, 1-Native) ; Requirement(s): Testing ; Return Value(s): On Success - The array subnet of IP Addresses ; element with index 0 is count of scopes ; On Failure - @error set to ; 1 - Scopes not defined, returned empty array ; 2 - Any Runtime Error, invalid array, ; API Error Code set to @extended ; Author(s): amel27 (Alexander Melnichuk) ; Note(s): ; ;=============================================================================== Func _DHCP_EnumSubnets($sDHCP, $iFlags=0) Local $tEnumSubnetsParms = DllStructCreate("hwnd ResumeHandle;ptr EnumInfoPtr;int ElementsRead;int ElementsTotal") Local $aSubnets[1]=[0], $tIPArray, $tAddress, $aRet Do $aRet = DllCall("Dhcpsapi.dll", "int", "DhcpEnumSubnets", _ "wstr", $sDHCP, _ "ptr" , DllStructGetPtr($tEnumSubnetsParms, "ResumeHandle"), _ "int", 100, _ "ptr" , DllStructGetPtr($tEnumSubnetsParms, "EnumInfoPtr") , _ "ptr" , DllStructGetPtr($tEnumSubnetsParms, "ElementsRead"), _ "ptr" , DllStructGetPtr($tEnumSubnetsParms, "ElementsTotal") ) If $aRet[0] Then Return SetError(2, $aRet[0]) ; ERR: Any runtime errors If DllStructGetData($tEnumSubnetsParms,"EnumInfoPtr")=0 Then Return SetError(1, 0, $aSubnets) ; ERR: Not Found $tIPArray = DllStructCreate("int NumElements;ptr Elements", DllStructGetData($tEnumSubnetsParms,"EnumInfoPtr")) ReDim $aSubnets[$aSubnets[0] + DllStructGetData($tIPArray,"NumElements") +1] For $i=$aSubnets[0]+1 To UBound($aSubnets)-1 $tAddress = DllStructCreate("dword SubNetAddess", DllStructGetData($tIPArray,2) + ($i-$aSubnets[0]-1)*4) $aSubnets[$i]=DllStructGetData($tAddress, "SubNetAddess") If BitAND($iFlags,1)=0 Then $aSubnets[$i] = BitRotate(BitAND($aSubnets[$i],0xFF000000), 8,"D") _ &"."& BitRotate(BitAND($aSubnets[$i],0x00FF0000),16,"D") _ &"."& BitRotate(BitAND($aSubnets[$i],0x0000FF00),-8,"W") _ &"."& BitAND($aSubnets[$i],0x000000FF) Next $aSubnets[0] += DllStructGetData($tIPArray,"NumElements") Until DllStructGetData($tEnumSubnetsParms,"ElementsRead") = DllStructGetData($tEnumSubnetsParms,"ElementsTotal") ; Freeing a memory DllCall("Dhcpsapi.dll", "none", "DhcpRpcFreeMemory", "ptr", DllStructGetData($tEnumSubnetsParms,"EnumInfoPtr")) Return $aSubnets EndFunc ; => _DHCP_EnumSubnets Edited June 24, 2008 by amel27 mLipok 1 Link to comment Share on other sites More sharing options...
amel27 Posted June 23, 2008 Author Share Posted June 23, 2008 - add new optional parameter "Type of Search Info" for strong typing - add supported of Native data format for quick exchange with others API functions: "Int" (aka "dword") for IP Address/Mask "Binary" for Hardware (MAC) address Link to comment Share on other sites More sharing options...
rasim Posted June 23, 2008 Share Posted June 23, 2008 amel27Welcome back! Useful UDF, thanks! Link to comment Share on other sites More sharing options...
amel27 Posted June 23, 2008 Author Share Posted June 23, 2008 Welcome back! Useful UDF, thanks!thx devide one huge UDF into two more readable Link to comment Share on other sites More sharing options...
amel27 Posted June 24, 2008 Author Share Posted June 24, 2008 - add returning of client Lease Expires Time Attribute; - _DHCP_EnumSubnets() support unlimited scopes Link to comment Share on other sites More sharing options...
Mojo Posted June 30, 2008 Share Posted June 30, 2008 Thanks for sharing. But could you please provide examples on how to call those functions? I tried a few things, but nothing worked. Local $ret = _DHCP_GetClientInfo("10.200.201.10", "Computer1") If @error Then MsgBox(0,"error & extended", @error & " " & @extended) _ArrayDisplay($ret) everything I tried errors out with @error = 4 and @extended = 5 Instead of "Computer1" I also tried an IP address, but that didn't work either. any hint would be helpful cheers You can fool some of the people all of the time, and all of the people some of the time, but you can not fool all of the people all of the time. Abraham Lincoln - http://www.ae911truth.org/ - http://www.freedocumentaries.org/ Link to comment Share on other sites More sharing options...
dleigh Posted September 18, 2008 Share Posted September 18, 2008 Would this NOT work if the DHCP server is on a Linux box (i.e. Autoit3 on Windows querying the DHCP server on Linux)? Thanks! Link to comment Share on other sites More sharing options...
amel27 Posted October 10, 2008 Author Share Posted October 10, 2008 MojoERROR 5: "Access is denied", see System Error CodesdleighThis UDF use Microsoft DHCP API, therefore it work only with Windows DHCP servers, this API work via RPC and requires sufficient rights on DHCP server. Link to comment Share on other sites More sharing options...
ludocus Posted October 10, 2008 Share Posted October 10, 2008 very usefull.. thank you! Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now