Page 1 of 1

Structures for IPv6

Posted: Thu Jan 24, 2013 3:45 pm
by SFSxOI
With the basic IPv6 capabilities being added to PureBasic, at some point some of you will want to go beyond those additions. This is not a trick or really a tip, its more of a "gee whiz" thing so they will be available for you when needed, so here are a few structures i've been using which you may encounter along your way with that IPv6 app you work on:

Code: Select all

; Ipv6 and Ipv4
; comes in especially handy when you want to store addresses for either Ipv6 or Ipv4 or both at the same time
Structure SOCKADDR_STORAGE ;->Structure SOCKADDR_STORAGE
  ss_family.l
  __ss_pad1.b[6]
  __ss_align.q
  __ss_pad2.b[112]
EndStructure

; Ipv6 and Ipv4
Structure SOCKET_ADDRESS ;->Structure SOCKET_ADDRESS
*lpSockaddr.SOCKADDR_STORAGE
  iSockaddrLength.l
EndStructure

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

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

; Ipv6 and Ipv4
Structure SCOPE_ID
  StructureUnion
    Zone.l[28]
    Level.l[4]
  EndStructureUnion
  Value.l
EndStructure

; Ipv6 only
Structure IN6_ADDR ;->Structure in6_addr
  StructureUnion
    s6_bytes.b[16]
    s6_words.w[8]
  EndStructureUnion
EndStructure

; defined as ; SOCKADDR_IN6_LH in the SDK, replaces sockaddr_in6_w2ksp1 for Vista and above
; Ipv6 only
Structure sockaddr_in6  ;->Structure sockaddr_in6
  sin6_family.w
  sin6_port.w
  sin6_flowinfo.l
  sin6_addr.IN6_ADDR
   StructureUnion
    sin6_scope_id.l
    sin6_scope_struct.SCOPE_ID ; SCOPE_ID sin6_scope_struct
  EndStructureUnion
EndStructure

; defined as ; SOCKADDR_IN6_W2KSP1 in the SDK
; for use with less than Winodws Vista although will work in about 90% of applications for Vista and above
; IPv6 only
Structure sockaddr_in6_w2ksp1  ;->Structure sockaddr_in6_w2ksp1
  sin6_family.w
  sin6_port.w  
  sin6_flowinfo.l
  sin6_addr.IN6_ADDR 
  sin6_scope_id.l
EndStructure

;; Structure To hold a pair of source, destination addresses.
; IPv6 only but has a direct parallel for IPv4 in the SDK
Structure sockaddr_in6_pair  ;->Structure sockaddr_in6_pair
  SourceAddress.sockaddr_in6 ; PSOCKADDR_IN6
  DestinationAddress.sockaddr_in6 ; PSOCKADDR_IN6
EndStructure
Nothing earth shattering, but its nice to have them already available in the forum for copy and paste when you need them.

Short quick example of one basic usage of the sockaddr_in6 structure (just for example purposes to show basic set up of the structure)

Code: Select all

Structure SCOPE_ID ;->Structure SCOPE_ID
  StructureUnion
    Zone.l[28]
    Level.l[4]
  EndStructureUnion
  Value.l
EndStructure

Structure IN6_ADDR ;->Structure in6_addr
  StructureUnion
    s6_bytes.b[16]
    s6_words.w[8]
  EndStructureUnion
EndStructure

Structure sockaddr_in6  ;->Structure sockaddr_in6
  sin6_family.w
  sin6_port.w
  sin6_flowinfo.l
  sin6_addr.IN6_ADDR
   StructureUnion
    sin6_scope_id.l
    sin6_scope_struct.SCOPE_ID
  EndStructureUnion
EndStructure

Prototype PInetPton(Family, pszAddrString, pAddrBuf)
Global InetPton.PInetPton

Lib_Winsock = OpenLibrary(#PB_Any,"ws2_32.dll")
If IsLibrary(Lib_Winsock)<> 0
  CompilerIf #PB_Compiler_Unicode ; if compiled in unicode use this
    InetPton.PInetPton=GetFunction(Lib_Winsock,"InetPtonW") ; works with IPv4 and Ipv6
  CompilerElse ; if not compiled in unicode use this
    InetPton.PInetPton=GetFunction(Lib_Winsock,"inet_pton") ; works with IPv4 and Ipv6
  CompilerEndIf
EndIf

#AF_INET6 = 23

Macro IN6_IS_ADDR_UNSPECIFIED(adr)
  ((adr\s6_words[0] = 0) And (adr\s6_words[1] = 0) And (adr\s6_words[2] = 0) And (adr\s6_words[3] = 0) And (adr\s6_words[4] = 0) And (adr\s6_words[5] = 0) And (adr\s6_words[6] = 0) And (adr\s6_words[7] = 0))
EndMacro

Macro IN6_IS_ADDR_LOOPBACK(adr)
  ((adr\s6_words[0] = 0) And (adr\s6_words[1] = 0) And (adr\s6_words[2] = 0) And (adr\s6_words[3] = 0) And (adr\s6_words[4] = 0) And (adr\s6_words[5] = 0) And (adr\s6_words[6] = 0) And (adr\s6_words[7] = $0100))
EndMacro

Macro IN6_IS_ADDR_6TO4(adr)
  (adr\s6_words[0] = $220)
EndMacro

Macro IN6_IS_ADDR_LINKLOCAL(adr)
  ((adr\s6_bytes[0] = $fffffffffffffffe) And ((adr\s6_bytes[1] & $ffffffffffffffc0) = $ffffffffffffff80))
EndMacro


Procedure.s Ipv6AddressIdentify(DIPinAdr$)
  Protected *Resolve.sockaddr_in6
      
  *Resolve.sockaddr_in6 = #Null
  
  *Resolve.sockaddr_in6 = AllocateMemory(SizeOf(sockaddr_in6))
  *Resolve\sin6_family = #AF_INET6
  *Resolve\sin6_port = 0
  *Resolve\sin6_flowinfo = 0
  InetPton(#AF_INET6, @DIPinAdr$, @*Resolve\sin6_addr)
  *Resolve\sin6_scope_id = 0
  
  ;**************************************************************
  If IN6_IS_ADDR_UNSPECIFIED(*Resolve\sin6_addr)
    ProcedureReturn "This is an Unspecified Ipv6 address"
  ElseIf IN6_IS_ADDR_LOOPBACK(*Resolve\sin6_addr)
    ProcedureReturn "This is the Ipv6 loopback address"
  ElseIf IN6_IS_ADDR_6TO4(*Resolve\sin6_addr)
    ProcedureReturn "This is an Ipv6 6to4 address"
  ElseIf IN6_IS_ADDR_LINKLOCAL(*Resolve\sin6_addr)
    ProcedureReturn "This is an Ipv6 Link Local address"
  EndIf
  
  
  ; **********************************************************************
  FreeMemory(*Resolve)
  
EndProcedure

Debug Ipv6AddressIdentify("::")
Debug Ipv6AddressIdentify("::1")
Debug Ipv6AddressIdentify("2002:62ab:b6bf::62ab:b6bf")
Debug Ipv6AddressIdentify("fe80::82b:3794:9e04:4853")
Another basic example I previously posted showing use of the ADDRINFOEX and sockaddr_in6 structures can be found here > http://www.purebasic.fr/english/viewtop ... 12&t=52755

One basic example I previously posted of using the SOCKADDR_STORAGE structure can be found here > http://www.purebasic.fr/english/viewtop ... 12&t=52402