rendered paste body#define GOALRATE 45000#define RTIMEOUT 30#define WTIMEOUT 10#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <arpa/inet.h>#include <assert.h>#include <inttypes.h>#include <netdb.h>#include <netinet/in.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <ifaddrs.h>#include <net/if.h>#include <stdarg.h>#include <string.h>#include <unistd.h>#include <pcap.h>#include <poll.h>#include <fcntl.h>struct ip_hdr_t{#if (BYTE_ORDER == LITTLE_ENDIAN) uint8_t ip_hl:4, ip_v:4;#elif (BYTE_ORDER == BIG_ENDIAN) uint8_t ip_v:4, ip_hl:4;#else #error "Adjust your <asm/byteorder.h> defines"#endif uint8_t ip_tos; uint16_t ip_len; uint16_t ip_id; uint16_t ip_off; uint8_t ip_ttl; uint8_t ip_p; uint16_t ip_sum; uint32_t ip_src; uint32_t ip_dst;}__attribute__((packed));struct tcp_hdr_t { uint16_t tcp_sport; uint16_t tcp_dport; uint32_t tcp_seq; uint32_t tcp_ackseq;#if (BYTE_ORDER == LITTLE_ENDIAN) uint8_t res:4, doff:4;#elif (BYTE_ORDER == BIG_ENDIAN) uint8_t doff:4, res:4;#else#error "Adjust your <asm/byteorder.h> defines"#endif uint8_t tcp_flags; uint16_t tcp_window; uint16_t tcp_sum; uint16_t tcp_urgptr;} __attribute__((packed));struct pseudo_hdr_t { uint32_t src; uint32_t dst; uint8_t pad; uint8_t proto; uint16_t tcpl; struct tcp_hdr_t tcp;}__attribute__((packed));struct net { uint32_t start; uint32_t stop; uint32_t count; uint32_t pos; uint32_t xor; struct net *next; uint32_t bitmap[0];};struct pkt { struct ip_hdr_t ip; struct tcp_hdr_t tcp;};#define HSIZE 512struct net *netlist = NULL;int check_map(uint32_t ip){ struct net *net; for (net = netlist; net; net=net->next) { //printf("chknet %x %x %x\n", net->start, ip, net->stop); if ((ip < net->start) || (ip > net->stop)) continue; int pos = (ip-net->start); if ((net->bitmap[pos/32] && (1<<(pos%32)))==0) { //printf("process %x\n", ip); net->bitmap[pos/32] |= (1<<(pos%32)); return 1; } } return 0;}uint32_t getaddr(char *s){ union { struct in_addr ia; in_addr_t iat; uint32_t i; } a; a.iat = inet_addr(s); return ntohl(a.i);}uint16_t net_ip_sum (const uint16_t *ptr, int len){ register int sum = 0; while (len > 1) { sum += *ptr++; len -= 2; } if (len == 1) sum += *((unsigned char *) ptr); sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); return (~sum);}#define SNAPLEN 128*1024struct pseudo_hdr_t pseudo;struct pkt p;void init_pkt(uint32_t srcip, int dport){ p.ip.ip_src = htonl(srcip); pseudo.src = p.ip.ip_src; pseudo.pad = 0; pseudo.proto = IPPROTO_TCP; pseudo.tcpl = htons(sizeof p.tcp); p.ip.ip_v = 4; p.ip.ip_hl = 5; p.ip.ip_tos = 0; p.ip.ip_len = sizeof(p); p.ip.ip_off = 0; p.ip.ip_id = 0x1337; p.ip.ip_ttl = 63; p.ip.ip_p = IPPROTO_TCP; p.tcp.tcp_sport = htons(1337); p.tcp.tcp_dport = htons(dport); p.tcp.tcp_seq = 0xdeadbabe; p.tcp.tcp_ackseq = 0xcafebeef; p.tcp.doff = sizeof(p.tcp)/4; p.tcp.tcp_flags = 0x2; // SYN p.tcp.tcp_window = 100; p.tcp.tcp_urgptr = 0;}void send_pkt(int sock, uint32_t dstip){ static struct sockaddr_in sin; p.ip.ip_dst = htonl(dstip); p.ip.ip_sum = net_ip_sum((void*)&p.ip, sizeof p.ip); pseudo.dst = p.ip.ip_dst; p.tcp.tcp_sum = 0; memcpy(&pseudo.tcp, &p.tcp, sizeof p.tcp); p.tcp.tcp_sum = net_ip_sum((void*)&pseudo, sizeof pseudo); sin.sin_family = AF_INET; sin.sin_port = p.tcp.tcp_dport; memcpy(&sin.sin_addr.s_addr,&p.ip.ip_dst,4); sendto(sock, &p, sizeof(p),0, (struct sockaddr *) &sin, sizeof(sin));}struct pollfd *pollfds = NULL;int *tmap = NULL;int npoll = 0;int inflight=0;time_t oldnow;time_t now;void poll_add(int fd, int events){ int i; for (i = 0; i < npoll; i++) { if (pollfds[i].fd == -1) break; } if (i == npoll) { pollfds = realloc(pollfds, sizeof(pollfds[0])*(++npoll)); tmap = realloc(tmap, sizeof(int)*(npoll)); } //printf("adding @ idx %d fd %d\n", i, fd); pollfds[i].fd = fd; pollfds[i].events = events; tmap[i] = now; inflight++;}void poll_del(int idx){ //printf("deleting idx %d, fd %d\n", idx, pollfds[idx].fd); assert(pollfds[idx].fd != -1); pollfds[idx].fd = -1; pollfds[idx].events = 0; inflight--;}int main(int argc, char *argv[]){ char buf[512]; int done; int dport; double probed; double total; double goal; double found; double rate; double irate; FILE *f; int sock; struct sockaddr_in sin; memset(&sin, 0,sizeof sin); char pcap_err[PCAP_ERRBUF_SIZE]; pcap_t *pc; int pc_off = 0; struct bpf_program filter; struct pcap_pkthdr ph; int pfd; FILE *fout; double penalty; int i; struct net *net; unsigned char *gotpk; struct pkt *rpkt; int finishers = 0; int repeats=0; double limit; int pks; signal(SIGPIPE, SIG_IGN); /* srcip srcif dstport srclist dstlist * 1 2 3 4 5 * */ assert(argc==6 && "srcip srcif dstport srclist dstlist"); assert((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))>=0); assert(f = fopen(argv[4], "r")); assert(fout = fopen(argv[5], "a")); dport = strtol(argv[3], NULL, 10); pc = pcap_open_live(argv[2], sizeof(struct pkt) + 32, 0, 100, pcap_err);// pcap_setnonblock(pc, 1, pcap_err); if (pcap_datalink(pc) == DLT_EN10MB) pc_off = 14; assert(pcap_compile(pc, &filter, "(ip proto \\tcp) and ((tcp[13] & (tcp-ack+tcp-rst)) = tcp-ack) and dst port 1337", 0, 0) != -1); assert(pcap_setfilter(pc, &filter) != -1); poll_add(pfd=pcap_fileno(pc), POLLIN); uint32_t sip = getaddr(argv[1]); init_pkt(sip, dport); probed=irate = rate = found = total = goal = 0; limit = 1000; pks = 0; while (fgets(buf,512,f)) { struct net *net; char a[512]; char b[512]; uint32_t na,nb,l; assert(sscanf(buf,"%[^-]-%s",a,b)==2); na = getaddr(a); nb = getaddr(b); l = sizeof *net + ((nb-na+32)/32)*sizeof(uint32_t); net = malloc(l); memset(net,0,l); net->start = na; net->stop = nb; net->count = nb-na+1; goal+= net->count; //printf("%.2f\n", goal); net->next = netlist; net->pos = 0; srand(time(NULL)); net->xor = rand() % net->count; netlist = net; } net = NULL; fprintf(stderr, "scanning %.2fM IPs for port %d\n", goal/1000000, dport); while (1) { int igots=0; pks=0; while (pks<limit) { for (net = net?net:netlist; net; net = net->next) { if (pks>limit) break; if (net->pos == net->count) continue; send_pkt(sock, net->start + ((net->pos)) % net->count); rate++; net->pos++; total++; pks++; } } now = time(NULL); usleep(2); if (now > oldnow+3) { rate = rate/(now-oldnow); irate = irate/(now-oldnow); limit /= rate/GOALRATE; if (limit<1) limit=1; if (limit>10000) limit=10000; fprintf(stderr, "txrate %.2fKpps (limit %.2fKpp/burst) || rxrate %.2fpps || %.2f %% done (%.2fM) || %.0f probed (%.2f prevalency)\r", rate/1000, limit/1000, irate, total*100/goal, total/1000000, probed, probed * 100 / goal); rate=0; irate=0; oldnow = now; if (total==goal) { fprintf(stderr,"Finished!\n"); if (finishers++>30) break; } } } fprintf(stderr, "\n");}