DF-0053 / mkjail.c
/* mkjail - create a jail with N IPv4 IPs via jail(2) directly (bypasses jail(8)'s * ~24-IP realloc limit). Run as root. Usage: mkjail <path> <hostname> <n_ips> <sleeper> */ #include <sys/types.h> #include <sys/syscall.h> #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> /* Match struct jail ABI from sys/sys/jail.h (the syscall arg struct). */ struct jail_abi { uint32_t version; char *path; char *hostname; uint32_t n_ips; struct sockaddr_storage *ips; }; int main(int argc, char **argv){ if(argc < 5){ fprintf(stderr,"usage: %s path host n_ips sleeper\n",argv[0]); return 1; } const char *path=argv[1], *host=argv[2]; int n=atoi(argv[3]); const char *sleeper=argv[4]; struct sockaddr_storage *ips = calloc(n, sizeof(struct sockaddr_storage)); for(int i=0;i<n;i++){ struct sockaddr_in *s4=(struct sockaddr_in*)&ips[i]; s4->sin_family=AF_INET; unsigned a=10,b=0,c=(i/256),d=(i%254)+1; s4->sin_addr.s_addr=htonl((a<<24)|(b<<16)|(c<<8)|d); } struct jail_abi j; memset(&j,0,sizeof(j)); j.version=1; j.path=(char*)path; j.hostname=(char*)host; j.n_ips=n; j.ips=ips; pid_t pid=fork(); if(pid==0){ long _jr=syscall(SYS_jail,&j); if(_jr<0){ perror("jail"); _exit(1); } chdir("/"); char *av[2]={(char*)sleeper,NULL}; char *ev[1]={NULL}; execve(sleeper,av,ev); for(;;) pause(); } sleep(2); printf("mkjail: pid=%d n_ips=%d host_len=%zu\n",pid,n,strlen(host)); return 0; } |