/* * shoveler- used to proxy and redirect packets * * Requires libpcap and libdnet, www.tcpdump.org and libdnet.sourceforge.net * respectively. Compile using: * * gcc -o shoveler shoveler.c -lpcap -ldnet */ #include #include #include #include #include #include #include #include "mn.h" struct shoveler_settings shoveler_ctx; struct bpf_program pcapfilter; struct in_addr net, mask; pcap_t *pd; char pcap_err[PCAP_ERRBUF_SIZE]; char *dev; /* * usage routine */ void usage(char *prog, int exit_code) { printf("USAGE:\n"); printf("%s [options] -r -s -t \n\n",prog); printf("Options include:\n"); printf(" -d use something other than the default eth0\n"); printf(" -p proxy mode\n"); printf(" -v verbose mode\n"); printf(" -V version info\n"); printf(" -h this help screen\n"); printf("\n"); exit(exit_code); } u_long grab_my_addr( void ) { struct ifreq ifr; register struct sockaddr_in *sin; int fd; fd = socket(PF_INET, SOCK_DGRAM, 0); if (fd < 0) return 0; memset(&ifr,0,sizeof(ifr)); sin = (struct sockaddr_in *)&ifr.ifr_addr; strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name)); ifr.ifr_addr.sa_family = AF_INET; if (ioctl(fd, SIOCGIFADDR, (char*) &ifr) < 0) { close(fd); return 0; } close(fd); return(ntohl(sin->sin_addr.s_addr)); } /* initialize the shoveler */ int shoveler_init( void ) { shoveler_ctx.link_offset = 0; shoveler_ctx.verbose = 0; shoveler_ctx.proxy = 0; shoveler_ctx.spleen = 0; if(((ip_addr_t)shoveler_ctx.my_ip.addr_ip = grab_my_addr()) == 0) return(FAILURE); if((shoveler_ctx.handle = ip_open()) == NULL) return(FAILURE); else return (SUCCESS); } /* * packet handler, rewrites packets from on of four scenarios as needed */ void grab_packets(u_char *data1, struct pcap_pkthdr* h, u_char *p) { struct ip_hdr *ip_header; int len = 0, sent = 0, i; ip_header = (struct ip_hdr *)(p + shoveler_ctx.link_offset); /* we see a packet coming from the target back toward the real address, so we need to rewrite the destination */ if((ip_header->ip_src == shoveler_ctx.target_ip.addr_ip) && (ip_header->ip_dst == shoveler_ctx.real_ip.addr_ip)) { memcpy(&(ip_header->ip_dst),&(shoveler_ctx.source_ip.addr_ip),IP_ADDR_LEN); len = ntohs(ip_header->ip_len); ip_checksum(p, len); for(i=0; iip_src == shoveler_ctx.real_ip.addr_ip) && (ip_header->ip_dst == shoveler_ctx.target_ip.addr_ip) && (shoveler_ctx.spleen)) { ip_checksum(p,len); } /* we get a packet from the attack source for us, rewrite the source and destination addresses, assuming we are in proxy mode */ if((ip_header->ip_src == shoveler_ctx.source_ip.addr_ip) && (ip_header->ip_dst == shoveler_ctx.my_ip.addr_ip) && (shoveler_ctx.proxy)) { memcpy(&(ip_header->ip_src),&(shoveler_ctx.real_ip.addr_ip),IP_ADDR_LEN); memcpy(&(ip_header->ip_dst),&(shoveler_ctx.target_ip.addr_ip),IP_ADDR_LEN); len = ntohs(ip_header->ip_len); ip_checksum(p, len); for(i=0; i