bind () to an IPv6 address in windows 7 is Failing with Error code :: WSAEADDRNOTAVAIL (10049) - windows-7

I am trying to set-up a private ipv6 network with two windows-7 machines for tesing my application. I have written a sample code to test the socket apis. I have created an IPv6 socket. When I try to bind with the link-local address (which I get from ipconfig command), the error code is 10049.
Please inform, why the bind with Ipv6 address is failing in windows-7 machine ?

If you're using a link-local IPv6 address, you probably need to set the sin6_scope_id field in your sockaddr_in6 structure to indicate which interface you want to listen on. A link-local address is ambiguous, since every interface must have a link-local address assigned, and they all use the same prefix. (fe80::/64)
You should probably bind() your listen socket to the unspecified address (all-zeroes or ::) so this isn't an issue, but it will still be a problem for the sending side. If you don't specify the sin6_scope_id, the system won't know which interface to send the packet on.
To avoid the issue, it would be best to set up an IPv6 router that does router advertisements, so you can get global unicast (or, at a minimum, unique local) addresses.

Related

IPv6 handling when using Direct protocol v4.00

I tried turning on Direct protocol v4.00 today, however I hit a snagging point with IP address handling. Some client IP addresses are IPv6 addresses e.g: 2a02:c7f:d192:dc00:de4:a84d:aab5:8225 (i've tweaked this address a little)
When I send these IPv6 addresses through I get the following error:
VPSProtocol=4.00
Status=INVALID
StatusDetail=3067 : The ClientIPAddress is too long.
VPSTxId={03F24DE5-60E6-FE73-0BFA-SOMETHING}
If I omit the IP address altogether, I get the following error:
VPSProtocol=4.00
Status=INVALID
StatusDetail=3333 : The ClientIPAddress is missing.
VPSTxId={983A157B-8866-A6C9-A4AC-SOMETHING}
So, what am I meant to do when presented with an IPv6 address? Fall back to Direct protocol v3.00??

What is a Valid IPv4 Address for GetIpAddrTable

I would like to know what a "valid IPv4 address" is in the context of the win32 GetIpAddrTable function call. The documentation indicates that this function does not return invalid IPv4 addresses on Vista and above. It does not explain how it determines validity.
On Windows Server 2008 and Windows Vista, the IPv4 addresses returned
by the GetIpAddrTable function are not affected by the media sensing
capability of the TCP/IP stack on a local computer. The GetIpAddrTable
function returns only valid IPv4 addresses.
I am digging into a problem where a call to this function is not returning the address for a functioning adapter. The adapter uses the driver's DHCP server to assign a link-local IP address. On most systems this works fine. On a specific customer system, it does not.
Ping and traffic tests work fine and the adapter shows up in output from GetAdaptersAddresses. My other question seems to indicate that the only difference should be IPv6 support. The adapter in question receives a link-local IPv6 address as well, but that shouldn't prevent it from showing up in GetIpAddrTable output should it?
Cross-Reference
GetIpAddrTable Returned Adapter List Differs from GetAdaptersAddresses
Simple Answer: It does exactly what it says it does - it returns connected interfaces which are running IPv4.
I've now confirmed that GetAdaptersAddresses also skips our network adapter when limiting to IPv4 interfaces. So it appears that there's a problem between the driver and Windows in identifying as an IPv4 interface.

IPv6 link-local address format

I am working on a project related to networking/compression. One of the machines is Windows Vista, which already has IPv6 configured.
When I try ipconfig, I see an address in the following format: fe80::9dc8:72fa:aacd:76e2%10
But when I try to ping this machine from another with ping fe80::9dc8:72fa:aacd:76e2%10, I get the following error:
Ping request could not find host fe80::9dc8:72fa:e327:76e2%10.
Please check the name and try again.
Any ideas/comments are very helpful.
The %10 after the address is called the scope zone. When you use link-local IPv6 addresses, the scope zone is required so that the system knows which interface to send the packet out on.
On Windows, if you issue the netsh interface ipv6 show addresses command, you'll see the addresses assigned to the system complete with their zone IDs. Notice that the zone IDs match the interface index. For example:
Interface 22: VirtualBox Host-Only Network
Addr Type DAD State Valid Life Pref. Life Address
--------- ----------- ---------- ---------- ------------------------
Other Preferred infinite infinite fe80::15c3:6bea:aaac:a015%22
This address is scoped %22 because it is on an interface whose index is 22. Similarly, on Linux, you might see a link-local address like fe80::15c3:6bea:aaac:a016%eth0. The format of the zone ID is unique to each individual machine running IPv6, which is why it might be different if you try the ping from the other system.
For example, if you have:
System A (Windows): fe80::15c3:6bea:aaac:a015%22
System B (Linux): fe80::15c3:6bea:aaac:a016%eth0
... and you want to ping the Linux box from the Windows box, you cannot do ping fe80::15c3:6bea:aaac:a016%eth0. But you can do ping fe80::15c3:6bea:aaac:a016%22. This is the problem. Link-local addresses can be tricky in this way.
Try specifying the correct zone ID. That is, when you do your ping fe80::9dc8:72fa:aacd:76e2%10, first do netsh interface ipv6 show addresses on the machine you are pinging from, and change the %10 to the interface index for whichever interface you want to use on the source system.
If the machine you are pinging from is Linux, you will have to do ping6 -I eth0 fe80::9dc8:72fa:aacd:76e2 (assuming the other system is on eth0), because the Linux command-line utility does not support the % way of specifying the zone (the last time I checked, anyway).
Ideally you should set up an IPv6-capable router on your network to do router advertisements, so that you can use stateless address auto-configuration (SLAAC) and get global unicast addresses. Then this will not be an issue.
you cannot ping ipv6 addresses with the classic ping utility, only ipv4 addresses. linux has a commandline tool called ping6 to ping ipv6 addresses, windows probably has something similar. a little research told me that windows uses ping -6 for pinging ipv6 addresses.
The number after % is the interface name. if you open the status->detail of your network interface, you will see the ipv6 link-local address, with the %xx at the end of the address, which is the index of the interface, in case you want to find the index for some application. The System Information or ipconfig might just give you different index numbers, at least on my Windows 7 Pro, which is very confusing. The description you get from the OS could also be wrong.

How to detect if a windows machine is running IPV4 or IPV6?

Is there anyway to determine if a windows computer is running IPV6 using native utilities, python or php?
This is how I solved the issue, by trying to open up an IPv6 socket. If the system did not throw an error, then it is using IPv6.
import socket
def isIPV6():
ipv6 = True
try:
s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
except:
ipv6 = False
return ipv6
Sure. If ipconfig contains an IPv6 Address entry for a real interface, you've probably got IPv6 connectivity. There are also useful registry entries at HKLM\SYSTEM\CurrentControlSet\services\TCPIP6.
Every computer ships with IPv4 at standard. IPv6 is only enabled on specific machines. But if you parse ifconfig/ipconfig then you should find yourself a IPv4/6 address in the output
Enumerate the interfaces and check for an IPv6 address, like everyone else has stated. Alternatives include trying to open an IPv6 socket or get Python to call WSCEnumProtocols()
Jakob's approach is the simplest; you could pipe the result and do a match to see whether a network adapter has a valid IPv6 address.
Additionally, you could get this by fetching the Windows Management Instrumentation class Win32_NetworkAdapterConfiguration. The property IPAddress is an array of all the IP addresses associated with a network adapter and you can match against them to see if there is a IPv6 address associated. But PS is a bit of an overkill, I'd go with Jakob's or Wyatt's answer unless you'd need to do something more intelligible and fancy (send an HTTP request; change some network rules; restart a service).

Question regarding value returned from WebAuthenticationDetails.getRemoteAddress()

I am writing a custom AccessDecisionVoter that will allow access to certain resources only if the remote address of the request is found in a list of allow ip addresses. However, the value of the remote address returned by WebAuthenticationDetails.getRemoteAddress() is in a format that appears to be Ipv6. When running my app locally, this is what is returned by the above method:
0:0:0:0:0:0:0:1%0
I'm storing the allowed address in a comma-delimited list in a properties file. The list is parsed and each allowed address is compared to the remote address, but since I have no idea how to translate an Ipv4 address into an Ipv6 address this comparison will always fail.
So is the value that is always returned by WebAuthenticationDetails.getRemoteAddress() or am I seeing this only because I'm running this locally?
Is there some way to convert this string to an Ipv4 string?
Is there some way to have the method in question return an Ipv4 string instead?
Thanks!
You cannot convert an IPv6 address to an IPv4 address. The represent two different protocols. The address of getRemoteAddress() will be in a format depending on the protocol used to create the request to the webapp. I guess that you see the IPv6 address only when using the app locally. 0:0:0:0:0:0:0:1 is the address of localhost, which is the same as 127.0.0.1 in IPv4. I think you should simply add this IPv6 address to the list of allowed IPs.

Resources