Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

IP Helper Functions - Getting started with Iphlpapi.dll


  • Please log in to reply
7 replies to this topic
olfen
  • Members
  • 115 posts
  • Last active: Dec 25 2012 09:48 AM
  • Joined: 04 Jun 2005
IP2MAC(IP){
;http://msdn.microsoft.com/library/en-us/iphlp/iphlp/sendarp.asp
VarSetCapacity(ip_ulong, 4, 0)
ip_ulong := DllCall("Ws2_32.dll\inet_addr", "str", ip)
VarSetCapacity(pMacAddr, 6, 0)
PhyAddrLen=6
r := DllCall("Iphlpapi.dll\SendARP", "uint", ip_ulong, "uint", 0, "uint", &pMacAddr, "uint", &PhyAddrLen)
IfNotEqual, r, 0, return 0
int_format := A_FormatInteger
SetFormat, Integer, Hex
Loop, 6 {
  t := *(&pMacAddr + A_Index-1)
  StringTrimLeft, t, t, 2
  t=0%t%
  StringRight, t, t, 2
  res=%res%:%t%
}
StringTrimLeft, res, res, 1
StringUpper, res, res
SetFormat, Integer, %int_format%
Return, res
}

Ping(IP, MaxHops=30) {
;http://msdn.microsoft.com/library/en-us/iphlp/iphlp/getrttandhopcount.asp
VarSetCapacity(ip_ulong, 4, 0)
ip_ulong := DllCall("Ws2_32.dll\inet_addr", "str", ip)
VarSetCapacity(HopCount, 4, 0)
VarSetCapacity(RTT, 4, 0)
r := DllCall("Iphlpapi.dll\GetRTTAndHopCount", "UInt", ip_ulong, "UInt", &HopCount, "UInt", MaxHops, "UInt", &RTT)
If  (r > 0) {
  Loop, 4 {
      rRTT += *(&RTT + A_Index-1) << 8*(A_Index-1)
      rHopCount += *(&HopCount + A_Index-1) << 8*(A_Index-1)
    }
  IfEqual, rRTT, 0, return, "localhost"
  return rRTT
  } else {
  return r
  }
}

Sample code:
;show MAC addresses of the given IPs
Loop, 4 {
ip := A_IpAddress%a_index%
msgbox % "IP: " . ip . "`nMAC: " . ip2mac(ip)
}

;ping google.com
msgbox % Ping("64.233.187.99")

Edit: Changed Ping to return "localhost" when the round trip time equals zero (rHopCount is 1 in this case). Thanks corrupt.

Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
There have been several requests for a way to get the MAC address. This seems quite suitable.

Thanks for posting it.

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004
Nice :) . The sample provided seems to work but the following example doesn't:
;show MAC address for localhost 

ip := "127.0.0.1" 

msgbox % "IP: " . ip . "`nMAC: " . ip2mac(ip) 



;ping localhost 

msgbox % Ping("127.0.0.1")


olfen
  • Members
  • 115 posts
  • Last active: Dec 25 2012 09:48 AM
  • Joined: 04 Jun 2005

Nice :) . The sample provided seems to work but the following example doesn't:

;show MAC address for localhost 
ip := "127.0.0.1" 
msgbox % "IP: " . ip . "`nMAC: " . ip2mac(ip) 

;ping localhost 
msgbox % Ping("127.0.0.1")

Actually Ping("127.0.0.1") does work. But the return value (0), which is the round trip time, is misleading. I changed the function to return "localhost", when rRTT equals 0.

I will look into why ip2mac("127.0.0.1") is not working later, but my first guess is that it is due to the fact, that 127.0.0.1 is not by default explicitly assigned to the local network adapters (see ipconfig /all).

corrupt
  • Members
  • 2558 posts
  • Last active: Nov 01 2014 03:23 PM
  • Joined: 29 Dec 2004

Actually Ping("127.0.0.1") does work. But the return value (0), which is the round trip time, is misleading. I changed the function to return "localhost", when rRTT equals 0.

Hmm... That doesn't sound like a good idea since I also get 0 if I ping my gateway. Would it be possible to give a more accurate response time instead? Also, if the device does not respond (or doesn't exist) then the script hangs completely.

I will look into why ip2mac("127.0.0.1") is not working later, but my first guess is that it is due to the fact, that 127.0.0.1 is not by default explicitly assigned to the local network adapters (see ipconfig /all).

I guess it makes sense that localhost wouldn't return a mac address since a loopback wouldn't have one...

olfen
  • Members
  • 115 posts
  • Last active: Dec 25 2012 09:48 AM
  • Joined: 04 Jun 2005

Actually Ping("127.0.0.1") does work. But the return value (0), which is the round trip time, is misleading. I changed the function to return "localhost", when rRTT equals 0.

Hmm... That doesn't sound like a good idea since I also get 0 if I ping my gateway. Would it be possible to give a more accurate response time instead?

Valid point, but I think, using this function, there is no way to discriminate where the echo came from when rRTT is 0 and rHopCount is 1.

Also, if the device does not respond (or doesn't exist) then the script hangs completely.

I found no reliable method to avoid this.

Turning away from GetRTTAndHopCount seems a good advice to me.
IcmpSendEcho looks more promising (it has a timeout option and gives more info on the replies).

Edit: Removed some nonsense I had posted. :oops:

skrommel
  • Members
  • 193 posts
  • Last active: Jun 07 2010 08:30 AM
  • Joined: 30 Jul 2004
Wonderful! I've been hoping for this for a long time! Nice work on these network functions, olen!

Skrommel

olfen
  • Members
  • 115 posts
  • Last active: Dec 25 2012 09:48 AM
  • Joined: 04 Jun 2005
Thanks, Skrommel.
But you should definitively refrain from using "Ping" (see corrupt's post).