Understanding the difference between local and global IPv6 address - delphi

I'm implementing REST client in my Delphi application. The devices, I will be connecting to can be on local or global IPv6 addresses. The devices are having REST server and my application prepares REST URI by using %interface_index at the end of IPv6 address.
I'm observing connection problems when I use interface index(Zone_id) in the ipv6 address when its global.
I'm wondering if there is a way where i can differentiate between these and decide when to use the index or not.

IANA maintains some documents that may help. For example, Internet Protocol Version 6 Address Space
Every IPv6 interface will have a Link-Local address. Packets addressed with Link-Local addresses cannot be routed off the link (hence, Link-Local). Every link will use the same network, so you need to distinguish Link-Local addresses by adding a Zone ID. All Link-Local addresses are in the fe80::/10 network.
Global addresses are in the 2000::/3 range, but there are some address blocks within that range that are not forwardable or globally reachable. See the IANA IPv6 Special-Purpose Address Registry.
You should also study RFC 4291, IP Version 6 Addressing Architecture.

Related

how to know that wifi supports only ipv6 i.e it is ipv6 only router

How can Wifi router clients can know that router supports ipv6 only and does not support ipv4 ?.
We currently use a faulty logic that if router does not provide ipv4 ip .
consider it as ipv6 only router .
but this can cause problem in case of some ipv4 dhcp server issue in router .
can supplicant or other module can know that it is ipv6 only router ?.
is there any android api to know this .
There are so many combinations and edge cases that it is usually a bad idea to manually deal with this. Even if you only have an IPv6 address you can have connectivity using 464xlat for example. The best solution is to make connections using hostnames and let the operating system deal with the complexities.
The clients can't know if the router only provides IPv6 or if router has an ipv4-failure.
Smart clients could check if DNS is DNS64. In that case the probability is high, that the router doesn't provide IPv4.
There is a draft on going to do it via flag in the RAs.
https://datatracker.ietf.org/doc/html/draft-ietf-6man-ipv6only-flag-02

iOS Detect IPv6 Support

