#!/usr/bin/perl

# This is APSEND v1.57
# It comes under the GPL, have a look at the file COPYING for more
# information. You should also read the README file.

# Include a few modules...
use Getopt::Long;
use Net::RawIP;
use aattacks;
use aparse_file;
use asubs;
use ahelp;
use ainfo;
use aconstruct;
use asocket;


$VERSION=1.57;

# Define this constant please...
# Random source/dest port range
$field=65535;

# Here are the possible errors...
# We use the number of the element+1 (the error) as the exit code.
# For example we get the exit code of 1 if the error
# "Not enough command-line options (use at least -d, -x or --listen) !!!"
# occured.
@error=(
"Not enough command-line options (use at least -d, -x or --listen) !!!",
"Please specify not more than one attack at once !!!",
"You cannot use --listen and --connect at the the time !!!",
"Unsopported socket protocol. Please use TCP or UDP only !!!"
);


# No auto abbreviation, because I'd get conflicts with the
# command-line options if I would use it. If you still get errors
# then you should have a look if the variable POSIXLY_CORRECT is set
# and if it is you should unset it.
Getopt::Long::Configure('no_auto_abbrev');

# Catch CTRL-C and exit...
$SIG{INT}=\&ctrl_exit;

# Set autoflush, because we need no buffering...
$|=1;

GetOptions(
"help|h|?"=>\&help,          # Check if anyone needs help...
"show"=>\&icmp_show,         # Show ICMP types and codes...
"x"=>\&show_net_dev,         # Show network devices and exit...

"f|file=s"=>\$file,          # Script file (not implemented)

# The different TCP flags...
"syn"=>\$SYN,		# SYN flag
"ack"=>\$ACK,		# ACK flag
"urg"=>\$URG,		# URG flag
"fin"=>\$FIN,		# FIN flag
"rst"=>\$RST,		# RST flag
"psh"=>\$PSH,		# PUSH flag

# Protocol (like in /etc/protocols)
# Currently supported protocols:
# IP (0), ICMP (1), TCP (6), UDP (17)
# Please notify: You can build every possible
# packet using the --generic option!
"protocol=s"=>\$protocol,

# Source/Destination IP
# Use --source=0 for random source IP.
"source|s=s"=>\$saddr, 
"destination|dest|d=s"=>\$daddr,

# (random) source/destination port for TCP/UDP
"source-port|sp|b=i"=>\$sport,
"dest-port|dp|p=i"=>\$dport,
"rs"=>\$rsport,
"rd"=>\$rdport,

# Tpye of Service (ToS), Time to Live (TTL) and Total Length (tot_length)
"tos|o=s"=>\$tos,
"ttl|t=i"=>\$ttl,
"tot=i"=>\$tot,

# Fragmentation/Data offset, TCP/IP/UDP/ICMP checksum and UDP length
"frag-off|frag|fo=s"=>\$frag_off,
"data-off|doff|do=s"=>\$data_off,
"tcheck=s"=>\$tcheck,
"ipcheck=s"=>\$ipcheck,
"ucheck=s"=>\$ucheck,
"icheck=s"=>\$icheck,
"len=s"=>\$len,

# ACK number, SEQ number for TCP/ICMP, URG pointer and window size
"ack-num|a=s"=>\$ack_seq,
"seq-num|seq|n=s"=>\$seq,
"urg-ptr|u=s"=>\$urg_ptr,
"window|w=s"=>\$window,

# Ethernet frame options
"eth-device=s"=>\$ethdev,
"ems|eth-mac-source=s"=>\$smac,
"emd|eth-mac-dest=s"=>\$dmac,
"rems"=>\$rems,
"remd"=>\$remd,

# IP version, res1/res2 bit, ihl, id, ICMP id (iid)
"version|v=i"=>\$version,
"res1"=>\$res1,
"res2"=>\$res2,
"ihl=s"=>\$ihl,
"id=s"=>\$id,
"icmp-id|iid=s"=>\$iid,

# ICMP type and code
"i|icmp-type=i"=>\$icmptype,
"c|icmp-code=i"=>\$icmpcode,

# ICMP gateway and mtu
"gateway|g=s"=>\$gateway,
"mtu=s"=>\$mtu,

# DATA to send for UDP/TCP/ICMP
"data|y=s"=>\$data,

# Quiet?
"quiet|q"=>\$quiet,

# Number of packets to send
"number|m=i"=>\$count,

# For generic protocols
"generic=s"=>\$generic,

# Socket functions...
"listen|li=s"=>\$listen,
"connect|co=s"=>\$connect,
"socket-protocol|sop=i"=>\$sop,
"regex=s"=>\$regex,
"nregex=s"=>\$nregex,

# The different attacks
"syn-flood|flood|sf"=>\$syn_flood,
"land"=>\$land,
"stream"=>\$stream,
"tcp-dos|tcpd|td"=>\$tcp_dos,
"udp-flood|uf"=>\$udp_flood,
"ping-flood|pf"=>\$ping_flood,
"be-dos|bed|bd"=>\$bedos,

) || die("Error: Incorrect command line options !!!\n\n");


