arpsponge/TODO
Steven Bakker ac7e271972 Intermediate check-in while redoing the control socket code.
Move as the server-side stuff to Server.pm, make communications
very simple, let the client side do all the conversions.
2011-03-31 16:16:10 +00:00

144 lines
4.0 KiB
Plaintext

@(#) $Id$
--------------------------------------------------
Tue Mar 29 23:13:42 CEST 2011
Internal storage of IP and MAC addresses is now done
as hex strings.
Need to rework the client/server protocol, so the
client also sends and receives HEX strings. See the
doc/command_mapping.txt file.
--------------------------------------------------
Wish list for future enhancements:
* setuid() to unprivileged user after opening relevant streams.
* use ithreads for better real-time behaviour:
- process
- learner
- sweeper
- prober
Process: Always active, listens to packets on the wire.
Handles ALIVE->PENDING and DEAD->ALIVE, manages
the ARP table.
Learner: stays active for "n" iterations, then finishes.
Prober: waits for Learner to finish, then every second, probes
the IPs that are PENDING, moving them to DEAD if necessary.
Sweeper: waits for Learner to finish, then periodically probes
"quiet" IPs.
--------------------------------------------------
Wed Mar 23 17:45:17 CET 2011
* DONE: speed improvements:
MAC and IP addresses already come in as hex strings.
We currently use "hex2ip" and "hex2mac" to convert them
before storing them in the relevant hashes.
Why not keep them in hex form and convert to proper strings
when needed?
Also, using hex form only, there's a smart algorithm
for checking whether an IP address is in a network, which
dramatically cuts down on the packet handling loop.
#!/usr/bin/perl
use M6::ARP::Util qw( :all );
use Benchmark qw( cmpthese );
use Net::IPv4Addr qw( :all );
my $ip = '193.194.136.192';
my $net = '193.194.136.128';
my $mask = '255.255.255.128';
my $len = 25;
if (1) {
my $hexip = ip2hex($ip);
my $hexnet = ip2hex($net);
cmpthese($count, {
'ipv4_in_network' =>
sub {
my $bool = ipv4_in_network($net, $mask, $ip);
},
'addr_in_net' =>
sub {
my $bool = addr_in_net(ip2hex($ip), ip2hex($net), $len)
},
'addr_in_net2' =>
sub {
my $bool = addr_in_net($hexip, $hexnet, $len)
},
});
}
sub addr_in_net {
my ($addr, $net, $len) = @_;
my $nibbles = int($len / 4);
if ($nibbles) {
if (substr($addr, 0, $nibbles) ne substr($net, 0, $nibbles)) {
return;
}
}
$len = $len % 4;
return 1 if !$len;
my $mask = 0xf & ~( 1<<(4-$len) - 1 );
my $a = hex(substr($addr,$nibbles,1));
my $n = hex(substr($net,$nibbles,1));
return ($a & $mask) == $n;
}
--------------------------------------------------
Thu Oct 7 09:16:50 CEST 2010
[Implemented first approach]
Add flood protection by somehow limiting the significance of
ARP queries if they all come from the same source.
Possible approaches:
* Add src_ip to the queue as well, and when the queue is full, collapse
entries of the same source if they are timed too closely together (say,
less than 750ms).
* Take list:
[t0, s1], [t1, s2], [t2, s2], [t3, s1], [t4, s2], [t5, s2]
* Sort by SRC, then TIMESTAMP:
[t0, s1], [t3, s1], [t1, s2], [t2, s2], [t4, s2], [t5, s2]
* Reduce closely spaced entries from the same SRC:
[t0, s1], [t3, s1], [t1, s2], [t4, s2]
* Sort by TIMESTAMP again:
[t0, s1], [t1, s2], [t3, s1], [t4, s2]
Advantage: works even if multiple sources are spamming us with
ARP queries.
Disadvantage: more state to keep, more processing when queue is
full
* Add "last_src" to Queue. An ARP is only added if the source
does not match last_src, OR the difference in timestamps is
> 750ms.
Advantage: less state to keep, less processing when queue is full
Disadvantage: multiple flooding sources can still cause sponging,
extra overhead for adding _each_ entry to the queue.