I have an iOS application that utilizes a library with built in socket control (in other words, I don't create the sockets myself, I just pass the library the parameters for the sockets). I have two API's available to me from the library, each containing a configurable address that is either IPv4 or IPv6. Then there is a toggle I can configure to tell the library whether it should use IPv6 or IPv4.
Here is an example of how the configuration is loaded
// IPv6 Configuration
char* ipv6_addr = . . .; // This is defined elsewhere
config.server.s6.sin6_family = AF_INET6;
config.server.s6.sin6_port = htons(1122);
inet_pton(AF_INET6, ipv6_addr, &(config.server.s6.sin6_addr));
// IPv4 Configuration
char* ipv4_addr = . . .; // This is defined elsewhere
config.server.s4.sin_family = AF_INET;
config.server.s4.sin_port = htons(1122);
inet_pton(AF_INET, ipv4_addr, &(config.server.s4.sin_addr));
config.use_ipv6 = 1; // Set to 0 to use IPv4
I can currently successfully connect to either IPv4 or IPv6 depending on what the device and client network (ISP, etc) support, but I have to configure the use_ipv6 flag manually.
What I need to do is check if the client's network (ISP, etc) supports IPv6. If so, use an IPv6 connection. But if not, use an IPv4 connection. Preferably something like this: config.use_ipv6 = has_ipv6_support(); in which the function has_ipv6_support() returns either a 1 or 0.
So, how do I go about checking if the network has IPv6 support?
Notes
a) I can't use the regular methods of getaddrinfo since the sockets are handled inside of the library and I cannot use hostnames due to my infrastructure base shifting IP's around a lot. I only have either an IPv4 address or an IPv6 address at my disposal.
b) This is written in C, but I wouldn't mind a solution in Objective C either.
c) It would be difficult to simply test an IPv6 connection to decide since I'm using UDP for the connection and would have to timeout on a response. That's a bit more logic than I'd like to be involved as this will need to be done every now and again and I don't want to kill the battery by keeping the network adapters alive. I'd prefer to be able to pull this information locally.
As a UDP server, your library should listen both to IPv4 and IPv6 addresses simultaneously. Because there is strictly no mean to know which of IPv4 and IPv6 is available, without doing regular attempts to connect to a remote host with IPv4 and IPv6. This is because a network failure can occur in the network, somewhere on the IPv6 or IPv4 path only, to the remote sides that may talk to your app. So, either change your library (but it does not seem possible), or change your batteries regularly! Sorry :-(

Localhost OR loopback naming

During development of an IpAddress library's part, I'm confronted to a minor dilema.
How to name my function testing the address to be a LocalHost / Loopback.
What is the difference between this 2 designations?
In other libs , they make this choices:
Boost.asio -> is_loopback
Qt -> isLoopback
wxWidget -> IsLocalHost
Why do they call isLoopback a test like address == "::1" ??
ANSWER:
"localhost" is usually an alias for the "loopback" interface. They can and are often used interchangeably.
Subquestion: Is it the same definition between IPv4 and IPv6?
The previous answer is not entirely correct.
Loopback +interface+ may have configured multiple IP addresses, not only from localhost network. It is a common practice to put non-local address on loopback interface in e.g. dynamic routing, where you don't want to lose routes to router's IP in case any interface goes down.
On the other hand, loopback IPv4 +network+ is defined by IANA as 127.0.0.0/8. Surprisingly, for IPv6 they reserved only ::1/128 address.
To answer your question: if you want to check only addresses, I'd pick isLocalhost(). And to be a bit zealous, I'd check there for the whole network - I happened to see 127.0.0.2 a few times...

UDP Broadcast to All IPs not working in some networks

There is a lot of other answers related to this issue, however I believe this is specific.
I am using Delphi XE2 and Indy 10.5.8 and TIdUDPServer
In my local development network I have everything on the same network ip subrange and all connected to the very same Access Point (LinkSys)
I have Androids sendind UDP Broadcast to 255.255.255.255 to request the server ip address that is written in Delphi listening using TIdUDPServer on the port 44444.
The requests get there fine and I can answer back no problem. Works exactly as expected.
However I have noted that in some networks it does not work! It is always simple networks based on an access point, I am not sure but seems that where the problem happens the server PC is connect to the LAN port while the devices are using the wifi, all in the same access point.
Could be the case that the access points do not broadcast the UDP packet by the both LAN and wifi? I know that this kind of broadcast is very limited, but I have not found any information that tell me that in the same access point there is limitations like that.
Is there are ways to test, or workaround?
This solution needs to be strong enough to deal with the many AP out there.
EDIT: For those that want to get the source code for retrieving more information from the network including the broadcast ip as mentioned on the answer below follow this solution, it is all there.
http://www.code10.info/index.php?option=com_content&view=article&id=54:articleretrieve-network-adapter-information&catid=47:cat_coding_algorithms_network&Itemid=78
255.255.255.255 is not the best option for sending UDP broadcasts, and some routers/firewalls do block it unless configured otherwise. The better option is to use the NIC's actual subnet broadcast IP instead. For example, if a UDP socket is bound to local IP 192.168.0.1 with a subnet mask of 255.255.255.0, then the broadcast IP for that subnet is 192.168.0.255.
Most platforms have OS-specific APIs for retrieving a NIC's actual broadcast IP, such as getifaddrs() on POSIX systems, or at least for retrieving the NIC's subnet mask, such as GetAdaptersInfo() and GetAdaptersAddresses() on Windows, so you can calculate the broadcast IP manually.
Retrieving the local broadcast IP(s) may be added to Indy in a future version.

How Scan devices in a LAN network

I would like to do a scan in a LAN network to find devices linked.
I'm developping an app in IOS for IPAD
How do I do???
Because those are mobile devices I will assume you want to find devices on a wireless network. Theoretically, since wifi uses shared medium for communication, you can passively listen for traffic flowing through the network and collect data about client without sending any packets. This is something that is commonly referred to as a promiscuous mode. In practice there is 99% chance that the network adapter driver will allow you only to get traffic destined for your MAC address. In that case you will need to resort to actively scanning the network subnet which is not 100% accurate and depending on how the network is implemented can be considered as a possible attack.
The simple way of scanning is sending ICMP requests (ping) to every IP address in the subnet and collecting data from those who send back the echo reply. This is not reliable because some hosts won't respond to ICMP echo request even if they are active. First thing you need is to find out your own IP address and the subnet mask, and calculate the range of possible addresses in your subnet. The range is obtained by using logical AND operator where operands are binary values of your IP address and subnet mask. This is an example from the program that calculates this for typical 192.168.1.1 subnet with 255.255.255.0 subnet mask (192.168.1.1/24 in CIDR notation):
Address: 192.168.1.1 11000000.10101000.00000001 .00000001
Netmask: 255.255.255.0 = 24 11111111.11111111.11111111 .00000000
Wildcard: 0.0.0.255 00000000.00000000.00000000 .11111111
Network: 192.168.1.0/24 11000000.10101000.00000001 .00000000
Broadcast: 192.168.1.255 11000000.10101000.00000001 .11111111
HostMin: 192.168.1.1 11000000.10101000.00000001 .00000001
HostMax: 192.168.1.254 11000000.10101000.00000001 .11111110
Then you would iterate through the range and ping every address. Another thing you can consider is listening for broadcast traffic such as ARP and collecting some of the information that way. I don't know what are you trying to make but you can't get many useful information this way, except for vendor of a host's network adapter.
Check my LAN Scan on Github. It does exactly what you want.
I recently used MMLANScan that was pretty good. It discovers IP, Hostname and MAC Address.
Bonjour have been around since 2002, have a look at it!
I mean, just look at their current tagline:
Bonjour, also known as zero-configuration networking, enables automatic discovery of devices and services on a local network using industry standard IP protocols. Bonjour makes it easy to discover, publish, and resolve network services with a sophisticated, yet easy-to-use, programming interface that is accessible from Cocoa, Ruby, Python, and other languages.

Resources