Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

gethostbyname returns the proper IP address for valid domain names, fails for invalid domain names, but if I feed it a numeric invalidity like 1.1.1 or 9.9.9, it happily returns 1.1.0.1 or 9.9.0.9

Makes it kind of hard to check user input. What am I missing??

$name = "9.9.9";

@temp = gethostbyname($name);
unless (@temp) {
print "bad name\n";
exit;
}
$num = join(".",unpack("C4", @temp4));

print "num is $num for name $name\n";

Thanks for any assistance!
  • Comment on gethostbyname("1.1.1") returns 1.1.0.1 ????

Replies are listed 'Best First'.
Re: gethostbyname("1.1.1") returns 1.1.0.1 ????
by Abigail-II (Bishop) on Mar 06, 2003 at 00:53 UTC
    What makes you think that 1.1.1 or 9.9.9 are invalid representations of IP addresses? They *are* valid. If you're using the dotted number notation, there are at most 4 numbers. But if there are 3 or 2, the one or two numbers before the last are assumed to be 0. Hence, gethostbyname is quite correct, and you are incorrect by assuming to have it fed illegal input.

    Abigail

      To prove Abigail-II is right, just do a
      ping 127.1
      
      and it would ping 127.0.0.1 for you.
      if there are 3 or 2, the one or two numbers before the last are assumed to be 0.
      While this is "true", it obscures the fact that the range of the last part depends on how many parts there are.
      Parts:Range of last part:
      428-1 = 255
      3216-1 = 65535
      2224-1 = 16777215
      1232-1 = 4294967295
      Although, of course, the usual restrictions on legal addresses apply.

      jdporter
      The 6th Rule of Perl Club is -- There is no Rule #6.

        Although it is possible that I am not understanding your point, I believe your correction is incorrect.

        127.1 is 127.0.0.1. There is no range. 127.1.1 is 127.1.0.1. Again, there is no range. (Well, to be exact, there is a range of 1) The spec allows zero's before the last to be left out as a convenient expression form, not as a method of defining subnet's or 'range'. IPv6 has a similar form that allows a single '::' to be specified within the address that indicates that all missing numbers at this location are 0. Again, it is a convenient expression form, and nothing more.

      That's very interesting, I hadn't heard about that before. Just out of curiosity, do you happen to know the RFC (or whatever kind of document it is) that says all the different ways you can represent an IP address?

        I don't think there is an RFC that explicitly explains this, the reason it works is that if you take the address 127.1/24, the netmask specifies that the first 24 bits are the network address and the rest are the host address, the 127 falls within the network address part, setting the appropriate bits to one, and leaves all the other bits in the network part (even the unspecified ones) as zeros, since there is no third state that can represent the undefined value.

        So, the way I understand it, it works something like this:

        • 127.1 gets translated to binary and becomes 0111111100000001
        • The 24 bit netmask tells us that the host part is the last 8 bits, or 00000001
        • That leaves the other 24 bits for the network part, padded with zeros we get 011111110000000000000000
        • Stick these back together and you get 01111111000000000000000000000001
        • Split this long binary number into 4 bytes, and convert them back to decimal, and it leaves you with 127.0.0.1
Re: gethostbyname("1.1.1") returns 1.1.0.1 ????
by Limbic~Region (Chancellor) on Mar 06, 2003 at 00:42 UTC
    If you are trying to validate user input for an IP address, I suggest you read this entire thread. There are suggestions on what to do and what not to do.

    Cheers - L~R

Re: gethostbyname("1.1.1") returns 1.1.0.1 ????
by fokat (Deacon) on Mar 06, 2003 at 01:59 UTC

    Take a look at NetAddr::IP for the validation part. It will even call gethostbyname for you.

    Best regards

    -lem, but some call me fokat

Re: gethostbyname("1.1.1") returns 1.1.0.1 ???? (man inet)
by tye (Sage) on Mar 17, 2003 at 05:24 UTC

    Someone asked me to review a tutorial they were writing on internet addresses which lead me to put a section from "man inet" on my scratchpad (it's been there for months):


    Internet Addresses:

    Values specified using dot notation take one of the following forms:

    a.b.c.d
    a.b.c
    a.b
    a
    

    When four parts are specified, each is interpreted as a byte of data and assigned, from left to right, to the four bytes of an Internet address.

    When a three-part address is specified, the last part is interpreted as a 16-bit quantity and placed in the right-most two bytes of the network address. This makes the three-part address format convenient for specifying Class B network addresses as in 128.net.host.

    When a two-part address is supplied, the last part is interpreted as a 24-bit quantity and placed in the right-most three bytes of the network address. This makes the two-part address format convenient for specifying Class A network addresses as in net.host.

    When only one part is given, the value is stored directly in the network address without any byte rearrangement.

    All numbers supplied as parts in dot notation can be decimal, octal, or hexadecimal, as specified in the C language (i.e., a leading 0x or 0X implies hexadecimal; a leading 0 implies octal; otherwise, the number is interpreted as decimal).


    This is from a pretty old Unix system (HP-UX).

                    - tye