Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Apr 2003 19:17:57 +0200
From:      Pawel Jakub Dawidek <nick@garage.freebsd.pl>
To:        freebsd-hackers@freebsd.org
Cc:        Poul-Henning Kamp <phk@FreeBSD.org>
Subject:   Multiple ip-numbers in jails (fixed INADDR_ANY behaviour).
Message-ID:  <20030415171757.GU52293@garage.freebsd.pl>

next in thread | raw e-mail | index | archive | help

--BcZrms9gUsdgyR6a
Content-Type: multipart/mixed; boundary="V4yrq4dHtCqH+JvC"
Content-Disposition: inline


--V4yrq4dHtCqH+JvC
Content-Type: text/plain; charset=iso-8859-2
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hello hackers...

I've just finished patch for multiple ip-numbers inside jails.

There was a problem with handling INADDR_ANY correctly in multiple ips
implementations, but I think I solved this problem.

Another thing are priorities.
When port X is opened on main host and in jail as INADDR_ANY, current
implementation of jail converts INADDR_ANY to jail's IP.
When we're connecting to this port we will connect to jail's daemon,
because "exactly match" is there.
In my solution looking for opened port is in this order:
	1. non-jailed, non-wild.
	2. non-jailed, wild.
	3. jailed, non-wild.
	4. jailed, wild.

Please, review it. Thanks.

PS. Patch is against FreeBSD-CURRENT.

--=20
Pawel Jakub Dawidek                       pawel@dawidek.net
UNIX Systems Programmer/Administrator     http://garage.freebsd.pl
Am I Evil? Yes, I Am!                     http://cerber.sourceforge.net

--V4yrq4dHtCqH+JvC
Content-Type: text/plain; charset=iso-8859-2
Content-Disposition: attachment; filename="mijail5.patch"
Content-Transfer-Encoding: quoted-printable

diff -ru /usr/src/sys/kern/kern_jail.c src/sys/kern/kern_jail.c
--- /usr/src/sys/kern/kern_jail.c	Wed Apr  9 04:55:17 2003
+++ src/sys/kern/kern_jail.c	Tue Apr 15 12:39:34 2003
@@ -92,7 +92,7 @@
 	error =3D copyin(uap->jail, &j, sizeof j);
 	if (error)
 		return (error);
-	if (j.version !=3D 0)
+	if (j.version !=3D 1)
 		return (EINVAL);
=20
 	MALLOC(pr, struct prison *, sizeof *pr , M_PRISON, M_WAITOK | M_ZERO);
@@ -115,7 +115,14 @@
 	error =3D copyinstr(j.hostname, &pr->pr_host, sizeof pr->pr_host, 0);
 	if (error)
 		goto e_dropvnref;
-	pr->pr_ip =3D j.ip_number;
+	if (j.nips >=3D JAIL_MAX_IPS)
+		goto e_dropvnref;
+	MALLOC(pr->pr_ips, u_int32_t *, sizeof(u_int32_t) * j.nips,
+	    M_PRISON, M_WAITOK);
+	error =3D copyin(j.ips, pr->pr_ips, sizeof(u_int32_t) * j.nips);
+	if (error)
+		goto e_dropips;
+	pr->pr_nips =3D j.nips;
 	pr->pr_linux =3D NULL;
 	pr->pr_securelevel =3D securelevel;
=20
@@ -131,7 +138,7 @@
 			if (tryprid =3D=3D JAIL_MAX) {
 				mtx_unlock(&allprison_mtx);
 				error =3D EAGAIN;
-				goto e_dropvnref;
+				goto e_dropips;
 			}
 			goto next;
 		}
@@ -154,6 +161,8 @@
 	LIST_REMOVE(pr, pr_list);
 	prisoncount--;
 	mtx_unlock(&allprison_mtx);
+e_dropips:
+	FREE(pr->pr_ips, M_PRISON);
 e_dropvnref:
 	mtx_lock(&Giant);
 	vrele(pr->pr_root);
@@ -270,6 +279,7 @@
 		mtx_destroy(&pr->pr_mtx);
 		if (pr->pr_linux !=3D NULL)
 			FREE(pr->pr_linux, M_PRISON);