# Check a few things and set defaults...
if(defined($saddr) && $saddr==0) { $rsip=1 }  # Random source IP?
if(!defined($version)) { $version=4 }         # IP version
if(!defined($ihl)) { $ihl=5 }                 # Internet Header Length (IHL)
if(!defined($tos)) { $tos=16 }                # Type of Service (ToS)
if(!defined($frag_off)) { $frag_off=0x4000 }  # Fragmentation offset
if(!defined($ttl)) { $ttl=64 }                # Time to Live (TTL)
if(!defined($window)) { $window=0xFFFF }      # Window size
if(!defined($data_off)) { $data_off=5 }       # Data offset
if(!defined($data)) { $data=""; $d_undef=1 }  # Data
if(!defined($urg_ptr)) { $urg_ptr=0 }         # Urgent pointer
if(!defined($ack_seq)) { $ack_seq=0 }         # ACK number
if(!defined($seq)) { $seq=0 }                 # Sequence number (seq)
if(!defined($tot)) { $tot=0 }                 # Total lenght (tot/tot_len)
if(!defined($id)) { $id=0 }                   # ID
if(!defined($iid)) { $iid=0 }                 # ICMP ID
if(!defined($ucheck)) { $ucheck=0 }           # UDP checksum (0=no calculation)
if(!defined($mtu)) { $mtu=1500 }              # Maximal transfer unit (MTU)
if(!defined($gateway)) { $gateway="" }        # Gateway
if(!defined($count)) { $ucount=1; $count=1 }  # Send only one packet as default.
if(!defined($protocol)) { $protocol=6 }       # Use TCP as default protocol
if(!defined($icmptype)) { $icmptype=0 }       # ICMP type
if(!defined($icmpcode)) { $icmpcode=0 }       # ICMP code
if(!defined($sop)) { $sop=6 }                 # Default socket protocol (TCP/6)

# Funny isn't it?
foreach $flag ($SYN, $ACK, $URG, $PSH, $RST, $FIN) {
 if(!defined($flag)) { $flag=0 }
} 


# Call the sub parse_file, if defined($file) (not implemented)...
if(defined($file)) { parse_file($file) }


# Check if $smac is defined and if so, if it has the right format...
if(!defined($smac)) { $smac="00:00:00:00:00:00" } else {
 if($smac!~/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i) {
  die("Error: Incorrect source MAC address !!!\n\n");
 }
}

# Check if $dmac is defined and if so, if it has the right format...
if(!defined($dmac)) { $dmac="00:00:00:00:00:00" } else {
 if($dmac!~/^([0-9a-f]{2}:){5}[0-9a-f]{2}$/i) {
  die("Error: Incorrect destination MAC address !!!\n\n");
 }
}


# Set default ports for TCP and UDP...
if($protocol==6 || $protocol==17) {
 if(!defined($sport)) {
  $rsport=1;
 }
 if(!defined($dport)) {
  if($protocol==6)  { $dport=80 }
  if($protocol==17) { $dport=7  }
 }
}

if($protocol==6 && defined($udp_flood) && !defined($dport)) { $dport=7 }

# Destination IP specified and no listen mode?
if(!defined($daddr) and !defined($listen)) {
 help(1);
}

# Socket functions?
check_socket();

# Check if anyone specified an attack...
check_attack();

# ...if not then let's construct the packets now...
construct();


# We should never reach this point...
die("Error: Undefined error !!!\n");

