News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

IPv6 structures missing?

Started by pcMike, November 15, 2017, 10:21:32 AM

Previous topic - Next topic

pcMike

I wrote a tcp server which I want to update to support IPv6, so I need to replace the sockaddr_in structure with sockaddr_in6.
Unfortunately sockaddr_in6 is not defined in windows.inc. Can anyone tell me what's needed to add it?

Also, if anyone has example code for an IPv6 tcp server it would be very helpful. Ideally I want to accept both IPv4 and IPv6 connections using dual stack by creating an IPv6 socket and turning off the socket option IPV6_V6ONLY, (which is not defined in MASM32 either, but it is 027h), and then invoke bind and listen to allow inbound connections.

It appears that other then changing sockaddr_in to sockaddr_in6 and changing AF_INET to AF_INET6 (or AF_UNSPEC for dual stack), I will just need to adapt to using getaddrinfo and getnameinfo in place of the IPv4-only functions.





hutch--

Its handy in MSDN.

https://msdn.microsoft.com/en-us/library/windows/hardware/ff570824(v=vs.85).aspx

typedef struct sockaddr_in {
  ADDRESS_FAMILY sin6_family;
  USHORT         sin6_port;
  ULONG          sin6_flowinfo;
  IN6_ADDR       sin6_addr;
  union {
    ULONG    sin6_scope_id;
    SCOPE_ID sin6_scope_struct;
  };
} SOCKADDR_IN6, *PSOCKADDR_IN6;

pcMike

Thanks Hutch, but how would I create the same structure in MASM?

Is ADDRESS_FAMILY 8 bytes?
What does UNION do?
It appears that sin6_scope_struct is not defined in WINDOWS.INC either.



jj2007

Pick what you need:
ADDRINFOA STRUCT
ai_flags  DWORD ? ; AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST
ai_family DWORD ? ; PF_xxx
ai_socktype DWORD ? ; SOCK_xxx
ai_protocol DWORD ? ; 0 or IPPROTO_xxx for IPv4 and IPv6
ai_addrlen dd ? ; Length of ai_addr
ai_canonname LPVOID ? ; Canonical name for nodename
ai_addr dd ? ; Binary address
ai_next  dd ? ; Next structure in linked list
ADDRINFOA ENDS


SOCKADDR_IN6 STRUCT
sin6_family DWORD ?
sin6_port USHORT ?
sin6_flowinfo ULONG ?
sin6_addr DWORD ?
UNION
   sin6_scope_id ULONG ?
   sin6_scope_struct SCOPE_ID <>
ENDS
SOCKADDR_IN6 ENDS

PSOCKADDR_IN6 typedef ptr SOCKADDR_IN6


For the definition of SCOPE_ID, see here. Looks like a RECORD.

pcMike

Thanks JJ, that was exactly what I needed.

aw27

The structure is more likely something like this:

SOCKADDR_IN6 STRUCT
sin6_family   WORD ?
sin6_port    WORD ?
sin6_flowinfo   DWORD ?
sin6_addr    BYTE 16 DUP (?)
;UNION
   sin6_scope_id   DWORD ?
   ;sin6_scope_struct   SCOPE_ID <>
;ENDS
SOCKADDR_IN6 ENDS

scopeid is usually zero, probably you don't need to complicate things, unless you wish.

jj2007

José is right, the family is a short. Here is the GCC ws2tcpip.h, much cleaner than the obfuscated M$ crap:
struct sockaddr_in6 {
short sin6_family; /* AF_INET6 */
u_short sin6_port; /* transport layer port # */
u_long sin6_flowinfo; /* IPv6 traffic class & flow info */
struct in6_addr sin6_addr;  /* IPv6 address */
u_long sin6_scope_id; /* set of interfaces for a scope */
};


The sin6_addr member is a "struct" that can be one byte, word or dword:struct in6_addr {
    union {
        u_char _S6_u8[16];
        u_short _S6_u16[8];
        u_long _S6_u32[4];
        } _S6_un;
};


And of course, it is a DWORD in practice, what else?

aw27

Quote from: jj2007 on November 15, 2017, 07:35:09 PM
and of course, it is a DWORD in practice, what else?

It is never a DWORD, JJ.  :icon_eek:
Have you ever seen a IPv6 address?

jj2007

Yeah, it's four DWORDs, right, thank you so much and have a nice day.

aw27

Quote from: jj2007 on November 15, 2017, 08:00:55 PM
Yeah, it's four DWORDs, right, thank you so much and have a nice day.
No, it is 16 bytes. No function deals with it as an array of dwords.
Now, you can rest in peace.  :t

jj2007

Quote from: aw27 on November 15, 2017, 08:10:07 PMNo function deals with it as an array of dwords.

Then why does GCC provide u_long _S6_u32[4]; in the header file?

aw27

Quote from: jj2007 on November 15, 2017, 09:10:03 PM
Quote from: aw27 on November 15, 2017, 08:10:07 PMNo function deals with it as an array of dwords.
Then why does GCC provide u_long _S6_u32[4]; in the header file?

Does not make much sense, but VS does the same. 
On top of that values are in network byte order.

dedndave

actually, it's 8 words, divided into 3 groups of different sizes  :biggrin:

qWord

... and normative it is:
Quote from: RFC4291IPv6 addresses are 128-bit identifiers for interfaces and sets of interfaces



RFC4291

MREAL macros - when you need floating point arithmetic while assembling!

jj2007

struct in6_addr {
    union {
        u_char _S6_u8[16];
        u_short _S6_u16[8];
        u_long _S6_u32[4];
        GUID _S6_uxxl;
        } _S6_un;
};
;)