I think this is a pretty good IP sanity check snippet. If anyone has any comments please let me know!
use strict; { package IPSanity; use Socket; sub VerifyIP { chomp ($_); my ($a,$c,$d,$e,$f,$g); my $b = 0; if ($_ =~ /[a-zA-Z]+/) { print "$_\n"; $_ = gethostbyname($_); ($c,$d,$e,$f) = unpack('C4', $_); $_ = $c . "." . $d . "." . $e . "." . $f; } my @_temp = split(/\./,$_); $g = $#_temp; undef $_; if ($g ne '3') { print "Your IP address is malformed. I hope this isn't a +reflection of the user...\n"; exit; } foreach $a(@_temp) { if ($a =~ /\b\d\b|\b\d\d\b|\b\d\d\d\b/) { if ($a >= 0 && $a <= 255) { $_ = $_ . int($a); $_ = $_ . "." unless ($b > 2); $b++; } } } my $_IP = inet_aton( $_ ); length($_IP) or die "Sorry, '$_' is invalid.\n"; $_IP = inet_ntoa($_IP); print "$_IP is valid\n"; } } print "IP or Domain Name: "; $_ = <>; chomp; IPSanity->VerifyIP($_);

Replies are listed 'Best First'.
Re: IP Sanity Check
by grinder (Bishop) on Nov 11, 2002 at 20:39 UTC

    Note that it is perfectly valid to omit the penultimate zero value octets. You can play around with this in the following one-liner:

    % perl -MSocket -e 'print inet_aton shift' 65.0.0.65|hexdump 0000000 0041 4100 0000004 % perl -MSocket -e 'print inet_aton shift' 65.65|hexdump 0000000 0041 4100 0000004

    That is, there exists a shorthand for x.0.0.y and x.y.0.z (but not x.0.y.z). To complete the picture, you can also do this for 0.0.0.x, but that's hardly ever useful.

    Which is another reason why inet_aton is such a good idea.

    <update> Re your 01.1.1.010 problem, there is an issue you should be aware of. A leading 0 in a string, signals octal (assuming you're trying to interpret the string as a number). Consider the following:

    % perl -MSocket -le 'print inet_ntoa inet_aton shift' 01.1.1.10 1.1.1.10 % perl -MSocket -le 'print inet_ntoa inet_aton shift' 01.1.1.010 1.1.1.8

    Note that I don't see the behaviour you describe, although I'd be loathe to consider this the work of an interfering shell. If this is really a problem, I'd be inclined to do a simple cleanup prior to calling inet_aton with something like (untested):

    my $_IP = inet_aton( join '.', map { s/^0([1-9]\d*)$/$1/; $_ } # strip leading zeroes split( /\./, $original_ip) # of each octet );
    </update>
    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'
      the reason why i am doing it the way i am is so that an IP address that somehow gets to the system like '01.1.1.010' is successfully resolved to '1.1.1.10'. If you pass that to inet_aton directly I get (at least on this system with activestate perl version 5.6) 0.1.1.0.

      I hope I am not doing something utterly stupid...

      ; )

      www.loungeman.com
Re: IP Sanity Check
by jupe (Beadle) on Nov 11, 2002 at 18:50 UTC
    Oh yeah, mega props to jdporter for being a perl guru and all around nice guy (pointed me to the inet_aton for actually verifying the address).