Check basic IPv6 connection ability for IPv6 addresses

Share your advanced PureBasic knowledge/code with the community.
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Check basic IPv6 connection ability for IPv6 addresses

Post by SFSxOI »

To determine basic IPv6 connectivity take a look here > http://www.purebasic.fr/english/viewtop ... 2&p=398042

For something that will also check for proper IPv6 connectivity in a more comprehensive manner and provide a sort of basic platform code for development of a basic IPv6 trouble shooting tool for your computer connectivity, the following is offered using Windows API. Works in unicode or ANSI compilation, for Windows Vista and later but only tested using Windows 7 x86. Purebasic does not do IPv6 so you need to call the API here for some things but i provided the whole thing with calls to API through the .dll's:

Code: Select all

Prototype Pgetaddrinfo(pNodeName, pServiceName, pHints, ppResult)
Prototype PWSAStartup(wVersionRequested, lpWSAData)
Prototype PWSACleanup()
Prototype Psocket(af, type, protocol)
Prototype Pclosesocket(s)
Prototype Pconnect(In_SOCKET, In_struct_sockaddr_name, In_intnamelen)
Prototype PFreeAddrInfo(ai)
Prototype PRtlZeroMemory(mem, sze)
Global getaddrinfo.Pgetaddrinfo
Global WSAStartup.PWSAStartup
Global WSACleanup.PWSACleanup
Global socket.Psocket
Global closesocket.Pclosesocket
Global connect.Pconnect
Global FreeAddrInfo.PFreeAddrInfo
Global ZeroMemory.PRtlZeroMemory

