AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Host to Ip Address, using Winsock 2.0 dll

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Tasman



Joined: 20 May 2006
Posts: 21

PostPosted: Sat May 20, 2006 2:34 pm    Post subject: Host to Ip Address, using Winsock 2.0 dll Reply with quote

This function gets the IP address for the given host directly using the WinSock 2.0 dll, without using temp files or third party utilities.
Multiple addresses are returned, seperated by a newline, if available.

Note! If a domain has no dedicated IP address because it is run from a server using virtual hosts the IP address of the server is returned.

The script below is fully functional as given, just copy and paste it (beware of line breaks) into a script file.
(largely based on functions from the WinLirc script and various other posts in this forum)
Code:
 
NodeName = www.google.com
IPs := HostToIp(NodeName)
DllCall("Ws2_32\WSACleanup") ; always inlude this line after calling to release the socket connection
if IPs <> -1 ; no error occurred
   Msgbox, %NodeName%`n%IPs%
else
   MsgBox, Host "%NodeName%" not found

HostToIp(NodeName) ; returns -1 if unsuccessfull or a newline seperated list of valid IP addresses on success
{
   VarSetCapacity(wsaData, 32)  ; The struct is only about 14 in size, so 32 is conservative.
   result := DllCall("Ws2_32\WSAStartup", "UShort", 0x0002, "UInt", &wsaData) ; Request Winsock 2.0 (0x0002)
   if ErrorLevel   ; check ErrorLevel to see if the OS has Winsock 2.0 available:
   {
      MsgBox WSAStartup() could not be called due to error %ErrorLevel%. Winsock 2.0 or higher is required.
      return -1
   }
   if result  ; Non-zero, which means it failed (most Winsock functions return 0 on success).
   {
      MsgBox % "WSAStartup() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") ; %
      return -1
   }
   PtrHostent := DllCall("Ws2_32\gethostbyname", str, Nodename)
   if (PtrHostent = 0)
      Return -1
   VarSetCapacity(hostent,16,0)
   DllCall("RtlMoveMemory",UInt,&hostent,UInt,PtrHostent,UInt,16) 
   h_name      := ExtractInteger(hostent,0,false,4)
   h_aliases   := ExtractInteger(hostent,4,false,4)
   h_addrtype  := ExtractInteger(hostent,8,false,2)
   h_length    := ExtractInteger(hostent,10,false,2)
   h_addr_list := ExtractInteger(hostent,12,false,4)
   ; Retrieve official name
   VarSetCapacity(Name,64,0)
   DllCall("RtlMoveMemory",UInt,&Name,UInt,h_name,UInt,64)
   ; Retrieve Aliases
   VarSetCapacity(Aliases,12,0)
   DllCall("RtlMoveMemory", UInt, &Aliases, UInt, h_aliases, UInt, 12)
   Loop, 3
   {
      offset := ((A_Index-1)*4)
      PtrAlias%A_Index% := ExtractInteger(Aliases,offset,false,4)
      If (PtrAlias%A_Index% = 0)
         break
      VarSetCapacity(Alias%A_Index%,64,0)
      DllCall("RtlMoveMemory",UInt,&Alias%A_Index%,UInt,PtrAlias%A_Index%,Uint,64)
   }
   VarSetCapacity(AddressList,12,0)
   DllCall("RtlMoveMemory",UInt,&AddressList,UInt,h_addr_list,UInt,12)
   Loop, 3
   {
      offset := ((A_Index-1)*4)
      PtrAddress%A_Index% := ExtractInteger(AddressList,offset,false,4)
      If (PtrAddress%A_Index% =0)
         break
      VarSetCapacity(address%A_Index%,4,0)
      DllCall("RtlMoveMemory" ,UInt,&address%A_Index%,UInt,PtrAddress%A_Index%,Uint,4)
      i := A_Index
      Loop, 4
      {
         if Straddress%i%
            Straddress%i% := Straddress%i% "." ExtractInteger(address%i%,(A_Index-1 ),false,1)
         else
            Straddress%i% := ExtractInteger(address%i%,(A_Index-1 ),false,1)
      }
      Straddress0 = %i%
   }
   loop, %Straddress0% ; put them together and return them
   {
      _this := Straddress%A_Index%
      if _this <>
         IPs = %IPs%%_this%
      if A_Index = %Straddress0%
         break
      IPs = %IPs%`n
   }
   return IPs
}
ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
{
   Loop %pSize%
     result += *(&pSource+pOffset+A_Index-1) << 8*A_Index-8
   Return result
}