+		FREE(pr->pr_ips, M_PRISON);
 		FREE(pr, M_PRISON);
 		return;
 	}
@@ -286,13 +296,6 @@
 	mtx_unlock(&pr->pr_mtx);
 }
=20
-u_int32_t
-prison_getip(struct ucred *cred)
-{
-
-	return (cred->cr_prison->pr_ip);
-}
-
 int
 prison_ip(struct ucred *cred, int flag, u_int32_t *ip)
 {
@@ -304,23 +307,16 @@
 		tmp =3D *ip;
 	else
 		tmp =3D ntohl(*ip);
-	if (tmp =3D=3D INADDR_ANY) {
-		if (flag)=20
-			*ip =3D cred->cr_prison->pr_ip;
-		else
-			*ip =3D htonl(cred->cr_prison->pr_ip);
-		return (0);
-	}
 	if (tmp =3D=3D INADDR_LOOPBACK) {
 		if (flag)
-			*ip =3D cred->cr_prison->pr_ip;
+			*ip =3D cred->cr_prison->pr_ips[0];
 		else
-			*ip =3D htonl(cred->cr_prison->pr_ip);
+			*ip =3D htonl(cred->cr_prison->pr_ips[0]);
 		return (0);
 	}
-	if (cred->cr_prison->pr_ip !=3D tmp)
-		return (1);
-	return (0);
+	if (tmp =3D=3D INADDR_ANY || jailed_ip(cred, tmp))
+		return (0);
+	return (1);
 }
=20
 void
@@ -336,9 +332,9 @@
 		tmp =3D ntohl(*ip);
 	if (tmp =3D=3D INADDR_LOOPBACK) {
 		if (flag)
-			*ip =3D cred->cr_prison->pr_ip;
+			*ip =3D cred->cr_prison->pr_ips[0];
 		else
-			*ip =3D htonl(cred->cr_prison->pr_ip);
+			*ip =3D htonl(cred->cr_prison->pr_ips[0]);
 		return;
 	}
 	return;
@@ -354,13 +350,31 @@
 		ok =3D 1;
 	else if (sai->sin_family !=3D AF_INET)
 		ok =3D 0;
-	else if (cred->cr_prison->pr_ip !=3D ntohl(sai->sin_addr.s_addr))
+	else if (!jailed_ip(cred, ntohl(sai->sin_addr.s_addr)))
 		ok =3D 1;
 	else
 		ok =3D 0;
 	return (ok);
 }
=20
+int
+jailed_ip(struct ucred *cred, u_int32_t ip)
+{
+	register struct prison *pr;
+	register u_int i;
+
+	if (!jailed(cred))
+		return(1);
+
+	pr =3D cred->cr_prison;
+	for (i =3D 0; i < pr->pr_nips; ++i) {
+		if (pr->pr_ips[i] =3D=3D ip)
+			return (1);
+	}
+
+	return (0);
+}
+
 /*
  * Return 0 if jails permit p1 to frob p2, otherwise ESRCH.
  */
@@ -439,7 +453,8 @@
 		xp->pr_id =3D pr->pr_id;
 		strlcpy(xp->pr_path, pr->pr_path, sizeof(xp->pr_path));
 		strlcpy(xp->pr_host, pr->pr_host, sizeof(xp->pr_host));
-		xp->pr_ip =3D pr->pr_ip;
+		memcpy(xp->pr_ips, pr->pr_ips, sizeof(u_int32_t) * pr->pr_nips);
+		xp->pr_nips =3D pr->pr_nips;
 		mtx_unlock(&pr->pr_mtx);
 		xp++;
 	}
diff -ru /usr/src/sys/netinet/in_pcb.c src/sys/netinet/in_pcb.c
--- /usr/src/sys/netinet/in_pcb.c	Fri Feb 21 06:28:27 2003
+++ src/sys/netinet/in_pcb.c	Tue Apr 15 18:58:34 2003
@@ -249,7 +249,7 @@
 	struct in_addr laddr;
 	u_short lport =3D 0;
 	int wild =3D 0, reuseport =3D (so->so_options & SO_REUSEPORT);
