Next IPTables::IPv4::IPQueue #15            

Filter based on username

First, a function which takes a NetPacket::TCP object, and return the associated username and PID

    sub getuserfromtcp
    {
        my ($ip, $tcp) = @_;
        my ($user, $pid);

        open PROCTCP, "/proc/net/tcp" or die;
        scalar <PROCTCP>;   # throw away header

        while (<PROCTCP>)
        {
            s/^\s*//;
            my ($local, $localport, $remote, $remoteport,
                    $state, $uid, $inode) = (split /[\s:]+/)[1,2,3,4,5,11,13];

            $local  = inet_ntoa inet_aton htonl hex $local;
            $remote = inet_ntoa inet_aton htonl hex $remote;
            $localport  = hex $localport;
            $remoteport = hex $remoteport;

            if  # outbound packets
               (($ip->{src_ip} eq $local && $tcp->{src_port} eq $localport &&
                $ip->{dest_ip} eq $remote && $tcp->{dest_port} eq $remoteport) ||
                # inbound packets
                ($ip->{src_ip} eq $remote && $tcp->{src_port} eq $remoteport &&
                $ip->{dest_ip} eq $local && $tcp->{dest_port} eq $localport))
            {
                $pid = getpidfrominode $inode;  # see below
                $user = getpwuid $uid;
                last;
            }
        }

        close PROCTCP;
        return ($user || "", $pid || -1);
    }

    sub getpidfrominode
    {
        my $inode = shift;

        for my $dir (glob "/proc/[0-9]*") {
            for my $file (glob "$dir/fd/*") {
                my $link = readlink $file or next;
                return +(split "/", $file)[2]
                    if ($link eq "socket:[$inode]");
            }
        }

        return 0;
    }


            Next © 2003 Michael C. Toren