Checking range of IP addresses

Discussion in 'Perl Misc' started by tim@roguevalleygroup.com, Jul 23, 2005.

  1. Guest

    A Perl script I wrote for a CGI is getting spammed. So I'm identifying
    and blocking ranges of IP addresses.

    At first I used IF statements like this:

    # 218.73.64.0 - 218.73.79.255 banned
    @ip = split(/\./, $ENV{'REMOTE_ADDR'});
    if ($ip[0] == 218 && $ip[1] == 73 && ($ip[2] >= 64 && $ip[2] <= 79)) {
    $banned = 1;
    }

    I know that's probably horrible programming and not very elegant. But
    it worked.

    Now the list I want to block is getting longer. I could continue to add
    IF statements but I feel that's probably stupid.

    Any suggestions how I might try to more elegantly process a list of
    banned IP's?

    Thanks!
    --Tim
    , Jul 23, 2005
    #1
    1. Advertising

  2. wrote:
    > Any suggestions how I might try to more elegantly process a list of
    > banned IP's?


    I'd look at CPAN. Net::IP sounds promising, doesn't it?

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Jul 23, 2005
    #2
    1. Advertising

  3. wrote:
    > A Perl script I wrote for a CGI is getting spammed. So I'm identifying
    > and blocking ranges of IP addresses.
    >
    > At first I used IF statements like this:
    >
    > # 218.73.64.0 - 218.73.79.255 banned
    > @ip = split(/\./, $ENV{'REMOTE_ADDR'});
    > if ($ip[0] == 218 && $ip[1] == 73 && ($ip[2] >= 64 && $ip[2] <= 79)) {
    > $banned = 1;
    > }
    >
    > I know that's probably horrible programming and not very elegant. But
    > it worked.
    >
    > Now the list I want to block is getting longer. I could continue to add
    > IF statements but I feel that's probably stupid.
    >
    > Any suggestions how I might try to more elegantly process a list of
    > banned IP's?


    Taking the chance that also this idea is stupid, I couldn't help
    reinventing the wheel:

    my $ip = '218.73.72.100';
    print "Banned\n" if banned($ip);

    sub banned {
    my $ip = shift;
    while (<DATA>) {
    if (/^(\S+)\s*-\s*(\S+)$/) {
    my $begin = pack 'C4', split /\./, $1;
    my $end = pack 'C4', split /\./, $2;
    my $packedip = pack 'C4', split /\./, $ip;
    return 1 if $packedip ge $begin and $packedip le $end;
    } else {
    chomp;
    return 1 if $ip eq $_;
    }
    }
    return 0;
    }

    __DATA__
    60.70.80.90
    218.73.64.0 - 218.73.79.255

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Jul 24, 2005
    #3
  4. Joe Smith Guest

    Gunnar Hjalmarsson wrote:

    > Taking the chance that also this idea is stupid, I couldn't help
    > reinventing the wheel:


    Your wheel doesn't work.

    > my $ip = '218.73.72.100';
    > print "Banned\n" if banned($ip);

    print "Still banned\n" if banned($ip);

    The second call to banned() does not operate the same way
    as the first call. Not good.

    -Joe
    Joe Smith, Jul 24, 2005
    #4
  5. Joe Smith wrote:
    > Gunnar Hjalmarsson wrote:
    >> Taking the chance that also this idea is stupid, I couldn't help
    >> reinventing the wheel:

    >
    > Your wheel doesn't work.
    >
    >> my $ip = '218.73.72.100';
    >> print "Banned\n" if banned($ip);

    >
    > print "Still banned\n" if banned($ip);
    >
    > The second call to banned() does not operate the same way
    > as the first call. Not good.


    Well, I never claimed it would work for multiple calls. Whether one call
    is sufficient depends on how it's supposed to be used, doesn't it? The
    OP seemed to just need a way to decide if REMOTE_ADDR would get access
    to a script, and there is only one REMOTE_ADDR ...

    The main point with posting the code snippet was to call the OP's
    attention to how the pack() function can be used.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Jul 24, 2005
    #5
  6. Guest

    Gunnar Hjalmarsson wrote:

    > Taking the chance that also this idea is stupid, I couldn't help
    > reinventing the wheel:


    Thank you for both of your replies. I'd not previously heard of Net::IP
    and I'm studying it.

    I also like your new wheel, even though it doesn't handle multiple
    calls. I admit knowing nothing about this pack() function. I will study
    your code until I understand it.

    Thanks again!

    --Tim
    , Jul 25, 2005
    #6
  7. wrote:
    > I also like your new wheel, even though it doesn't handle multiple
    > calls.


    If you find the approach useful, a natural application of it is to store
    and maintain the list of IP ranges in a separate file, and let the
    banned() function open/close the file. Doing so would take care of 'the
    multiple call issue' (even if I don't think that's an issue in your case).

    > I admit knowing nothing about this pack() function. I will study
    > your code until I understand it.


    To be honest, I'm not too comfortable with it either, but I have learned
    that it's useful for comparing and sorting IP addresses. Please feel
    free to ask here if you get stuck.

    > Thanks again!


    You're welcome.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Jul 25, 2005
    #7
  8. Anno Siegel Guest

    Gunnar Hjalmarsson <> wrote in comp.lang.perl.misc:
    > wrote:
    > > A Perl script I wrote for a CGI is getting spammed. So I'm identifying
    > > and blocking ranges of IP addresses.


    [...]

    > Taking the chance that also this idea is stupid, I couldn't help
    > reinventing the wheel:
    >
    > my $ip = '218.73.72.100';
    > print "Banned\n" if banned($ip);
    >
    > sub banned {
    > my $ip = shift;
    > while (<DATA>) {
    > if (/^(\S+)\s*-\s*(\S+)$/) {
    > my $begin = pack 'C4', split /\./, $1;
    > my $end = pack 'C4', split /\./, $2;
    > my $packedip = pack 'C4', split /\./, $ip;
    > return 1 if $packedip ge $begin and $packedip le $end;

    ^^^^^^^^^^^
    > } else {
    > chomp;
    > return 1 if $ip eq $_;

    ^^^^^^^^^^^
    > }
    > }
    > return 0;
    > }


    Any reason why you don't just

    return $packedip ge $begin and $packedip le $end;

    and

    return $ip eq $_;

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Jul 25, 2005
    #8
  9. Anno Siegel Guest

    Joe Smith <> wrote in comp.lang.perl.misc:
    > Gunnar Hjalmarsson wrote:
    >
    > > Taking the chance that also this idea is stupid, I couldn't help
    > > reinventing the wheel:

    >
    > Your wheel doesn't work.
    >
    > > my $ip = '218.73.72.100';
    > > print "Banned\n" if banned($ip);

    > print "Still banned\n" if banned($ip);
    >
    > The second call to banned() does not operate the same way
    > as the first call. Not good.


    That's easily fixed. Change

    sub banned {
    my $ip = shift;
    while (<DATA>) {
    # ...
    }
    }

    to

    {
    my @data;
    sub banned {
    @data = <DATA> unless @data;
    my $ip = shift;
    for ( @data ) {
    # ...
    }
    }
    }

    Anno

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Jul 25, 2005
    #9
  10. Anno Siegel wrote:
    > Gunnar Hjalmarsson wrote:
    >>
    >> return 1 if $packedip ge $begin and $packedip le $end;

    > ^^^^^^^^^^^
    >> } else {
    >> chomp;
    >> return 1 if $ip eq $_;

    > ^^^^^^^^^^^
    >
    > Any reason why you don't just
    >
    > return $packedip ge $begin and $packedip le $end;
    >
    > and
    >
    > return $ip eq $_;


    No reason whatsoever. ;-)

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
    Gunnar Hjalmarsson, Jul 25, 2005
    #10
  11. Guest

    To Gunnar and others:

    That snippet of code and the following comments turned out to be what I
    needed. I modified to suit my needs and it's working great.

    Thanks!
    , Jul 26, 2005
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stephen Briley
    Replies:
    3
    Views:
    496
    Paul McGuire
    Feb 16, 2004
  2. Replies:
    46
    Views:
    949
    Antoon Pardon
    Jul 25, 2006
  3. namespace1
    Replies:
    3
    Views:
    882
  4. Lambda
    Replies:
    2
    Views:
    382
    James Kanze
    Jul 16, 2008
  5. Adam Funk
    Replies:
    12
    Views:
    650
    Adam Funk
    Jul 5, 2005
Loading...

Share This Page