Last edited by Tasman on Sat May 20, 2006 5:17 pm; edited 1 time in total
Back to top
View user's profile Send private message
corrupt



Joined: 29 Dec 2004
Posts: 2436

PostPosted: Sat May 20, 2006 3:52 pm    Post subject: Reply with quote

Thanks for sharing Smile . Please use the [code] [/code] tags when posting code.
Back to top
View user's profile Send private message Visit poster's website
Tasman



Joined: 20 May 2006
Posts: 21

PostPosted: Sat May 20, 2006 5:19 pm    Post subject: Reply with quote

Sorry didn't realize that was possible, this was my first posting Very Happy
Back to top
View user's profile Send private message
corrupt



Joined: 29 Dec 2004
Posts: 2436

PostPosted: Sat May 20, 2006 6:03 pm    Post subject: Reply with quote

Thanks and welcome Smile
Back to top
View user's profile Send private message Visit poster's website
SKAN



Joined: 26 Dec 2005
Posts: 6264

PostPosted: Sat May 20, 2006 6:24 pm    Post subject: Reply with quote

Dear Tasman, Very Happy

Thanks! A very useful utility! Very Happy Very Happy

Regards, Smile

PS: I tested it for www.autohotkey.com and the result: http://205.234.198.215/

Edit: 01 June 2006
I tested it for www.autohotkey.com and the result: http://209.59.172.74/
_________________


Last edited by SKAN on Thu Jun 01, 2006 5:35 am; edited 1 time in total
Back to top
View user's profile Send private message
evl



Joined: 24 Aug 2005
Posts: 1239

PostPosted: Sat May 20, 2006 8:45 pm    Post subject: Reply with quote

Interesting script. Talk about diving in at the deep end for your first post Laughing
Back to top
View user's profile Send private message
Tasman



Joined: 20 May 2006
Posts: 21

PostPosted: Sat May 20, 2006 9:41 pm    Post subject: Reply with quote

I'd love to take full credit for all of it, but I have to admit most of the work was done by others here.
I just put various bits and pieces from everywhere together.

It might have been my first post but I have been using AHK for a while now.

I have started posting now, because other then setting hotkeys etc., I am now actually doing (trying to do) something more eleborate.
Out of curiousity and as a hobby I'm trying to write a (very) minimalist shell for windows in AHK.
The idea is to have virtually all the functionality of the explorer shell available within one single script and menu, accessable from a hotkey.
No visual candy, or fancy effects and skins, but something basic and small, leaving memory and resources free for actual work.
Most of my posts will be routines and functions made for that purpose, untill mostly ready, and I will post the whole script.
Back to top
View user's profile Send private message
corrupt



Joined: 29 Dec 2004
Posts: 2436

PostPosted: Sat May 20, 2006 10:28 pm    Post subject: Reply with quote

@Tasman: You wouldn't have an Hostname from IP script kicking around would you?
Back to top
View user's profile Send private message Visit poster's website
Guest






PostPosted: Sun May 21, 2006 2:49 pm    Post subject: Reply with quote

No not yet.
I'l have a look in the next few days if I can put one together.
Back to top
Tasman



Joined: 20 May 2006
Posts: 21

PostPosted: Tue May 23, 2006 7:34 pm    Post subject: Reply with quote

I just the found post again where virtually all the code came from.
It was a post by darvik http://www.autohotkey.com/forum/topic8871.html&highlight=gethostbyname.
I just made small changes as I did with the function from the winlirc script.

I am researching an IP to host script, but as I know little of sockets it is a learning experience in the first place.

As mentioned before there is a gethostbyaddr function, Im playing with it but haven't been able to entice something workable from it (yet)


Last edited by Tasman on Tue May 23, 2006 7:51 pm; edited 1 time in total
Back to top
View user's profile Send private message
Tasman



Joined: 20 May 2006
Posts: 21

PostPosted: Tue May 23, 2006 7:49 pm    Post subject: Reply with quote

The gethost byaddr function needs an IP adrress as a long integer, as far as I can tell the following dllcall should facilitate this conversion.

Netadd := DllCall("Ws2_32\inet_addr", "Str", IPAddress)

The gethost byaddr function itself returns a hostent structure in the same way as gethostbyname does so we should be able to reuse a lot of Darvik's code.

Any help is appreciated Laughing