Lib_Winsock = OpenLibrary(#PB_Any,"ws2_32.dll")
If IsLibrary(Lib_Winsock)<> 0
  WSAStartup.PWSAStartup=GetFunction(Lib_Winsock,"WSAStartup")
  WSACleanup.PWSACleanup=GetFunction(Lib_Winsock,"WSACleanup")
  socket.Psocket=GetFunction(Lib_Winsock,"socket")
  closesocket.Pclosesocket=GetFunction(Lib_Winsock,"closesocket")
  connect.Pconnect=GetFunction(Lib_Winsock,"connect")
  CompilerIf #PB_Compiler_Unicode ; if compiled in unicode use this
    FreeAddrInfo.PFreeAddrInfo=GetFunction(Lib_Winsock,"FreeAddrInfoW") 
    getaddrinfo.Pgetaddrinfo=GetFunction(Lib_Winsock,"GetAddrInfoW")
  CompilerElse ; if not compiled in unicode use this
    FreeAddrInfo.PFreeAddrInfo=GetFunction(Lib_Winsock,"freeaddrinfo")
    getaddrinfo.Pgetaddrinfo=GetFunction(Lib_Winsock,"getaddrinfo")
  CompilerEndIf
EndIf

Lib_Kernel32 = OpenLibrary(#PB_Any,"Kernel32.dll")
If IsLibrary(Lib_Kernel32)<> 0
  ZeroMemory.PRtlZeroMemory=GetFunction(Lib_Kernel32,"RtlZeroMemory")
EndIf

Structure SOCKADDR_STORAGE ;->Structure SOCKADDR_STORAGE
  ss_family.l
  __ss_pad1.b[6]
  __ss_align.q
  __ss_pad2.b[112]
EndStructure

Structure ADDRINFOEX ;->Structure ADDRINFOEX
  ai_flags.l
  ai_family.l
  ai_socktype.l
  ai_protocol.l
  ai_addrlen.i
  *ai_canonname 
  *ai_addr.SOCKADDR_STORAGE ; or structure of choice such as *ai_addr.SOCKADDR_STORAGE
  *ai_blob
  ai_bloblen.i
  ai_provider.l
  *ai_next.ADDRINFOEX
EndStructure

#AF_INET6 =  23
#AI_CANONNAME = $2
#AI_ADDRCONFIG = $00000400
#WSAHOST_NOT_FOUND = 11001
#WSANO_DATA = 11004
#WSATRY_AGAIN = 11002
#WSAEHOSTUNREACH = 10065
#WSAENETUNREACH = 10051
; 
Macro MAKEWORD(a, b)
  (a & $FF)|((b & $FF)<<8)
EndMacro

Procedure ConnctIpv6()
  ; this procedure is IP version agnostic but set up for IPv6 only as shown
  ; to make for both IPv6 and IPv4 change #AF_INET6 to #AF_UNSPEC and of course for Ipv4 you will need to use an IPv4 address
  ; to make just for IPv4 change #AF_INET6 to #AF_INET
  socket_estab.l
   rc.i
   iResult.i
   IPv6connect_result.i
   IPv6connect_good.b
   *dest_result.ADDRINFOEX = #Null ; the destinaton we are connecting to
   hints.ADDRINFOEX
   ZeroMemory(@hints, SizeOf(hints))
   ; note: #AI_ADDRCONFIG will make it check for an IPv6 address configured on local machine if this is configured for Ipv6, or IPv4 if configured for IPv4
  hints\ai_flags = #AI_CANONNAME|#AI_ADDRCONFIG
  hints\ai_family = #AF_INET6
  hints\ai_socktype = #SOCK_STREAM
  hints\ai_protocol = #IPPROTO_TCP
  ;destip$ = "www.purebasic.com" ; used for testing IPv6 connect with this as configured for IPv6, will cause #WSAHOST_NOT_FOUND to be returned
  destip$ = "[2620:0:1cfe:face:b00c::3]" ; IPv6 hexidecimal address can be with or without brackets
  ;destip$ = "2620:0:1cfe:face:b00c::3" ; this is facebook hexidecimal IPv6 address, they pulled some strings to get this one :)
  ;destip$ = "www.v6.facebook.com" ; IPv6 named addresses can be used.
  destip_port$ = "http"; service name for port 80
  rc = getaddrinfo(@destip$, @destip_port$, @hints, @*dest_result);
  If rc <> 0
    ProcedureReturn rc
  EndIf
  
  ; Note: 
  ;If connect fails using the Ipv6 hexidecimal address change it to the sites named IPv6 address e.g. www.v6.facebook.com, if it has one and is Ipv6 enabled
  ; (note that www.purebasic.com is not Ipv6 enabled at this time so trying that here as is popular to do in example purbasic code will fail)
  ; if it still fails then your IPv6 has a problem. If neither the hexidecimal or named address fails then everything is fine.
  ; If it does not fail with the sites IPv6 named address but fails with the Ipv6 hexidecimal address or
  ; fails with the IPv6 named address but not with the Ipv6 hexidecimal address then there is either a records problem (IPv6 uses AAAA records)
  ; or a DNS problem or a problejm with your internet service provider. If using something like a cable modem to connect then restart your computer
  ; then power down the cable modem by removing the power supply to it (unplug it from the AC power), wait 30 seconds, then power up your cable modem.
  ; if you still do not have proper IPv6 connectivity then contact your provider.
  ; Using IPv6 hexidecimal addresses results in slightly faster access under IPv6 than IPv6 named addresses.
  
  ; get socket established
  socket_estab = socket(*dest_result\ai_family, *dest_result\ai_socktype, *dest_result\ai_protocol)
  If socket_estab = #INVALID_SOCKET
    freeaddrinfo(*dest_result) ; assumes getaddrinfo was sucessful to get to this point so need to free up the address resource from getaddrinfo if failure here before returning 
    ProcedureReturn #INVALID_SOCKET
  EndIf
  
  ; Make connection to server via socket
  IPv6connect_result = connect(socket_estab, *dest_result\ai_addr, *dest_result\ai_addrlen)
  If IPv6connect_result = 0
    IPv6connect_good = #True
  Else
    IPv6connect_good = IPv6connect_result
  EndIf
  closesocket(socket_estab)
  freeaddrinfo(*dest_result)
  ProcedureReturn IPv6connect_good

EndProcedure

wVersionRequested.w = MAKEWORD(2,2)
WSAStart.i = WSAStartup(wVersionRequested,@wsaData.WSADATA)
ipv6 = ConnctIpv6()
Select ipv6
  Case 1
    IPv6Installed$ = "IPv6 is installed and operational, IPV6 hosts/sites are reachable."
  Case #WSAHOST_NOT_FOUND
    IPv6Installed$ = "No such host known, not an official IPv6 host name or alias or cannot be found in the database(s) being queried (make sure address is the proper address)."
  Case #WSANO_DATA
    IPv6Installed$ = "The requested address is valid & found in the database, but does not have correct associated data being resolved for (usually a misconfigured record)."
  Case #WSATRY_AGAIN
    IPv6Installed$ = "No response from an authoritative server, usually a temporary error during host name resolution and retry at later time may be successful."
  Case #WSAEHOSTUNREACH
    IPv6Installed$ = "No route to host/site."
  Case #WSAENETUNREACH
    IPv6Installed$ = "Network is unreachable, usually means local computer knows no route to reach the remote host/site (or maybe your ISP is having a problem)."
  Case -1
    IPv6Installed$ = "Unable to establish a socket for IPv6 (indicates IPV6 may not be fully operational or configured properly, is disabled, system has no assigned IPV6 address, or other IPV6 issue)."
  Case 0
    IPv6Installed$ = "Unable to connect to IPv6 address (site may be down at the time of check, IPv6 use has an issue, or address is blocked in some way on your end or via ISP)."
  Default
    IPv6Installed$ = "Other error occured in trying to connect to a IPv6 address"
EndSelect
Debug  IPv6Installed$
WSACleanup()
note: updated code after original post in response to request to expand upon possible more common errors in reaching hosts/sites
Last edited by SFSxOI on Thu Jan 24, 2013 5:04 pm, edited 2 times in total.
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
User avatar
Azul
Enthusiast
Enthusiast
Posts: 109
Joined: Fri Dec 29, 2006 9:50 pm
Location: Finland

Re: Check basic IPv6 connection ability for IPv6 addresses

Post by Azul »

Nothing to add but "editing" link does not work for others :P
SFSxOI wrote:To determine basic IPv6 connectivity take a look here > http://www.purebasic.fr/english/posting ... 2&p=398042
I'll assume correct link would be http://www.purebasic.fr/english/viewtop ... 2&p=398042

Code: Select all

; Hello, World!
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Re: Check basic IPv6 connection ability for IPv6 addresses

Post by SFSxOI »

Yep, you go it right.

Guess I wasn't watching and had the wrong tab up at the time when I copied the link. Corrected the original post. Thanks :)
The advantage of a 64 bit operating system over a 32 bit operating system comes down to only being twice the headache.
Post Reply