-	int error, prison =3D 0;
+	int error;
=20
 	if (TAILQ_EMPTY(&in_ifaddrhead)) /* XXX broken! */
 		return (EADDRNOTAVAIL);
@@ -270,9 +270,8 @@
 		if (sin->sin_family !=3D AF_INET)
 			return (EAFNOSUPPORT);
 #endif
-		if (sin->sin_addr.s_addr !=3D INADDR_ANY)
-			if (prison_ip(td->td_ucred, 0, &sin->sin_addr.s_addr))
-				return(EINVAL);
+		if (prison_ip(td->td_ucred, 0, &sin->sin_addr.s_addr))
+			return(EINVAL);
 		if (sin->sin_port !=3D *lportp) {
 			/* Don't allow the port to change. */
 			if (*lportp !=3D 0)
@@ -304,13 +303,11 @@
 			    ntohs(lport) >=3D ipport_reservedlow &&
 			    td && suser_cred(td->td_ucred, PRISON_ROOT))
 				return (EACCES);
-			if (td && jailed(td->td_ucred))
-				prison =3D 1;
 			if (so->so_cred->cr_uid !=3D 0 &&
 			    !IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
-				t =3D in_pcblookup_local(inp->inp_pcbinfo,
-				    sin->sin_addr, lport,
-				    prison ? 0 :  INPLOOKUP_WILDCARD);
+				t =3D in_pcblookup_local(td->td_ucred,
+				    inp->inp_pcbinfo, sin->sin_addr, lport,
+				    INPLOOKUP_WILDCARD);
 	/*
 	 * XXX
 	 * This entire block sorely needs a rewrite.
@@ -340,11 +337,10 @@
 					return (EADDRINUSE);
 				}
 			}
-			if (prison &&
-			    prison_ip(td->td_ucred, 0, &sin->sin_addr.s_addr))
+			if (prison_ip(td->td_ucred, 0, &sin->sin_addr.s_addr))
 				return (EADDRNOTAVAIL);
-			t =3D in_pcblookup_local(pcbinfo, sin->sin_addr,
-			    lport, prison ? 0 : wild);
+			t =3D in_pcblookup_local(td->td_ucred, pcbinfo,
+			    sin->sin_addr, lport, wild);
 			if (t && (t->inp_vflag & INP_TIMEWAIT)) {
 				if ((reuseport & intotw(t)->tw_so_options) =3D=3D 0)
 					return (EADDRINUSE);
@@ -369,9 +365,8 @@
 		ushort first, last;
 		int count;
=20
-		if (laddr.s_addr !=3D INADDR_ANY)
-			if (prison_ip(td->td_ucred, 0, &laddr.s_addr))
-				return (EINVAL);
+		if (prison_ip(td->td_ucred, 0, &laddr.s_addr))
+			return (EINVAL);
=20
 		if (inp->inp_flags & INP_HIGHPORT) {
 			first =3D ipport_hifirstauto;	/* sysctl */
@@ -409,8 +404,8 @@
 				if (*lastport > first || *lastport < last)
 					*lastport =3D first;
 				lport =3D htons(*lastport);
-			} while (in_pcblookup_local(pcbinfo, laddr, lport,
-			    wild));
+			} while (in_pcblookup_local(td->td_ucred, pcbinfo,
+			    laddr, lport, wild));
 		} else {
 			/*
 			 * counting up
@@ -424,8 +419,8 @@
 				if (*lastport < first || *lastport > last)
 					*lastport =3D first;
 				lport =3D htons(*lastport);
-			} while (in_pcblookup_local(pcbinfo, laddr, lport,
-			    wild));
+			} while (in_pcblookup_local(td->td_ucred, pcbinfo,
+			    laddr, lport, wild));
 		}
 	}
 	if (prison_ip(td->td_ucred, 0, &laddr.s_addr))
@@ -529,16 +524,6 @@
 	faddr =3D sin->sin_addr;
 	fport =3D sin->sin_port;
 	cred =3D inp->inp_socket->so_cred;
-	if (laddr.s_addr =3D=3D INADDR_ANY && jailed(cred)) {
-		bzero(&sa, sizeof(sa));
-		sa.sin_addr.s_addr =3D htonl(prison_getip(cred));
-		sa.sin_len =3D sizeof(sa);
-		sa.sin_family =3D AF_INET;
-		error =3D in_pcbbind_setup(inp, (struct sockaddr *)&sa,
-		    &laddr.s_addr, &lport, td);
-		if (error)
-			return (error);
-	}
=20
 	if (!TAILQ_EMPTY(&in_ifaddrhead)) {
 		/*
@@ -548,9 +533,12 @@
 		 * and the primary interface supports broadcast,
 		 * choose the broadcast address for that interface.
 		 */
-		if (faddr.s_addr =3D=3D INADDR_ANY)
-			faddr =3D IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr;
-		else if (faddr.s_addr =3D=3D (u_long)INADDR_BROADCAST &&
+		if (faddr.s_addr =3D=3D INADDR_ANY) {
+			if (jailed(cred))
+				faddr.s_addr =3D htonl(cred->cr_prison->pr_ips[0]);
+			else
+				faddr =3D IA_SIN(TAILQ_FIRST(&in_ifaddrhead))->sin_addr;
+		} else if (faddr.s_addr =3D=3D (u_long)INADDR_BROADCAST &&
 		    (TAILQ_FIRST(&in_ifaddrhead)->ia_ifp->if_flags &
 		    IFF_BROADCAST))
 			faddr =3D satosin(&TAILQ_FIRST(
@@ -907,7 +895,8 @@
  * Lookup a PCB based on the local address and port.
  */
 struct inpcb *
-in_pcblookup_local(pcbinfo, laddr, lport_arg, wild_okay)
+in_pcblookup_local(cred, pcbinfo, laddr, lport_arg, wild_okay)
+	struct ucred *cred;
 	struct inpcbinfo *pcbinfo;
 	struct in_addr laddr;
 	u_int lport_arg;
@@ -931,7 +920,9 @@
 #endif
 			if (inp->inp_faddr.s_addr =3D=3D INADDR_ANY &&
 			    inp->inp_laddr.s_addr =3D=3D laddr.s_addr &&
-			    inp->inp_lport =3D=3D lport) {
+			    inp->inp_lport =3D=3D lport &&
+			    inp->inp_socket->so_cred->cr_prison =3D=3D
+			    cred->cr_prison) {
 				/*
 				 * Found.
 				 */
@@ -969,6 +960,10 @@
 				if ((inp->inp_vflag & INP_IPV4) =3D=3D 0)
 					continue;
 #endif
+				if (inp->inp_socket->so_cred->cr_prison !=3D
+				    cred->cr_prison) {
+					continue;
+				}
 				if (inp->inp_faddr.s_addr !=3D INADDR_ANY)
 					wildcard++;
 				if (inp->inp_laddr.s_addr !=3D INADDR_ANY) {
@@ -997,8 +992,7 @@
  * Lookup PCB in hash list.
  */
 struct inpcb *
-in_pcblookup_hash(pcbinfo, faddr, fport_arg, laddr, lport_arg, wildcard,
-		  ifp)
+in_pcblookup_hash(pcbinfo, faddr, fport_arg, laddr, lport_arg, wildcard, i=
fp)
 	struct inpcbinfo *pcbinfo;
 	struct in_addr faddr, laddr;
 	u_int fport_arg, lport_arg;
@@ -1006,7 +1000,7 @@
 	struct ifnet *ifp;
 {
 	struct inpcbhead *head;
-	register struct inpcb *inp;
+	register struct inpcb *inp, *jinp =3D NULL;
 	u_short fport =3D fport_arg, lport =3D lport_arg;
=20
 	/*
@@ -1025,15 +1019,31 @@
 			/*
 			 * Found.
 			 */
-			return (inp);
+			if (inp->inp_socket->so_cred->cr_prison =3D=3D NULL)
+				return (inp);
+			else {
+				if (jinp =3D=3D NULL)
+					jinp =3D inp;
+			}
 		}
 	}
+	if (jinp !=3D NULL)
+		return (jinp);
 	if (wildcard) {
 		struct inpcb *local_wild =3D NULL;
 #if defined(INET6)
 		struct inpcb *local_wild_mapped =3D NULL;
 #endif /* defined(INET6) */
+		struct inpcb *jinp_wild =3D NULL;
+		struct ucred *cred;
=20
+		/*
+		 * Order of socket selection:
+		 * 1. non-jailed, non-wild.
+		 * 2. non-jailed, wild.
+		 * 3. jailed, non-wild.
+		 * 4. jailed, wild.
+		 */
 		head =3D &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->h=
ashmask)];
 		LIST_FOREACH(inp, head, inp_hash) {
 #ifdef INET6
@@ -1045,24 +1055,43 @@
 				if (ifp && ifp->if_type =3D=3D IFT_FAITH &&
 				    (inp->inp_flags & INP_FAITH) =3D=3D 0)
 					continue;
-				if (inp->inp_laddr.s_addr =3D=3D laddr.s_addr)
-					return (inp);
-				else if (inp->inp_laddr.s_addr =3D=3D INADDR_ANY) {
+				cred =3D inp->inp_socket->so_cred;
+				if (jailed(cred)) {
+					if (jinp !=3D NULL)
+						continue;
+					if (!jailed_ip(cred,
+					    ntohl(laddr.s_addr))) {
+						continue;
+					}
+				}
+				if (inp->inp_laddr.s_addr =3D=3D laddr.s_addr) {
+					if (jailed(cred))
+						jinp =3D inp;
+					else
+						return (inp);
+				} else if (inp->inp_laddr.s_addr =3D=3D INADDR_ANY) {
 #if defined(INET6)
 					if (INP_CHECK_SOCKAF(inp->inp_socket,
 							     AF_INET6))
 						local_wild_mapped =3D inp;
 					else
 #endif /* defined(INET6) */
-					local_wild =3D inp;
+					if (jailed(cred))
+						jinp_wild =3D inp;
+					else
+						local_wild =3D inp;
 				}
 			}
 		}
+		if (local_wild !=3D NULL)
+			return (local_wild);
 #if defined(INET6)
-		if (local_wild =3D=3D NULL)
+		if (local_wild_mapped !=3D NULL)
 			return (local_wild_mapped);
 #endif /* defined(INET6) */
-		return (local_wild);
+		if (jinp !=3D NULL)
+			return (jinp);
+		return (jinp_wild);
 	}
=20
 	/*
@@ -1176,7 +1205,7 @@
 {
 	if (!jailed(td->td_ucred))
 		return (0);
-	if (ntohl(inp->inp_laddr.s_addr) =3D=3D prison_getip(td->td_ucred))
+	if (jailed_ip(td->td_ucred, ntohl(inp->inp_laddr.s_addr)))
 		return (0);
 	return (1);
 }
diff -ru /usr/src/sys/netinet/in_pcb.h src/sys/netinet/in_pcb.h
--- /usr/src/sys/netinet/in_pcb.h	Wed Apr  2 22:14:43 2003
+++ src/sys/netinet/in_pcb.h	Tue Apr 15 11:47:57 2003
@@ -40,6 +40,7 @@
 #include <sys/queue.h>
 #include <sys/_lock.h>
 #include <sys/_mutex.h>
+#include <sys/ucred.h>
=20
 #include <net/route.h>
=20
@@ -340,7 +341,7 @@
 void	in_pcbdisconnect(struct inpcb *);
 int	in_pcbinshash(struct inpcb *);
 struct inpcb *
-	in_pcblookup_local(struct inpcbinfo *,
+	in_pcblookup_local(struct ucred *, struct inpcbinfo *,
 	    struct in_addr, u_int, int);
 struct inpcb *
 	in_pcblookup_hash(struct inpcbinfo *, struct in_addr, u_int,
diff -ru /usr/src/sys/netinet6/in6_pcb.c src/sys/netinet6/in6_pcb.c
--- /usr/src/sys/netinet6/in6_pcb.c	Wed Feb 19 23:32:42 2003
+++ src/sys/netinet6/in6_pcb.c	Tue Apr 15 18:00:45 2003
@@ -211,9 +211,9 @@
 					struct sockaddr_in sin;
=20
 					in6_sin6_2_sin(&sin, sin6);
-					t =3D in_pcblookup_local(pcbinfo,
-						sin.sin_addr, lport,
-						INPLOOKUP_WILDCARD);
+					t =3D in_pcblookup_local(td->td_ucred,
+					    pcbinfo, sin.sin_addr, lport,
+					    INPLOOKUP_WILDCARD);
 					if (t &&
 					    (so->so_cred->cr_uid !=3D
 					     t->inp_socket->so_cred->cr_uid) &&
@@ -233,8 +233,8 @@
 				struct sockaddr_in sin;
=20
 				in6_sin6_2_sin(&sin, sin6);
-				t =3D in_pcblookup_local(pcbinfo, sin.sin_addr,
-						       lport, wild);
+				t =3D in_pcblookup_local(td->td_ucred, pcbinfo,
+				    sin.sin_addr, lport, wild);
 				if (t &&
 				    (reuseport & t->inp_socket->so_options)
 				    =3D=3D 0 &&
diff -ru /usr/src/sys/sys/jail.h src/sys/sys/jail.h
--- /usr/src/sys/sys/jail.h	Wed Apr  9 04:55:18 2003
+++ src/sys/sys/jail.h	Tue Apr 15 12:38:23 2003
@@ -17,17 +17,21 @@
 	u_int32_t	version;
 	char		*path;
 	char		*hostname;
-	u_int32_t	ip_number;
+	u_int32_t	*ips;
+	u_int		nips;
 };
=20
+#define JAIL_MAX_IPS	256
+
 struct xprison {
-	int		 pr_version;
-	int		 pr_id;
-	char		 pr_path[MAXPATHLEN];
-	char 		 pr_host[MAXHOSTNAMELEN];
-	u_int32_t	 pr_ip;
+	int		pr_version;
+	int		pr_id;
+	char		pr_path[MAXPATHLEN];
+	char 		pr_host[MAXHOSTNAMELEN];
+	u_int32_t	pr_ips[JAIL_MAX_IPS];
+	u_int		pr_nips;
 };
-#define	XPRISON_VERSION	1
+#define	XPRISON_VERSION	2
=20
 #ifndef _KERNEL
=20
@@ -65,7 +69,8 @@
 	char		 pr_path[MAXPATHLEN];		/* (c) chroot path */
 	struct vnode	*pr_root;			/* (c) vnode to rdir */
 	char 		 pr_host[MAXHOSTNAMELEN];	/* (p) jail hostname */
-	u_int32_t	 pr_ip;				/* (c) ip addr host */
+	u_int32_t	*pr_ips;			/* (c) ip addr host */
+	u_int		 pr_nips;
 	void		*pr_linux;			/* (p) linux abi */
 	int		 pr_securelevel;		/* (p) securelevel */
 	struct mtx	 pr_mtx;
@@ -92,11 +97,11 @@
 void getcredhostname(struct ucred *cred, char *, size_t);
 int prison_check(struct ucred *cred1, struct ucred *cred2);
 void prison_free(struct prison *pr);
-u_int32_t prison_getip(struct ucred *cred);
 void prison_hold(struct prison *pr);
 int prison_if(struct ucred *cred, struct sockaddr *sa);
 int prison_ip(struct ucred *cred, int flag, u_int32_t *ip);
 void prison_remote_ip(struct ucred *cred, int flags, u_int32_t *ip);
+int jailed_ip(struct ucred *cred, u_int32_t ip);
=20
 #endif /* !_KERNEL */
 #endif /* !_SYS_JAIL_H_ */
diff -ru /usr/src/usr.sbin/jail/jail.c src/usr.sbin/jail/jail.c
--- /usr/src/usr.sbin/jail/jail.c	Wed Apr  9 05:04:12 2003
+++ src/usr.sbin/jail/jail.c	Tue Apr 15 12:30:01 2003
@@ -36,6 +36,8 @@
 	struct in_addr in;
 	int ch, groups[NGROUPS], i, iflag, ngroups;
 	char *username;
+	int c;
+	char *ip;
=20
 	iflag =3D 0;
 	username =3D NULL;
@@ -71,12 +73,25 @@
 	if (chdir(argv[0]) !=3D 0)
 		err(1, "chdir: %s", argv[0]);
 	memset(&j, 0, sizeof(j));
-	j.version =3D 0;
+	j.version =3D 1;
 	j.path =3D argv[0];
 	j.hostname =3D argv[1];
-	if (inet_aton(argv[2], &in) =3D=3D 0)
-		errx(1, "Could not make sense of ip-number: %s", argv[2]);
-	j.ip_number =3D ntohl(in.s_addr);
+	for (c =3D 1, ip =3D argv[2]; *ip; ++ip) {
+		if (*ip =3D=3D ',')
+			++c;
+	}
+	if ((j.ips =3D (u_int32_t *)malloc(sizeof(u_int32_t) * c)) =3D=3D NULL)
+		errx(1, "malloc()");
+	for (c =3D 0, ip =3D strtok(argv[2], ","); ip;
+	    ++c, ip =3D strtok(NULL, ",")) {
+		i =3D inet_aton(ip, &in);
+		if (!i) {
+			free(j.ips);
+			errx(1, "Couldn't make sense of ip-number\n");
+		}
+		j.ips[c] =3D ntohl(in.s_addr);
+	}
+	j.nips =3D c;
 	i =3D jail(&j);
 	if (i =3D=3D -1)
 		err(1, "jail");
@@ -102,6 +117,6 @@
 {
=20
 	(void)fprintf(stderr,
-	"usage: jail [-i] [-u username] path hostname ip-number command ...\n");
+	"usage: jail [-i] [-u username] path hostname ip1[,ip2[...]] command ...\=
n");
 	exit(1);
 }
diff -ru /usr/src/usr.sbin/jls/jls.c src/usr.sbin/jls/jls.c
--- /usr/src/usr.sbin/jls/jls.c	Wed Apr  9 05:04:12 2003
+++ src/usr.sbin/jls/jls.c	Tue Apr 15 12:47:58 2003
@@ -43,7 +43,7 @@
 {=20
 	struct xprison *sxp, *xp;
 	struct in_addr in;
-	size_t i, len;
+	size_t i, j, len;
=20
 	if (sysctlbyname("security.jail.list", NULL, &len, NULL, 0) =3D=3D -1)
 		err(1, "sysctlbyname(): security.jail.list");
@@ -67,9 +67,13 @@
=20
 	printf("   JID  IP Address   Hostname                      Path\n");
 	for (i =3D 0; i < len / sizeof(*xp); i++) {
-		in.s_addr =3D ntohl(xp->pr_ip);
+		in.s_addr =3D ntohl(xp->pr_ips[0]);
 		printf("%6d  %-12.12s %-29.29s %.77s\n",
 		    xp->pr_id, inet_ntoa(in), xp->pr_host, xp->pr_path);
+		for (j =3D 1; j < xp->pr_nips; ++j) {
+			in.s_addr =3D ntohl(xp->pr_ips[j]);
+			printf("        %-12.12s\n", inet_ntoa(in));
+		}
 		xp++;
 	}
 	free(sxp);

--V4yrq4dHtCqH+JvC--

--BcZrms9gUsdgyR6a
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.7 (FreeBSD)

iQCVAwUBPpw+xT/PhmMH/Mf1AQEavwQAmaG3u/QiwAfUG5PMPAMWfROPzl+SGHgA
CfN5jx3S5ZPMI3awwASNYNF1WutHH++na/85tYU/zL6BKr/mKSZC2zW2WN/PFNul
orRmBoYKXahige2JBYn8yc+IHbNwNf8AGNsqnEjWWDD6PRP9FFDySop7kymXcoSM
qRmPircf0yo=
=1/2N
-----END PGP SIGNATURE-----

--BcZrms9gUsdgyR6a--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030415171757.GU52293>