Last edited by Tasman on Tue May 23, 2006 9:53 pm; edited 1 time in total
Back to top
View user's profile Send private message
Tasman



Joined: 20 May 2006
Posts: 21

PostPosted: Tue May 23, 2006 8:08 pm    Post subject: Reply with quote

Just in case anybody else out there is looking for info on sockets this is a great resource http://www.sockets.com/
Back to top
View user's profile Send private message
Tasman



Joined: 20 May 2006
Posts: 21

PostPosted: Tue May 23, 2006 9:14 pm    Post subject: Get local ip numbers Reply with quote

In my so far unsuccessfull quest for an ip to host script, I (erroneously/accidentally) came up with the following function, it faithfully returns the Ip addresses of the machine you are working on.
Thought I might just as well post it maybe somebody can use it.
I left in but commented out some of the lines I used to debug, sorry its a bit messy.

Again there are only small changes to the code posted above.


Code:
IPs := LocalIps()
DllCall("Ws2_32\WSACleanup") ; always inlude this line after calling to release the socket connection
Msgbox, %IPs% 

LocalIps() ; returns -1 if unsuccessfull or a newline seperated list of valid IP addresses on success
{
   VarSetCapacity(wsaData, 32)  ; The struct is only about 14 in size, so 32 is conservative.
   result := DllCall("Ws2_32\WSAStartup", "UShort", 0x0002, "UInt", &wsaData) ; Request Winsock 2.0 (0x0002)
   if ErrorLevel   ; check ErrorLevel to see if the OS has Winsock 2.0 available:
   {
      MsgBox WSAStartup() could not be called due to error %ErrorLevel%. Winsock 2.0 or higher is required.
      return -1
   }
   if result  ; Non-zero, which means it failed (most Winsock functions return 0 on success).
   {
      MsgBox % "WSAStartup() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") ; %
      return -1
   }
   ; convert ip to Inet Address
   Inet_address := DllCall("Ws2_32\inet_addr", Str, "0") 
   PtrHostent := DllCall("Ws2_32\gethostbyaddr", "int *", %Inet_address%, "int", 4, "int", 2)     
   if (PtrHostent = 0)
      Return -1
   VarSetCapacity(hostent,16,0)
   DllCall("RtlMoveMemory",UInt,&hostent,UInt,PtrHostent,UInt,16) 
   h_addr_list := ExtractInteger(hostent,12,false,4)

   VarSetCapacity(AddressList,12,0)
   DllCall("RtlMoveMemory",UInt,&AddressList,UInt,h_addr_list,UInt,12)
   Loop, 3
   {
      offset := ((A_Index-1)*4)
      PtrAddress%A_Index% := ExtractInteger(AddressList,offset,false,4)
      If (PtrAddress%A_Index% =0)
         break
      VarSetCapacity(address%A_Index%,4,0)
      DllCall("RtlMoveMemory" ,UInt,&address%A_Index%,UInt,PtrAddress%A_Index%,Uint,4)
      i := A_Index
      Loop, 4
      {
         if Straddress%i%
            Straddress%i% := Straddress%i% "." ExtractInteger(address%i%,(A_Index-1 ),false,1)
         else
            Straddress%i% := ExtractInteger(address%i%,(A_Index-1 ),false,1)
      }
      Straddress0 = %i%
   }
   loop, %Straddress0% ; put them together and return them
   {
      _this := Straddress%A_Index%
      if _this <>
         IPs = %IPs%%_this%
      if A_Index = %Straddress0%
         break
      IPs = %IPs%`n
   }
   return IPs
}
ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
{
   Loop %pSize%
     result += *(&pSource+pOffset+A_Index-1) << 8*A_Index-8
   Return result
}


Last edited by Tasman on Tue May 23, 2006 10:29 pm; edited 1 time in total
Back to top
View user's profile Send private message
Tasman



Joined: 20 May 2006
Posts: 21

PostPosted: Tue May 23, 2006 9:48 pm    Post subject: Reply with quote

Just edited the localip post above with cleaned up code.
Back to top
View user's profile Send private message
ParanoidX



Joined: 16 Dec 2005
Posts: 149
Location: Australia

PostPosted: Thu Jun 01, 2006 5:29 am    Post subject: Reply with quote

I tested the script and it simply return 0.

WinXP SP2.
_________________

546F206C69766520
6973204368726973742C0D746F2064696520
6973206761696E2E0D285068696C20313A323129
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group