Next How to Avoid Writing Kernel Modules
© 2004 Michael C. Toren
#19            

iptables libipq: Customizing REJECT packets (II)

    ...

    my @hops = qw(10.0.0.1  10.0.0.2  10.0.0.3);

    while (1) {
        my $msg = $ipq->get_message;
        my $ipin = NetPacket::IP->decode($msg->payload);
        my $hop = $hops[ $ipin->{ttl} -1 ];

        unless ($hop) {
            $ipq->set_verdict($msg->packet_id, NF_ACCEPT);
            next;
        }

        my $ipout = NetPacket::IP->decode;
        $ipout->{ver}       = IP_VERSION_IPv4;
        $ipout->{hlen}      = 5;
        $ipout->{tos}       = 0xC0;
        $ipout->{len}       = 0;
        $ipout->{id}        = int rand(0xFFFF);
        $ipout->{foffset}   = 0;
        $ipout->{proto}     = IP_PROTO_ICMP;
        $ipout->{src_ip}    = $hop;
        $ipout->{dest_ip}   = $ipin->{src_ip};
        $ipout->{options}   = "";
        $ipout->{flags}     = 2;
        $ipout->{ttl}       = 255;

        my $icmp = NetPacket::ICMP->decode;
        $icmp->{type}       = ICMP_TIMXCEED;
        $icmp->{code}       = 0;
        $icmp->{data}       = "\0"x4 . substr($ipin->encode, 0, $ipin->{hlen}*4+8);

        $ipout->{data}  = $icmp->encode;
        Net::RawSock::write_ip($ipout->encode);
        $ipq->set_verdict($msg->packet_id, NF_DROP);    # Drop the original packet
    }