DF-3399 / udp_spray.c
/* * DF-3399: spray N distinct outbound UDP flows through the ipfw3 NAT. * Unprivileged-friendly: plain UDP socket, fresh source port per datagram. * Every new 5-tuple forces a new NAT state; on a multi-CPU box most of them * are handled by the cross-CPU netmsg path that leaks its netmsg. */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char **argv) { int n = atoi(argv[1]); int i; struct sockaddr_in dst; char buf[16]; memset(&dst, 0, sizeof(dst)); dst.sin_family = AF_INET; dst.sin_len = sizeof(dst); inet_aton("10.0.2.2", &dst.sin_addr); dst.sin_port = htons(9); for (i = 0; i < n; i++) { struct sockaddr_in src; int s = socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) { perror("socket"); return 1; } memset(&src, 0, sizeof(src)); src.sin_family = AF_INET; src.sin_len = sizeof(src); src.sin_port = htons(1024 + (i % 60000)); inet_aton("10.0.2.15", &src.sin_addr); if (bind(s, (struct sockaddr *)&src, sizeof(src)) < 0) { /* port in use; skip */ close(s); continue; } if (sendto(s, buf, sizeof(buf), 0, (struct sockaddr *)&dst, sizeof(dst)) < 0) perror("sendto"); close(s); } printf("sprayed %d flows\n", n); return 0; } |