my @ip_addresses = qw(123.123.123.123); # change this to your server ip
my $interface = "eth1"; # change this to the interface you are sniffing
my $logfile = "/var/log/mailproto.log";
my $port = "25";
# Prepares pcap and compiles filter.
sub cap_pkt
{
my ($pcap,$err,$mask,$net,$filter2);
my $snaplen = 4096;
my $promisc = 1;
my $timeout = 500;
# get netmask for filter
if ((Net::Pcap::lookupnet($interface, \$net, \$mask, \$err)) == -1 )
{
die ("Net::Pcap::lookupnet failed ($err) for device '$interface'\n");
}
# open pcap.
$pcap = Net::Pcap::open_live($interface, $snaplen, $promisc, $timeout, \$err);
if (!($pcap))
{
die ("can't create packet fd ($err) on '$interface'\n");
}
else
{
print "dumping on '$interface'\n";
}
# make filter struct
if (Net::Pcap::compile($pcap, \$filter2, $filter, 1, $mask) != '0')
{
die ("broken filter ($filter)\n");
}
# apply
Net::Pcap::setfilter($pcap, $filter2);
return $pcap;
}
# Pcap callback function. Gets called by Net::Pcap::loop
sub proc_pkt
{
my($user_data, $hdr, $pkt) = @_;
# Extract packet information.
my ($user,$msg);
my $eth = NetPacket::Ethernet->decode($pkt);
my $ip = NetPacket::IP->decode($eth->{data});
my $tcp_obj = NetPacket::TCP->decode(ip_strip(eth_strip($pkt)));
my $ofh = select LOG;
my $dst = $ip->{dest_ip};
my $src = $ip->{src_ip};
my @data = split(/\n/,$tcp_obj->{data});
# For each line of captured text, prepend the IP address to which the
# text was sent, and write it to the logfile.
# This makes it easier to see which text is part of
# which conversation stream when looking at the log file.
foreach(@data)
{
my $data = $_;
$| = 1;
print LOG "$src->$dst | $data\n";
$| = 0;
select $ofh;
}
}
# Cleanup function. After an interrupt signal was captured, make sure we clean
# up after ourselves.
sub cleanup
{
print "cleaning up...";
Net::Pcap::close($pcap);
close(LOG);
}
# Entry point -----------------------------------------------------------------
# output file
open (LOG,">>$logfile");
# daemonize
exit if (fork());
exit if (fork());
sleep 1 until getppid() == 1;
print "mailsniff $$ running...\n";
# Trap interrupts so we can cleanup before exiting.
$SIG{'INT'} = \&cleanup;
# Building up the pcap filter string.
# This section will build up the ip filter list based on the
# list of ip addresses defined in the @ip_addresses array.
my $ip_filters = "";
foreach my $ip(@ip_addresses)
{
$ip_filters .= "(src host $ip) or (dst host $ip) or";
}
# Cut off the last 'or'.
chop($ip_filters);
chop($ip_filters);
# Now compose the rest of the filter.
$filter = "tcp and ( ($ip_filters) and (dst port $port) )";
# Start the pcap sniffing loop.
$pcap = &cap_pkt;
if (!($pcap))
{
die ("cant capture\n");
}
Net::Pcap::loop($pcap, -1, \&proc_pkt, 0);