AutoHotkey Community

It is currently May 27th, 2012, 1:37 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 43 posts ]  Go to page Previous  1, 2, 3
Author Message
 Post subject:
PostPosted: March 25th, 2010, 8:40 pm 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
nice.
I would appreciate it if you rename the functions, If I am allowed to add the library into my collection for republishing. I think, in the current form the names are unluckily chosen. They all should have a consistent prefix to work with the stdlib mechanism and prevent collision with other functions without a prefix. And the one prefix A_ collides with another library I already added. Also the A_ does not mean anything at this point. And I suggest to name the main function for the end user to ping(), and all other helper functions with an added prefix ping_. That makes it clear and easy to remember. The file would be named to ping.ahk.

in example:
Code:
ping()    ; shortcut for user, formerly known as A_ping()
ping_()    ; main routine for internal use, formerly known as ping()
ping_GetError()
ping_Host2IP()
ping_DW2IP()


If you do not want to change the names, whatever the reason is, am I allowed todo that and republish the changed version?

(also I would like to see a license text or term^^ and a documentation, sorry hope its ok if I ask)

_________________
{1:"ahkstdlib", 2:"my libs", 3:"my apps", 4:"my license"}
--> Don't feed the troll! <--


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 26th, 2010, 3:35 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
Thank you for the interest, Tuncay. This script is of course free to change and republish for everyone, as per the AHK license. Dunno when I will be able to publish the modified version - could be in a week or two, whenever I get around changing the code and getting back here to uploading it - but you're welcome to perform the required changes for your collection, if time is of essence.

The reason I chose to name it A_Ping is simply because I thought one day it might've been added to AHK as a built-in function (wishful thinking, I know... :roll: ) and at that point no changes to existing scripts would have been required. Since that's unlikely to happen, I think the names you provided would be more than reasonable and will see to changing the script accordingly when I get to it.

As for the documentation, I'll see what I can provide, considering no Internet access at my new home. License, as mentioned before, is same as AutoHotkey's.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 26th, 2010, 5:14 pm 
Offline

Joined: June 17th, 2008, 7:51 am
Posts: 243
Hi Drugwash,
there is no built-in function which is called "A_***". Only built-in variables have this nomenclature.

_________________
Greetings
Rog


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 31st, 2010, 3:09 am 
Offline

Joined: November 8th, 2009, 2:46 am
Posts: 234
Location: Canberra Oz
infogulch wrote:
Cool!

Do you have a function for getting the information from the ICMP_ECHO_REPLY struct?

e.g. ICMP_ECHO_REPLY(adr, ByRef Address = "", ByRef Status = "" ... )

I wouldn't know how to implement it, or I would have posted it instead.

I thought this may be helpful to someone
Code:
; Results
ICMP_ECHO_IPAddress:=NumGet(reply, 0, "UInt") ;
ICMP_ECHO_Status:=NumGet(reply, 4, "UInt") ;
ICMP_ECHO_RoundTripTime:=NumGet(reply, 8, "UInt") ; 
ICMP_ECHO_DataSize:=NumGet(reply, 12, "UShort") ;
; Offset 14-15 Reserved, 16+Data
;

