Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm trying to create a small service that monitors and kills sockets which have the FIN flag. I can get them with tcpdump (I also tried tcp[13] & 1):

tcpdump "tcp[tcpflags] & tcp-fin != 0"

tcpkill is suppose to use the same interface as tcpdump, but it isn't working the same. I've tried a bunch of commands, but it should just be (-i eth0 optional):

tcpkill -9 "tcp[tcpflags] & tcp-fin != 0"

Which says (but nothing else, successful tcpkill outputs data):

tcpkill: listening on eth0 [tcp[tcpflags] & tcp-fin != 0]

Looking at the source, it should be passing the correct filter to pcap (between the [ ] brackets). Using a perl script with Net::Pcap I can determine the filter works fine. I don't know what I'm doing wrong, or if it's an older version of tcpkill/pcap that's an issue. Any help with tcpkill or help using perl's Net::Pcap to kill sockets would be appreciated. Thanks!

#!/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;
share|improve this question
1  
Just out of curiosity, what is the purpose or goal behind this? If it's just "because I can" or "because I want to", that's cool. But I'm wondering what the actual problem you're trying to solve is. If you're just concerned with connections that you've FIN'ed and that haven't closed yet, changing OS TCP/IP paramters (like 'tcp_fin_timeout' on Linux) may be a better solution. –  Christopher Cashell Aug 2 '10 at 17:22
add comment

1 Answer

up vote 0 down vote accepted

Looking at the source code for tcpkill, it uses libnet to generate a RST packet(s) to kill a given TCP connection. I'm not sure why it's not working (though verifying the PCAP version it was built against is a great place to start). You can also use tcpdump to look for the RST packets it should be sending out.

Regarding implementing the equivalent in Perl, I once had to do something sort of similar. Below is (untested!) code which might point you in the right direction.

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 is more refined in terms of attempting to figure out the correct sequence number, which is what the -1..9 flags are for. Have you tried using different values for that flag?

share|improve this answer
    
Good to know, thanks. I started using pycap, which seemed to be working at least half the time, but I wasn't sure. I'm going to give these suggestions a try (perl and figuring out sequence). Something I was wondering is if I should ONLY be sending the RST packet to the OTHER servers, or just my server, or both my server and the others? tcpkill seems to just reverse the destination and source? Would that be circular? –  Eric Muyser Jul 30 '10 at 2:55
    
When you say you want to "kill FINished sockets", what is your goal? What OS are you using? With tcpkill, you're only initiating a tear down of the TCP session. After the RST is sent, you're waiting on the TCP/IP stack timers to clear out the resources on the local end. Alternatively, BSD systems have a utility called 'tcpdrop', which instruct the kernel to drop the connection. It too initiates a RST packet, but alleviates the need to figure out the correct TCP sequence number in user space (i.e. the TCP/IP stack knows). It also seems to be quicker about clearing out the local resources. –  chuckx Jul 30 '10 at 9:10
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.