LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   valid check of IP in C++ code (https://www.linuxquestions.org/questions/linux-software-2/valid-check-of-ip-in-c-code-905248/)

Anandkpda 09-27-2011 10:20 AM

valid check of IP in C++ code
 
Hi,

I want to check & validate given IP address in my Code. Can Checked with inet_addr & inet_itoa fns().
both will pass if IP address is xx.xx, as this is invalid.

can anybody explain me the usage of ping in the C++ code.

thanks,
Anand

Nominal Animal 09-27-2011 01:19 PM

There are two types of IP addresses: IPv4 and IPv6.

I recommend you split the checking into two phases:
  1. String to address conversion
    IPv4 addresses are 32 bits long, IPv6 addresses are 128 bits long.
    Since IPv4 addresses (0xXXYYZZWW) can be mapped to IPv6 addresses (0:0:0:0:ffff:XXYY:ZZWW) you can have just one string conversion function, which always returns an IPv6 address.
    Or, you can use the functions provided by your C or C++ library, for example trying each one if they work (without error).
  2. Address check
    As described in the Wikipedia articles for IPv4 and IPv6 and documents they link to, there are certain address ranges that have a special purpose. If you wish to classify or check for these, you should do it on the binary data, not on a string.

ping is an external program, which sends an ICMP echo request to the desired IP address, optionally tracing the route (by setting a flag which indicates every device on the route should also send a response to the originator). It is quite nontrivial to implement ping in your own program -- and on many architectures it requires superuser privileges, too. Usually it is much better to execute the command with desired command line options, and parse the output instead.

Note that you absolutely cannot rely on ping, and you really should not be considering using it here. ICMP echo packets are routinely dropped by many if not most firewalls. IP addresses can also be faked (called IP spoofing); you do not want your software to be used as a part of a DDOS (distributed denial-of-service) attack, where an attacker spoofs the victim's address, and connects to your software, and your software then sends the DOSing ICMP echo packets like a well-trained goon.

A reverse DNS lookup (where you look up the name corresponding to the IP address you know) may be useful, although not all IP addresses are named. Most IP addresses can be geolocated (due to the way they are assigned); you might use a IP geolocation service instead of ping.

Finally, an IP address is not an identifying factor. NAT (network address translation) is used in a lot, which means many users share an IP address (or more frequently, a pool of IP addresses). For home users, service providers do not usually give a fixed IP address, but simply the next available IP address from their IP address pool (although many at least try to give the same IP address if it is still available). An IP address really is an ephemeral address, which you can only rely on when you have an open connection (stream or datagram socket) to it, really.

Anandkpda 09-28-2011 03:34 AM

thanks a lot. it means there is no single OS call to validate.

Could you please elaborate the 2nd check(Address check)

Nominal Animal 09-28-2011 01:20 PM

For the address validity check, consider the reserved IP address list.

The interpretation of what should be allowed and what should not be depends on how you intend to use the IP address. For example, if it is a host IPv4 address, you will want to exclude all 0.*.*.*, 169.254.*.*, 192.0.2.*, 198.18-19.*.*, 198.51.100.*, 203.0.113.*, 224-239.*.*.*, and 255.255.255.255, but accept all other addresses. If it should be an external host, then you can also exclude 127.*.*.*, since they are always local addresses (but it usually makes no sense to specifically ban those). 240-254.*.*.* are still unassigned, except 255.255.255.255 is the global broadcast address; right now only IP spoofers use those addresses, but they may be legitimately used in the future.

In the general case, excluding all-zeros and all-ones should be enough (and should be done when parsing an address, not as a separate step). Everything else is a valid IP address at least in some contexts. This is also the reason there is no single OS call.

Because IP spoofing is so easy, you cannot rely on any IP address on being valid (unless you have local firewall rules applied that validate them, for example by filtering them per interface). Linux, and Unix-like systems in general, do not normally apply checks like this, because it is policy, and is the users'/administrators' responsibility.

To put it bluntly, there is no reason why your application should not accept say IPv4 address 192.168. If the user/admin specifies that to your application, then that is what your application should use. The same obviously applies to IPv6. If the user/admin wishes to avoid the IPv4 address ranges (for example due to attacks) I listed above, they can trivially set up iptables DROP rules in their kernel.

I've written some networking software, both client and server side, mostly in C (GNU C and/or C99), and I've never needed and IP address validation function. If it can be parsed correctly, I'm happy with it. If it happens to be completely bogus, let the user/admin worry about it. If you try to cuddle your users (like certain commercial OSes do, to a very large extent), you simply end up limiting the number of choices available to the user. And I for one do not like that one bit.

However, I don't know how you will be using the IP addresses, so I don't want to claim you should never try to validate them. I just cannot think of any good reason right now. But if you need to, the beginning of this message should point you the right direction. If you need the validation in an application or a library, you should consider putting the rules in configuration files (separate for IPv4 and IPv6), so that the users can modify them if a need arises.


All times are GMT -5. The time now is 11:18 AM.