; Status Values
; Usage example
;   err:=A_Ping(...)
;   If (ErrorLevel) {
;      If  ( err=ICMP_ECHO_IP_HW_ERROR )
;         MsgBox, Your stuffed mate
ICMP_ECHO_IP_BUF_TOO_SMALL=11001
ICMP_ECHO_IP_DEST_NET_UNREACHABLE=11002
ICMP_ECHO_IP_DEST_HOST_UNREACHABLE=11003
ICMP_ECHO_IP_DEST_PROT_UNREACHABLE=11004
ICMP_ECHO_IP_DEST_PORT_UNREACHABLE=11005
ICMP_ECHO_IP_NO_RESOURCES=11006
ICMP_ECHO_IP_BAD_OPTION=11007
ICMP_ECHO_IP_HW_ERROR=11008
ICMP_ECHO_IP_PACKET_TOO_BIG=11009
ICMP_ECHO_IP_REQ_TIMED_OUT=11010
ICMP_ECHO_IP_BAD_REQ=11011
ICMP_ECHO_IP_BAD_ROUTE=11012
ICMP_ECHO_IP_TTL_EXPIRED_TRANSIT=11013
ICMP_ECHO_IP_TTL_EXPIRED_REASSEM=11014
ICMP_ECHO_IP_PARAM_PROBLEM=11015
ICMP_ECHO_IP_SOURCE_QUENCH=11016
ICMP_ECHO_IP_OPTION_TOO_BIG=11017
ICMP_ECHO_IP_BAD_DESTINATION=11018
ICMP_ECHO_IP_GENERAL_FAILURE=11050


If anyone can code the extraction of the Data field and/or the IP_OPTION_INFORMATION, PM me and I'll edit this (with credits :) ) to keep it in one spot.

My thinking cap is too tight at the moment. :shock:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 2nd, 2010, 9:26 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
ruespe wrote:
Hi Drugwash,
there is no built-in function which is called "A_***". Only built-in variables have this nomenclature.
Oh well, I must've thought too much in advance (or whatever). :oops:

Anyway, I've made the changes on the home copy and will publish them (hopefully) next time I get here.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 22nd, 2010, 1:15 am 
Hi!

If IcmpSendEcho doesn't support multiple requests, could it be fixed with creating threads :)? If you know what I mean..


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: June 22nd, 2010, 3:09 am 
Offline
User avatar

Joined: September 5th, 2009, 2:06 pm
Posts: 1718
Location: Somewhere near you
Can I see the ping result in ms, like in the command prompt?
And does NCA pings the host continuosly, like settimer?

_________________
Image
The quick onyx goblin jumps over the lazy dwarf


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 4th, 2010, 1:27 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
@ ddk: I'm pretty sure it's not possible to call the API multiple times simultaneusly. Can't actually perform any tests now since my Internet access is extremely limited.

@ tomoe_uehara: Theoretically, ping reply time display could be done but it's currently not implemented. Will look into adding such functionality, but testing might be a problem (see my reply above).

As for the other question: yes, it does ping continuously, since it's been built specifically to notify when Internet access is down. If you check the script you'll see. ;)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 6th, 2010, 3:29 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
I modified the functions to use a ByRef variable for return info and implemented a ping_time() function to get the number of milliseconds the ping lasted.

Example use at the top of the script:
Code:
loop
{
   ping(r, "yahoo.com")
   msgbox % "IP:`t" ping_DW2IP(r) "`nTime:`t" ping_time(r)
}

;*********************************

; Ping function by Drugwash March 26, 2010
; v2.0

; modified by infogulch on July 2, 2010
; changes:
; - modified ping functions to use ByRef variable for details
;     instead of returning the address of a static variable
;     (which is messy and un-library-like)
; - modified ping_DW2IP() function to work with new ByRef variables
; - added ping_time() function to retrieve the ping time from
;     the ByRef return value

;*********************************

