Я пытаюсь создать небольшую службу, которая отслеживает и убивает сокеты, у которых есть ПЛАВНИК флаг. Я могу получить их с tcpdump (Я также пробовал tcp [13] & 1):
tcpdump "tcp[tcpflags] & tcp-fin != 0"
tcpkill предполагается использовать тот же интерфейс, что и tcpdump, но это не работает. Я пробовал кучу команд, но это должно быть просто (-i eth0 необязательно):
tcpkill -9 "tcp[tcpflags] & tcp-fin != 0"
Что говорит (но ничего другого, успешно tcpkill выводит данные):
tcpkill: прослушивание eth0 [tcp [tcpflags] & tcp-fin! = 0]
Если посмотреть на исходный код, он должен передать в pcap правильный фильтр (между скобками []). Использование Perl-скрипта с Net :: Pcap Я могу определить, что фильтр работает нормально. Я не знаю, что я делаю не так, или проблема в более старой версии tcpkill / pcap. Любая помощь с tcpkill или помощь с использованием perl Net :: Pcap убить сокеты будут оценены. Спасибо!
#!/usr/bin/perl
use strict;
use warnings;
use Net::Pcap;
my $err = '';
my $dev = 'eth0';
my ($address, $netmask);
Net::Pcap::lookupnet($dev, \$address, \$netmask, \$err);
my $pcap = Net::Pcap::open_live($dev, 1500, 1, 0, \$err);
my $filter;
Net::Pcap::compile($pcap, \$filter, "tcp[tcpflags] & tcp-fin != 0", 0, $netmask);
Net::Pcap::setfilter($pcap, $filter);
while(1)
{
Net::Pcap::loop($pcap, 1, \&process_packet, "packet found");
}
Net::Pcap::close($pcap);
sub process_packet
{
my($user_data, $header, $packet) = @_;
print "$user_data\n";
}
exit 0;
Глядя на исходный код для tcpkill, он использует libnet для генерации пакета (ов) RST, чтобы уничтожить данное TCP-соединение. Я не уверен, почему он не работает (хотя проверка версии PCAP, для которой он был создан, - отличное место для начала). Вы также можете использовать tcpdump для поиска пакетов RST, которые он должен отправлять.
Что касается реализации эквивалента в Perl, мне однажды пришлось сделать нечто подобное. Ниже приведен (непроверенный!) Код, который может указать вам правильное направление.
use NetPacket::Ethernet;
use NetPacket::IP;
use NetPacket::TCP;
use Net::RawIP;
... (the rest of your script) ...
sub process_packet {
my ($user_data,$header,$packet) = @_;
my $ethernet_frame = NetPacket::Ethernet::strip($packet);
my $ip_packet = NetPacket::IP->decode($ethernet_frame);
my $tcp = NetPacket::TCP->decode($ip_packet->{data});
my $reset_packet = new Net::RawIP;
$reset_packet->set({
ip => {
saddr => $ip_packet->{dest_ip},
daddr => $ip_packet->{src_ip}
},
tcp => {
source => $tcp->{dest_port},
dest => $tcp->{src_port}
},
rst => 1,
seq => $ip->{acknum},
data => 'access denied'
});
$reset_packet->send();
}
tcpkill более усовершенствован с точки зрения попытки определить правильный порядковый номер, для чего нужны флаги -1..9. Вы пробовали использовать другие значения для этого флага?