#!/usr/bin/perl -w
#
##############################################################################
#
# File: knopspoof
#
# Purpose:  To provide an interface for fwknop to send spoofed authentication
#           packets to another fwknop instance running in pcap mode.  We need
#           this script because normally doing "use Net::RawIP;" requires
#           root access, and fwknop does not normally run as root when
#           executed in client mode.
#
# Author: Michael Rash (mbr@cipherdyne.org)
#
# Version: 0.9.0
#
# Copyright (C) 2004 Michael Rash (mbr@cipherdyne.org)
#
# License (GNU Public License):
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
#    USA
#
#  NOTE: This program has been depreciated in favor of fwknop using
#        Net::RawIP directly.
#
##############################################################################
#
# $Id: knopspoof,v 1.4 2005/09/13 02:23:08 mbr Exp $
#

use lib '/usr/lib/fwknop';
use Net::RawIP;
use strict;

my $file = $ARGV[0] || die "[*] Usage: $0 <file>";

my $ip_re = '(?:\d{1,3}\.){3}\d{1,3}';

open F, "< $file" or die "[*] Could not open $file: $!";
my $line = <F>;
close F;

if ($line =~ /^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\d+)\s+(\S+)/) {

    my $src   = $1;
    my $dst   = $2;
    my $proto = lc($3);
    my $sp    = $4;
    my $dp    = $5;
    my $msg   = $6;

    ### the file theat is read is constructed by fwknop
    die "[*] proto: $proto not supported.\n"
        unless ($proto eq 'udp' or $proto eq 'tcp' or $proto eq 'icmp');
    die "[*] src address must be a standard IP address."
        unless $src =~ /$ip_re/;
    die "[*] dst address must be a standard IP address."
        unless $dst =~ /$ip_re/;

    if ($proto eq 'udp') {
        my $rawpkt = new Net::RawIP({ip => {saddr => $src, daddr => $dst},
            udp =>{}});
        $rawpkt->set({ ip => { saddr  => $src,
                daddr  => $dst
            },
            udp => {
                source => $sp,
                dest   => $dp,
                data   => $msg,
            }
        });
        $rawpkt->send();
    } elsif ($proto eq 'icmp') {
        my $rawpkt = new Net::RawIP({ip => {saddr => $src, daddr => $dst},
            icmp =>{}});
        $rawpkt->set({ ip => { saddr  => $src,
                daddr  => $dst
            },
            icmp => {
                type => 0,
                code => 0,
                sequence => 0,
                data => $msg
            }
        });
        $rawpkt->send();
    } elsif ($proto eq 'tcp') {
        my $rawpkt = new Net::RawIP({ip => {saddr => $src, daddr => $dst},
            tcp =>{}});
        $rawpkt->set({ ip => { saddr => $src,
                daddr  => $dst
            },
            tcp => {
                ack => 1,
                source => $sp,
                dest   => $dp,
                data => $msg
            }
        });
        $rawpkt->send();
    }
} else {
    die "[*] Line not in the correct format.\n";
}
exit 0;