ping_(ByRef reply, adr, data, timeout)
{
   ErrorLevel = 0
   SetFormat, IntegerFast, H
   cAdr := DllCall("wsock32\inet_addr", UInt, &adr, UInt)   ; convert address to 32bit UInt
   if cAdr = 0xFFFFFFFF
      cAdr := DllCall("ws2_32\inet_addr", str, adr, Int) ; second attempt at conversion, using ws2_32
   if cAdr = 0xFFFFFFFF
   {
      ErrorLevel = 1
      return err := "Error: Cannot convert address to UInt."
   }
   ; test for function presence since it's located in different libs through various OS
   hLib := DllCall("LoadLibrary", str, "iphlpapi.dll")
   if hLib
   {
      hPrAdr := DllCall("GetProcAddress", UInt, hLib, str, "IcmpCreateFile")
      if hPrAdr
         ;      hPort := DllCall("iphlpapi\IcmpCreateFile", UInt)   ; open a port (iphlpapi.dll in XP+)
         hPort := DllCall(hPrAdr, UInt)   ; open a port (iphlpapi.dll in XP+)
      else
         DllCall("FreeLibrary", UInt, hLib)
   }
   if !hPort
      hPort := DllCall("icmp\IcmpCreateFile", UInt)   ; open a port (icmp.dll in Win2000 and lower)
   if !hPort
      return err := "Error: Cannot open port.", ErrorLevel := 1
   SetFormat, Integer, D
   szreply = 278                ; ICMP_ECHO_REPLY structure
   VarSetCapacity(reply, szreply, 0)
   DllCall("icmp\IcmpSendEcho", UInt, hPort, UInt, cAdr, UInt, &data, UInt, StrLen(data), UInt, NULL, UInt, &reply, UInt, szreply, UInt, timeout, UInt)
   errcode := NumGet(reply, 4, "UInt")   ; check for status
   errcode := errcode <> 0 ? errcode : errcode+11000
   if errcode = 11001   ; function returned 'buffer too small' so we increase it and try again
   {
      VarSetCapacity(reply, NumGet(reply, 12, "UShort")+16)
      DllCall("icmp\IcmpSendEcho", UInt, hPort, UInt, cAdr, UInt, &data, UInt, StrLen(data), UInt, NULL, UInt, &reply, UInt, szreply, UInt, timeout, UInt)
      errcode := NumGet(reply, 4, "UInt")   ; another check for status on 2-nd attempt
      errcode := errcode <> 0 ? errcode : errcode+11000
   }
   err := ping_GetError(errcode, "IcmpSendEcho")   ; error handling
   DllCall("icmp\IcmpCloseHandle", UInt, hPort)   ; close port
   if errcode != 11000            ; IP_SUCCESS
      return err, ErrorLevel := 1
   else
      ; on success returns ICMP_ECHO_REPLY structure address for external processing of data
      return err := True, ErrorLevel := False
}

;*********************************

ping_GetError(code, func="[ukn]")      ; error translation
{
   str := "Success|Reply buffer too small|Destination network unreachable|Destination host unreachable|Destination protocol unreachable|Destination port unreachable|Insufficient IP resources|Bad IP option specified|Hardware error|Packet too big|Request timed out|Bad request|Bad route|TTL expired in transit|TTL expired during fragment reassembly|Parameter problem|Datagrams are arriving too fast to be processed and datagrams may have been discarded|IP option too big|Bad destination|General failure (possible malformed ICMP packets)"
   Loop, Parse, str, |
      if (code = 11000 + A_Index - 1) || (A_Index = 20 && code = 11050)
         return err := "Error " code " [" A_LoopField "] in function " func
   return err := "Function " func " returned " code
}

;*********************************

