2 * Copyright (c) 2003 Mike Barcroft <mike@FreeBSD.org>
3 * Copyright (c) 2008 Bjoern A. Zeeb <bz@FreeBSD.org>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/param.h>
31 #include <sys/types.h>
33 #include <sys/sysctl.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
46 #define FLAG_A 0x00001
47 #define FLAG_V 0x00002
49 #ifdef SUPPORT_OLD_XPRISON
51 char *print_xprison_v1(void *p, char *end, unsigned flags)
53 struct xprison_v1 *xp;
56 if ((char *)p + sizeof(struct xprison_v1) > end)
57 errx(1, "Invalid length for jail");
59 xp = (struct xprison_v1 *)p;
61 printf("%6d %-29.29s %.74s\n",
62 xp->pr_id, xp->pr_host, xp->pr_path);
63 /* We are not printing an empty line here for state and name. */
64 /* We are not printing an empty line here for cpusetid. */
66 in.s_addr = htonl(xp->pr_ip);
67 printf("%6s %-15.15s\n", "", inet_ntoa(in));
69 printf("%6d %-15.15s %-29.29s %.74s\n",
70 xp->pr_id, inet_ntoa(in), xp->pr_host, xp->pr_path);
73 return ((char *)(xp + 1));
78 char *print_xprison_v3(void *p, char *end, unsigned flags)
81 struct in_addr *iap, in;
82 struct in6_addr *ia6p;
83 char buf[INET6_ADDRSTRLEN];
88 if ((char *)p + sizeof(struct xprison) > end)
89 errx(1, "Invalid length for jail");
90 xp = (struct xprison *)p;
92 if (xp->pr_state < 0 || xp->pr_state >= (int)
93 ((sizeof(prison_states) / sizeof(struct prison_state))))
96 state = prison_states[xp->pr_state].state_name;
98 /* See if we should print non-ACTIVE jails. No? */
99 if ((flags & FLAG_A) == 0 && strcmp(state, "ALIVE")) {
100 q = (char *)(xp + 1);
101 q += (xp->pr_ip4s * sizeof(struct in_addr));
103 errx(1, "Invalid length for jail");
104 q += (xp->pr_ip6s * sizeof(struct in6_addr));
106 errx(1, "Invalid length for jail");
111 printf("%6d %-29.29s %.74s\n",
112 xp->pr_id, xp->pr_host, xp->pr_path);
114 /* Jail state and name. */
116 printf("%6s %-29.29s %.74s\n",
117 "", (xp->pr_name[0] != '\0') ? xp->pr_name : "", state);
122 "", xp->pr_cpusetid);
124 q = (char *)(xp + 1);
125 /* IPv4 addresses. */
126 iap = (struct in_addr *)(void *)q;
127 q += (xp->pr_ip4s * sizeof(struct in_addr));
129 errx(1, "Invalid length for jail");
131 for (i = 0; i < xp->pr_ip4s; i++) {
132 if (i == 0 || flags & FLAG_V)
133 in.s_addr = iap[i].s_addr;
135 printf("%6s %-15.15s\n", "", inet_ntoa(in));
137 /* IPv6 addresses. */
138 ia6p = (struct in6_addr *)(void *)q;
139 q += (xp->pr_ip6s * sizeof(struct in6_addr));
141 errx(1, "Invalid length for jail");
142 for (i = 0; i < xp->pr_ip6s; i++) {
143 if (flags & FLAG_V) {
144 inet_ntop(AF_INET6, &ia6p[i], buf, sizeof(buf));
145 printf("%6s %s\n", "", buf);
149 /* If requested print the old style single line version. */
150 if (!(flags & FLAG_V))
151 printf("%6d %-15.15s %-29.29s %.74s\n",
152 xp->pr_id, (in.s_addr) ? inet_ntoa(in) : "",
153 xp->pr_host, xp->pr_path);
162 (void)fprintf(stderr, "usage: jls [-av]\n");
167 main(int argc, char *argv[])
175 while ((ch = getopt(argc, argv, "av")) != -1) {
190 if (sysctlbyname("security.jail.list", NULL, &len, NULL, 0) == -1)
191 err(1, "sysctlbyname(): security.jail.list");
194 for (i = 0; i < 4; i++) {
201 if (sysctlbyname("security.jail.list", q, &len, NULL, 0) == -1) {
202 if (errno == ENOMEM) {
208 err(1, "sysctlbyname(): security.jail.list");
213 err(1, "sysctlbyname(): security.jail.list");
214 if (len < sizeof(int))
215 errx(1, "This is no prison. Kernel and userland out of sync?");
217 if (version > XPRISON_VERSION)
218 errx(1, "Sci-Fi prison. Kernel/userland out of sync?");
220 if (flags & FLAG_V) {
221 printf(" JID Hostname Path\n");
222 printf(" Name State\n");
223 printf(" CPUSetID\n");
224 printf(" IP Address(es)\n");
226 printf(" JID IP Address Hostname"
229 for (; q != NULL && (char *)q + sizeof(int) < (char *)p + len;) {
231 if (version > XPRISON_VERSION)
232 errx(1, "Sci-Fi prison. Kernel/userland out of sync?");
234 #ifdef SUPPORT_OLD_XPRISON
236 q = print_xprison_v1(q, (char *)p + len, flags);
239 errx(1, "Version 2 was used by multi-IPv4 jail "
240 "implementations that never made it into the "
246 q = print_xprison_v3(q, (char *)p + len, flags);
249 errx(1, "Prison unknown. Kernel/userland out of sync?");