All pastes #2056421 Raw Edit

rapeloli.c

public c v1 · immutable
#2056421 ·published 2011-05-10 20:08 UTC
rendered paste body
#define HTTPREQ "GET /blah HTTP/1.1\r\nHost: reply.me\r\nConnection: close\r\n\r\n" // should return HTTPCHECK string#define HTTPCHECK "proxycheckfound"#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 pkt {	struct ip_hdr_t ip;	struct tcp_hdr_t tcp;};struct iphash {	uint32_t ip;	struct iphash *next;};#define HSIZE 512#define SNAPLEN 128*1024struct pollfd *pollfds = NULL;#define BUFSZ 8188struct tentry {	uint32_t t;	uint8_t buf[BUFSZ];};struct tentry *tmap = NULL;int npoll = 0;int inflight=0;time_t now, oldnow;int	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(tmap[0])*(npoll));	}	//printf("adding @ idx %d fd %d\n", i, fd);	pollfds[i].fd = fd;	pollfds[i].events = events;	tmap[i].t = now;	tmap[i].buf[0] = 0;	inflight++;	return i;}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--;}//struct iphash *hash[2048];uint8_t ipmap[1<<29];int	check_map(uint32_t ip){	if (ipmap[ip/8] & (1<<(ip%8)))		return 0;	ipmap[ip/8] |= (1<<(ip%8));	return 1;}int	make_connection(uint32_t ip, int port){	struct sockaddr_in sin;	int sock;	memset(&sin, 0, sizeof(sin));	sin.sin_family = AF_INET;	sin.sin_port = htons(port);	ip = htonl(ip);	memcpy(&sin.sin_addr.s_addr, &ip, 4);	assert((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP))>=0);	fcntl(sock, F_SETFL, O_NONBLOCK);	connect(sock, (struct sockaddr *) &sin, sizeof(sin));	return sock;}int	main(int argc, char *argv[]){	char buf[512];	int done;	int dport;	int probed=0;	double total;	double goal;	int found=0;	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;	int timedout = 0;	signal(SIGPIPE, SIG_IGN);	/* srcip srcif dstport srclist dstlist	 * 1	 2	3	4	5	 * */	assert(argc==4 && "srcif dstport dstlist");	assert(fout = fopen(argv[3], "a"));	dport = strtol(argv[2], NULL, 10);	pc = pcap_open_live(argv[1], sizeof(struct pkt) + 32, 0, 100, pcap_err);	assert(pcap_setnonblock(pc, 1, pcap_err)==0);	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);	while (1) {		poll(pollfds, npoll, 100);		now = time(NULL);		for (i = 0; i < npoll; i++) {			int want = pollfds[i].events;			int got = pollfds[i].revents;			int fd = pollfds[i].fd;			uint8_t *buf = tmap[i].buf;			if (fd==-1) continue;			if (got & (POLLERR|POLLHUP))				goto errclose;			if ((got & want) == 0) continue;			if (fd == pfd) {				retry:				gotpk = pcap_next(pc, &ph);				if (!gotpk) continue;				gotpk += pc_off;				rpkt = (void*)gotpk;				uint32_t gip = ntohl(rpkt->ip.ip_dst);				uint32_t fip = ntohl(rpkt->ip.ip_src);				if ((rpkt->tcp.tcp_dport == htons(1337)) && (rpkt->tcp.tcp_sport == htons(dport)) && check_map(fip)) {					int cn = make_connection(fip, dport);					int id = poll_add(cn, POLLOUT);					strcpy(tmap[id].buf, HTTPREQ);					probed++;				}				goto retry;			} else {				if (want == POLLOUT) {					int tow = strlen(buf);					int got = write(fd, buf, tow);					if (got <= 0) {						close(fd);						poll_del(i);						continue;					}					memmove(buf, buf + got, tow-got+1);					tow -= got;					if (!tow) {						tmap[i].t = now;						pollfds[i].events = POLLIN;						buf[0] = 0;					}				} else {					int rgot;					int bufl = strlen(buf);					rgot = read(fd, buf + bufl, BUFSZ - bufl - 1);					if (rgot <= 0) {						errclose:;						close(fd);						poll_del(i);						continue;					}					tmap[i].t = now;					bufl += rgot;					buf[bufl] = 0;					if (bufl < 16)						continue;					if (memcmp(buf + 9, "200", 3))						goto errclose;					uint8_t *p = strstr(buf, "\r\n\r\n");					if (!p) {						if (bufl == BUFSZ-1) goto errclose;						continue;					}					p += 4;					if (strstr(buf, HTTPCHECK)) {						socklen_t sinlen = sizeof(sin);						getpeername(fd, (struct sockaddr*)&sin, &sinlen);						fprintf(fout, "%s\n", inet_ntoa(sin.sin_addr));						fflush(fout);						found++;						close(fd);						poll_del(i);					}				}			}		}		if (now < oldnow+3)			continue;		for (i = 0; i < npoll; i++) {			int want = pollfds[i].events;			int fd = pollfds[i].fd;			if (fd == -1 || fd == pfd) continue;			if ((want == POLLIN && tmap[i].t + RTIMEOUT < now) || 				(want == POLLOUT && tmap[i].t + WTIMEOUT < now)) {				close(fd);				poll_del(i);				timedout++;			}		}		oldnow = now;		fprintf(stderr, "%d probed, %d timed out, %d inflight, %d found       \r", probed, timedout, inflight, found);		fflush(stdout);	}	return 0;}