7 require './access_list.pl';
13 if ($range =~ /^(\d+)\.\.(\d+)$/) {
21 my ($elem, $ranges) = @_;
23 for my $range (@$ranges) {
24 if ($range =~ /^(\d+)\.\.(\d+)$/) {
25 return 1 if ($elem >= $1 && $elem <= $2);
27 return 1 if ($elem == $range);
37 vec($bits, fileno($fh), 1) = 1;
42 # Find what ports we need to listen on
44 for my $e (@Config::access_list) {
45 for my $r (@{$e->{'ports'}}) {
46 for my $p (expand_range($r)) {
51 my @ports = sort { $a <=> $b } keys %port_hash;
53 # Open a socket for each port
55 my $udp = getprotobyname("udp");
58 socket($sock, PF_INET, SOCK_DGRAM, $udp);
59 bind($sock, sockaddr_in($p, INADDR_ANY));
63 my $sendsock = Net::RawIP->new({udp => {}});
65 print "Listening on " . scalar @ports . " ports.\n";
69 my $rin = fhbits(@socks);
72 my $nfound = select($rout=$rin, undef, undef, undef);
73 for my $sock (@socks) {
74 next unless (vec($rout, fileno($sock), 1) == 1);
77 my $addr = recv($sock, $data, 8192, 0); # jumbo broadcast! :-P
78 my ($sport, $saddr) = sockaddr_in($addr);
79 my ($dport, $daddr) = sockaddr_in(getsockname($sock));
80 my $size = length($data);
82 # We don't get the packet's destination address, but I guess this should do...
83 # Check against the ACL.
85 for my $rule (@Config::access_list) {
86 if (match_ranges($dport, $rule->{'ports'}) &&
87 match_ranges($size, $rule->{'sizes'})) {
93 print "$dport, $size bytes => filtered\n";
98 for my $net (@Config::networks) {
99 next if (Net::CIDR::cidrlookup(inet_ntoa($saddr), $net));
101 my ($range) = Net::CIDR::cidr2range($net);
105 print inet_ntoa($saddr), ", $dport, $size bytes => $broadcast\n";
109 saddr => inet_ntoa($saddr),