All pastes #2056419 Raw Edit

rapex.c

public c v1 · immutable
#2056419 ·published 2011-05-10 20:07 UTC
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");}