summaryrefslogtreecommitdiff
path: root/srcx/jstart.c
diff options
context:
space:
mode:
Diffstat (limited to 'srcx/jstart.c')
-rw-r--r--srcx/jstart.c78
1 files changed, 76 insertions, 2 deletions
diff --git a/srcx/jstart.c b/srcx/jstart.c
index 6360f06..c61f484 100644
--- a/srcx/jstart.c
+++ b/srcx/jstart.c
@@ -44,12 +44,15 @@
#include <sys/types.h>
#include <sys/param.h>
#include <sys/jail.h>
+#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <netdb.h>
#include <paths.h>
#include <stdio.h>
+#include <stdlib.h>
#include <err.h>
#include <unistd.h>
#include <limits.h>
@@ -66,7 +69,8 @@ static char* START_ARGS[] = { _PATH_BSHELL, START_SCRIPT, NULL };
static void usage();
-#ifdef JAIL_MULTIPATCH
+/* Jail structure with multi address patch */
+#if defined(JAIL_MULTIPATCH)
static void allocate_address(char* arg, struct jail* j)
{
@@ -101,7 +105,77 @@ static void free_address(struct jail* j)
free(j->ips);
}
-#else /* !JAIL_MULTIPATCH */
+/* Jail structure with multi address (FreeBSD 7.2+) */
+#elif defined(JAIL_MULTIADDR)
+
+static void add_addresses(struct jail *j, struct addrinfo *all)
+{
+ struct addrinfo *res;
+ void *mem;
+
+ for(res = all; res; res = res->ai_next)
+ {
+ switch(res->ai_family)
+ {
+ case AF_INET:
+ j->ip4 = realloc(j->ip4, sizeof (*(j->ip4)) * (j->ip4s + 1));
+ if(j->ip4 == NULL)
+ errx(1, "out of memory");
+ memcpy(j->ip4 + j->ip4s, &((struct sockaddr_in*)res->ai_addr)->sin_addr, sizeof (*(j->ip4)));
+ ++j->ip4s;
+ break;
+#ifdef INET6
+ case AF_INET6:
+ j->ip6 = realloc(j->ip6, sizeof (*(j->ip6)) * (j->ip6s + 1));
+ if(j->ip6 == NULL)
+ errx(1, "out of memory");
+ memcpy(j->ip6 + j->ip6s, &((struct sockaddr_in6*)res->ai_addr)->sin6_addr, sizeof (*(j->ip6)));
+ ++j->ip6s;
+ break;
+#endif /* INET6 */
+ default:
+ errx(1, "Address family %d not supported", res->ai_family);
+ }
+ }
+}
+
+static void allocate_address(char* arg, struct jail* j)
+{
+ struct addrinfo hints, *res;
+ struct in_addr in;
+ char *ip;
+ int error, i = 0;
+
+ j->ip4s = j->ip6s = 0;
+ j->ip4 = NULL;
+ j->ip6 = NULL;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_flags = AI_NUMERICHOST;
+
+ for(i = 0, ip = strtok(arg, ","); ip; i++, ip = strtok(NULL, ","))
+ {
+ error = getaddrinfo(ip, NULL, &hints, &res);
+ if(error != 0)
+ errx(1, "invalid ip address: %s", ip);
+ add_addresses(j, res);
+ freeaddrinfo(res);
+ }
+
+ j->version = JAIL_API_VERSION;
+}
+
+static void free_address(struct jail* j)
+{
+ free(j->ip4);
+ free(j->ip6);
+}
+
+/* No jail multi addrs */
+#else
static void allocate_address(char* arg, struct jail* j)
{