How to get netmask and default gateway of adapters in WEC2013 - windows-embedded-compact

The function GetAdaptersInfo allows to retrieve the address information including netmask and default gateway for all adapters.
This function is deprecated since Windows Embedded Compact 7.
The "Functionality To Use Instead" list the function GetAdaptersAddresses as a replacement. But this function doesn't report netmask and default gateway.
How can I get the netmask and the default gateway of the network adapters?

GetAdaptersAddresses returns a linked list of IP_ADAPTER_ADDRESSES structs.
Within each IP_ADAPTER_ADDRESSES, the FirstUnitcastAddress field points to a list of IP_ADAPTER_UNICAST_ADDRESSES structs.
Within each IP_ADAPTER_UNICAST_ADDRESSES there is a field called OnLinkPrefixLength, which specifies the netmask as the length, in bits, of the network part of the IP address. Note that this field is not documented for WEC2013 (it is for desktop Windows, though).
To convert OnLinkPrefixLength to a ULONG mask, use ConvertLengthToIpv4Mask.
Gateway addresses are provided through the FirstGatewayAddress field in each IP_ADAPTER_ADDRESSES struct.

Related

getaddrinfo with flag AI_NUMERICHOST

Please tell me something I can't understand. There is a function getaddrinfo() and there is a flag AI_NUMERICHOST. MSDN says that in getaddrinfo() with this flag, you need to send the numeric value of the IP address, and not the domain name. But why?
I already have an IP address, why should I ask DNS for an IP address?
getaddrinfo() outputs sockaddr_... structs (sockaddr_in or sockaddr_in6) for the requested host/service. It is not just about IP addresses, it is also about other things, like socket types, service ports, etc, depending on your input and hint values.
So, if you already have an IP address in a string format, you can have getaddrinfo() parse that string for you (specifying AI_NUMERICHOST to avoid DNS) into a binary format in the output sockaddr_..., as well as fill in other sockaddr_... fields at the same time.

windows winsock2 socket return 10014 WSAEFAULT from WSAGetLastError (ipv4 / ipv6 related)

Steps to reproduce:
Create IPv6 socket AF_INET6/SOCK_DGRAM/UDP
Bind the socket to an IPv6 address
Use sendto(...) winsocket API but specify an IPv4
socket AF_INET family address address to send to
Winsock2 API will return WSAEFAULT with WSAGetLastError.
If you attempt to send a UDP packet to an IPv4 address using an IPv6 socket, sendto() will report the WSAEFAULT error. This behavior is described by MSDN:
sendto function
Return value
If no error occurs, sendto returns the total number of bytes sent, which can be less than the number indicated by len. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError.
...
WSAEFAULT
The buf or to parameters are not part of the user address space, or
the tolen parameter is too small.
Technically that's true because an IPv4 address is smaller than an IPv6 address. It might be a bit misleading to think sizeof was wrong when it's actually the wrong address family used and hence the sizeof represents the wrong size to use.
See also windows error codes here:
Windows Sockets Error Codes

ipv6calc outputs wrong address when converting from ipv4 to ipv6?

Having a strange issue while trying to convert an ipv4 list file to ipv6:
ipv6calc -q --action conv6to4 --in ipv4 1.1.23.1 --out ipv6
2002:101:1701::
Trying to validate that result is correct, I used some online converters and it seems that 1.1.23.1 is 2002:0:0:0:0:0:101:1701 (or else 2002::101:1701).
So the last "::" should be removed & 2002 should have extra ":".
I really don't want to use sed/awk commands in order to manipulate this result, so the questions are:
is there alternative cmd/linux SW?
is this somehow fixed inside ipv6 calc, am I doing something wrong?
Thanks
This is the correct 6to4 address. A 6to4 subnet is on the format 2002:IP4_HI:IP4_LO::/48. IP4_HI is the top 16 bits of the IPv4 address, while IP4_LO is the low 16 bits of the address.
For example, the IPv4 address 1.2.3.4 gives you the 6to4 subnet 2002:0102:0304::/48.
See 6to4 address block allocation for more details.
A different question is whether this is actually the address you want? There are other ways to map IPv4 addresses to IPv6 addresses. For example, there are IPv4-mapped IPv6 addresses, which are typically written as ::ffff:1.2.3.4.
The address format you need depends on what you are going to use it for.

in winsock, how do i connect to a server via a domain name?

when i'm filling out a SOCKADDR_IN struct for the connect function, i tend to fill it out with the exact ip address, but let's say i wanted to set up a dynamic domain name online to represent an occasionally changing ip address? I'm not quite sure how i would fill out the struct, given a domain name. What i do now is this:
#define DEFAULT_PORT 12345
SOCKADDR_IN serverInfo;
serverInfo.sin_port=htons(DEFAULT_PORT);
serverInfo.sin_family=AF_INET;
serverInfo.sin_addr.s_addr= inet_addr("127.0.0.1"); // actual ip normally here
but how do you resolve domain names to get the ip of the server for this struct?
You want to use the gethostbyname function
http://msdn.microsoft.com/en-us/library/windows/desktop/ms738524%28v=vs.85%29.aspx

How to add persistent IPv6 address in Vista/Windows7?

I want to add a persistent IPv6 address using just API calls or with Registry edits. I have currently implemented a code which uses CreateUnicastIpAddressEntry API to add the IPv6 address successfully, but the IP address is destroyed when the adapter is reset or machine rebooted (as mentioned in MSDN docs).
With IPv4, it was easy to do. Just use AddIPAddress API combined with registry entries to get the desired result.
I have tried to find any entry in the Windows Registry which is being used to save the IPv6 address without any success. The MSDN docs suggests to use netsh.exe to do the task, but then I am quite sure netsh.exe is doing some API call or Registry entry to achieve this task (which is not documented by Microsoft anywhere).
How can this be achieved?
Well, after some reverse engineering of netsh.exe and detailed analysis I think there is sufficient info to create a persistent ipv6 address.
The ipv6 address (UNICAST) is stored in following registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nsi\{eb004a01-9b1a-11d4-9123-0050047759bc}\10
For every ipv6 address to be added, create a REG_BINARY value such that the name of the value contains NET_LUID concatenated with the ipv6 address in full. Like for example, if the ipv6 address is 2001::1, the name of the value will be 000000090000060020010000000000000000000000000001, where the first 16 characters is the NET_LUID of the network adapter and the rest the ipv6 address in full.
This registry value data is made of a 48 byte long structure given below:
typedef struct _UNKNOWN {
ULONG ValidLifetime;
ULONG PreferredLifetime;
NL_PREFIX_ORIGIN PrefixOrigin;
NL_SUFFIX_ORIGIN SuffixOrigin;
UINT8 OnLinkPrefixLength;
BOOLEAN SkipAsSource;
UCHAR Unknown[28];
} UNKNOWN;
The last 28 bytes of this structure is unknown and must be initialized to 0xFF.
Refer to MIB_UNICASTIPADDRESS_ROW structure info in msdn for more info on the UNKNOWN structure members.
While doing this, I also figured out that ipv6 ANYCAST addresses are stored similarly in registry key:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nsi\{eb004a01-9b1a-11d4-9123-0050047759bc}\8`\

Resources