tcpdump mailing list archives

Re: Sniffing ranges of ips


From: Jefferson Ogata <Jefferson.Ogata () noaa gov>
Date: Fri, 19 Nov 2004 08:14:51 -0500

MMatos wrote:
I want to write a little program that analyses packets within a given ip range.

My current problem is to set a filter that work with ip ranges.

For example I want to dump all traffic that arrives to my box from ips 192.168.2.15 to 192.168.2.40 I could write all the ips in the range but that's not a good solution, so how can implement that filter correctly using the range?

some kind of
$tcpdump "src 192.168.2.15/40"           :)

Use the attached perl scripts, e.g.:

tcpdump [options] `./genrange.pl 192.168.2.15 192.168.2.40 | ./aggregate.pl | ./iptcpdump.pl src`

--
Jefferson Ogata <Jefferson.Ogata () noaa gov>
NOAA Computer Incident Response Team (N-CIRT) <ncirt () noaa gov>
#!/usr/bin/perl -wT

my $low = shift;
my $high = shift;

die "usage: $0 low-addr high-addr" unless (defined ($high));

$low = &a2n ($low);
$high = &a2n ($high);

for (my $ip = $low; $ip <= $high; ++$ip)
{
    print &n2a ($ip), "\n";
}

sub a2n
{
    return unpack ('N', pack ('C4', split (/\./, $_[0])));
}

sub n2a
{
    return join ('.', unpack ('C4', pack ('N', $_[0])));
}

#!/usr/bin/perl -wT

my %in;
my %out;

while (defined ($_ = <STDIN>))
{
    chomp;
    my $line = $_;
    s/#.*$//;
    s/\s+//;
    next unless (length);
    die (qq{$.:$line}) unless (/^([\d\.]+)(?:\/(\d+))?$/);
    my ($ip, $bits) = ($1, $2);
    $bits = 32 unless (defined ($bits));
    $ip = &a2n ($ip);
    $in{$ip} = $bits;
}

# Eliminate subnets.
foreach (keys (%in))
{
    next unless (exists ($in{$_}));
    my $mask = &mask ($in{$_});
    foreach my $sub (keys (%in))
    {
        next if ($sub == $_);
        if (($sub & $mask) == $_)
        {
            delete ($in{$sub});
        }
    }
}

# Aggregate what's left.
while (scalar (keys (%in)))
{
    foreach (sort (keys (%in)))
    {
        next unless (exists ($in{$_}));
        my $bits = $in{$_};
        my $node = 1 << (32 - $bits);
        my $other = $_ ^ (1 << (32 - $bits));
        if (exists ($in{$other}))
        {
            delete ($in{$_});
            delete ($in{$other});
            my $super = $_ & &mask ($bits - 1);
            $in{$super} = $bits - 1;
        }
        else
        {
            $out{$_} = $bits;
            delete ($in{$_});
        }
    }
}

foreach (sort (keys (%out)))
{
    my $bits = $out{$_};
    print &n2a ($_), '/', &n2a (&mask ($bits)), qq{\n};
}


sub a2n
{
    return unpack ('N', pack ('C4', split (/\./, $_[0])));
}

sub n2a
{
    return join ('.', unpack ('C4', pack ('N', $_[0])));
}

sub mask
{
    my $bits = shift;
    return 0xffffffff if ($bits > 32);
    return 0 if ($bits < 1);
    return ~((1 << (32 - $bits)) - 1);
}


#!/usr/bin/perl -wT

my @expr;

my $qualifier = shift;
if (defined ($qualifier))
{
    $qualifier =~ s/^\s+//;
    $qualifier =~ s/\s+$//;
    $qualifier .= ' ';
}
else
{
    $qualifier = '';
}

while (defined ($_ = <STDIN>))
{
    chomp;
    my $line = $_;
    s/#.*$//;
    s/\s+//;
    next unless (length);
    die (qq{$.:$line}) unless (/^([\d\.]+)\/([\d\.]+)$/);
    my ($addr, $mask) = ($1, $2);
    if ($mask eq '255.255.255.255')
    {
        push (@expr, "${qualifier}host $addr");
    }
    else
    {
        push (@expr, "(${qualifier}net $addr mask $mask)");
    }
}

print join (' or ', @expr), "\n";

-
This is the tcpdump-workers list.
Visit https://lists.sandelman.ca/ to unsubscribe.

Current thread: