IPv6 handling when using Direct protocol v4.00 - opayo

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??

Related

destination MAC to use when sending to remote host (is it my router)?

For various reasons, I'm trying to construct and send raw TCP packets to a remote host (ex. google.com) with raw sockets. I'm trying to use pcap, so the raw socket code can be ported to Windows at some point.
Looks pretty straightforward...
1. ethernet header
2. ip header
3. tcp header
4. segment (optional)
2,3,4 are straightforward. #1 is the rub because I don't know what to use for the destination MAC address of google.com. From what I can tell, ARP is useless for telling me that MAC because I have to be connected to google's router for it to work. Snag.
So that makes me ask this question:
Should I use the MAC of MY router as the destination MAC address in the ethernet header when sending to a host not in LAN? And when the packet is forwarded, does every router it hits tear out that Ethernet header and replace it with the appropriate source/destination MACs so it gets to Google.com? That is the only thing that sounds reasonable.
Side note, I think this was the motivation here, but the question never quite made it:
how to determinate destination MAC address
That's right. The source MAC address in the ethernet header should be the MAC address of the interface you're sending from, and the destination MAC address should be your router's MAC on its interface that is connected to your LAN.
It's important to remember that Link-Layer addresses are used within networks (in this case, both your MAC address and your router's internal interface are on your LAN), while Network Layer (IPv4/IPv6) addressing is used to route your packet from the source host to the destination host (this is ignoring NAT and a whole bunch of other grossness that arises in IPv4).
What will happen when you send your Ethernet frame out of your interface is the following:
Your router will end up with the frame after it travels through 0 or more switches, which know where your router's internal MAC address is from receiving traffic from it in the past. Your router knows the frame is for it because its internal MAC address is the destination MAC.
Your router will strip off the Ethernet header. Then, it will inspect the destination IP address, and determine how to forward that packet based on that address. If we're talking about your home router, it is probably also changing the source IP address (something called Network Address Translation, or NAT), but since it isn't in the scope of your question I'll leave that alone.
Before it forwards the packet to the next router on the path toward the destination IP address, the router needs to put another Link-Layer header back on the IP datagram because it stripped off the one you had put on it. So, it will create a new Link-Layer header using its outgoing interface's MAC address as the source MAC, and the MAC address of the next router's internal MAC address as the destination. In this way, the Link-Layer header is re-written "hop-by-hop".
Somedays before even I faced the same confusion. So long story short yes the destination MAC address will be the gateway router MAC address. And about how I determined is - like this -
I used the command
route -n
Then I used the command
arp -n
The output is as you can see -
goutbose#####:~$ route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 10.39.51.1 0.0.0.0 UG 0 0 0 enp2s0f0
goutbose####:~$ arp -n
Address HWtype HWaddress Flags Mask Iface
10.39.51.130 ether 00:1a:c5:01:12:94 C enp2s0f0
Now you can hardcode your destination MAC in your packets as I did as an easy hack or if you want you can design your own ARP resolution which is way out of my knowledge scope to help you out. My implementation to implement my own ICMP ping request using raw sockets is as follows -
https://github.com/Goutam1511/Socket-Programming-with-C/blob/master/myping.c
Although a late reply I hope it may help somebody else out because there are very little resources related to using raw socket in the link layer.

Connecting to MySQL (on Google Cloud SQL) via JDBC and IPv6?

I would like to connect to Google Cloud SQL from an external application using JDBC and the instance's IPv6 address as shown on my Google Developers Console (here obfuscated):
String url = "jdbc:mysql://abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd";
String user = "root";
String password = "<also_obfuscated>";
connection = DriverManager.getConnection(url, user, password);
This leads to the following exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:
Cannot load connection class because of underlying exception:
'java.lang.NumberFormatException:
For input string: "abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd"'.
I am using the latest JDBC driver for MySQL. Connection via JDBC and IPv4 works but requires an extra configuration step and incurs (small) extra cost.
So is it even possible to connect to MySQL via JDBC and IPv6 and if so how?
UPDATE According to the documentation, this URL should work for IPv6:
jdbc:mysql://address=(protocol=tcp)(host=abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd)(port=3306)
However, now I'm getting the following exception:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
Communications link failure
The last packet sent successfully to the server was 0 milliseconds ago.
The driver has not received any packets from the server.
Besides the JDBC driver supporting IPv6 (which it does, according to the documentation), and the client OS supporting IPv6 (which mine should as it is OS X Yosemite), and the server OS supporting IPv6 (which the Google Cloud does because it reports an IPv6 server address) what other pieces need to be in place in order for IPv6 client-server connections to work?
E.g. does my ISP have to provide any particular support?
You need to register the IPV6 address from which you'll be coming into Google Cloud SQL, among the authorized addresses on the Cloud SQL console.
You can check that IPv6 address e.g by visiting sites such as whatismyv6.com .
Then, all your ISP has to do is to provide a stable IPV6 address (alas, even to these days, not all do -- alas, AT&T Uverse, my ISP at home, does not, for example).
Even from locations where I could reliably get a stable IPv6 address, I had exactly the same problem, originally -- until it dawned on me that, if I'm coming in with an IPv6 address and what I've authorized is an IPv4 one, Google Cloud SQL cannot "translate" one into the other to find out I'm in fact authorized!-)
Note that if you don't have and can't get an IPv6 address from which to connect (e.g. connecting from a home machine through an ISP that does not yet support IPv6) then you can hit the "Request IPv4 address" button under Google Developers Console / Storage / Cloud SQL / [Your Intance] / Access Control / IP Address and you will get one assigned (within a few seconds) which will cost $0.01 per hour, paid from your free $300 of credit if you still have that credit available. Once you move your app to, for example, one of Google's app servers, you will no doubt be able to get an IPv6 address. Release the IPv4 address when unused to save credit.
Try
String url = "jdbc:mysql://[abcd:abcd:abcd:abcd:abcd:abcd:abcd:abcd]";
In URLs literal IPv6 addresses have to be surrounded by [] so that the parser can see the difference between parts of the address and the optional port number which is also separated by a :.
It is often easier to use hostnames instead of literal IP addresses. It stays independent of the used IP protocol and changing addresses is easier as well.

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.

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

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.

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