ping_Host2IP(name)
{
   ErrorLevel = 0
   type := SubStr(name, 1, 1)
   if type is alpha
   {
      hostent := DllCall("ws2_32\gethostbyname", UInt, &name, UInt) ; http://msdn.microsoft.com/en-us/library/ms738524(VS.85).aspx
      if !hostent
      {
         err := DllCall("ws2_32\WSAGetLastError")
         ErrorLevel = 1
         return err
      }
      ; string containing protocol types (mainly for debug purposes)
      str := "local to host (pipes, portals)|internetwork: UDP, TCP, etc.|arpanet imp addresses|pup protocols: e.g. BSP|mit CHAOS protocols|XEROX NS protocols or IPX protocols: IPX, SPX, etc.|ISO protocols or OSI is ISO|european computer manufacturers|datakit protocols|CCITT protocols, X.25 etc|IBM SNA|DECnet|Direct data link interface|LAT|NSC Hyperchannel|AppleTalk|NetBios-style addresses|VoiceView|Protocols from Firefox|Unknown - Somebody is using this!|Banyan|Native ATM Services|Internetwork Version 6|Microsoft Wolfpack|IEEE 1284.4 WG AF"
      ptrName := NumGet(hostent+0, 0, "UInt")
      pt := NumGet(hostent+0, 8, "UShort")
      Loop, Parse, str, |
         if (A_Index = pt)
            type := A_LoopField
      len := NumGet(hostent+0, 10, "UShort")
      ptrAddress := NumGet(hostent+0, 12, "UInt")
      ptrIPAddress := NumGet(ptrAddress+0, 0, "UInt")
      strAddress := NumGet(ptrIPAddress+0, 0, "UInt")
      VarSetCapacity(adr, 16, 32)
      DllCall("lstrcpy", UInt, &adr, UInt, DllCall("ws2_32\inet_ntoa", UInt, strAddress))
      VarSetCapacity(adr, -1)
      VarSetCapacity(pname, 260, 32)
      DllCall("lstrcpy", UInt, &pname, UInt, ptrName)
      VarSetCapacity(pname, -1)
      return adr
   }
   else
      return name
}

;*********************************

ping_DW2IP(ByRef adr)
{
   return (*&adr) "." (*(&adr+1)) "." (*(&adr+2)) "." (*(&adr+3))
}

;*********************************

ping_time(ByRef adr)
{
   return NumGet(adr, 8, "uint")
}

ping(ByRef reply, addr, data="AHK ping test", timeout="500")
{
   ; Sockets initialization http://msdn.microsoft.com/en-us/library/ms741563(VS.85).aspx
   VarSetCapacity(WSADATA, 12+257+129, 0)   ; WSADATA structure initialization
   err := DllCall("wsock32\WSAStartup", Short, 0x101, UInt, &WSADATA, UInt)
   if err > 0
   {
      ErrorLevel = 1
      err = Socket initialization error %err%      ; Failed to initialize sockets
      goto error
   }
   address := ping_Host2IP(addr)               ; address conversion to DWORD
   err := ping_GetError(address, "ping_Host2IP")         ; error handling
   if ErrorLevel
      goto error
   err := ping_(reply, address, data, timeout)         ; ping function call
   error:
   EL := ErrorLevel
   DllCall("wsock32\WSACleanup")            ; Sockets cleanup & close
   ErrorLevel := EL
   return err
}

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 14th, 2010, 12:19 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
Ah, bad timing on my side! I had already added reply time to NetCon Alert before getting to read your reply. I'm gonna post it as is, for now and examine your changes when I get back home.

As for the static variable: that actually contains the address of the ICMP_ECHO_REPLY structure from which any relevant information can be extracted at will. That is precisely the reason why I chose such return type: to give anyone the opportunity to choose whatever information they need.

NetCon Alert v2.1.0 can be found here


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 14th, 2010, 3:13 am 
Offline

Joined: January 2nd, 2008, 4:47 am
Posts: 150
Location: Freenode IRC
Sort of related to the NetCon portion of this thread. Does anyone know what method(s) can determine the Gateway address of the active internet (gateway'd) device? The gateway address on home networks is typically "192.168.0.1" or something similar.

As part of a script I'm writing, I would like to pin-point net connection issues, by pinging the gateway address along with known internet addresses to identify the point of failure.

_________________
Image

Need help right away? Get live support on IRC.
Already have an IRC client installed? /join #ahk


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 27th, 2010, 2:51 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
I suppose the registry could be queried in this regard.Can't pinpoint the exact location now though.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 11th, 2010, 5:20 am 
I could be mistaken but querying ipconfig will return the active gateway. A CMD parse could retrieve it.


Report this post
Top
  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 43 posts ]  Go to page Previous  1, 2, 3

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot] and 19 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group