diff options
| author | Stef Walter <stef@memberwebs.com> | 2009-03-20 17:49:16 +0000 | 
|---|---|---|
| committer | Stef Walter <stef@memberwebs.com> | 2009-03-20 17:49:16 +0000 | 
| commit | f1ac1edac99c9c4b3dddecb575b3ef520b14dff2 (patch) | |
| tree | 1ff3ae8db60ef89395604d8831904ec0a93a5cfa /module | |
| parent | dcc4fbe0b1576d44fcc0f1417e13c11793efab84 (diff) | |
Add support for FreeBSD 7.2 jails.
Diffstat (limited to 'module')
| -rw-r--r-- | module/bsnmp-jails.c | 136 | 
1 files changed, 125 insertions, 11 deletions
diff --git a/module/bsnmp-jails.c b/module/bsnmp-jails.c index 31b3848..a6ea004 100644 --- a/module/bsnmp-jails.c +++ b/module/bsnmp-jails.c @@ -77,6 +77,13 @@   * COMPAT   */ +/* + * First jail structure kernel version in + * FreeBSD 4.x to 7.1 (unpatched) + */ + +#ifndef HAVE_XPRISON_V1 +  struct xprison_v1 {          int             pr_version;          int             pr_id; @@ -85,6 +92,17 @@ struct xprison_v1 {          u_int32_t       pr_ip;  }; +/* It's now defined */ +#define HAVE_XPRISON_V1 1 + +#endif /* HAVE_XPRISON_V1 */ + + +/* + * Second jail structure kernel version, used by multiple + * IP jail patches that applied to 5.x, 6.x and 7.0 + */ +  #ifndef JAIL_MAX_IPS  #define JAIL_MAX_IPS    256  #endif @@ -98,6 +116,24 @@ struct xprison_v2 {          u_int           pr_nips;  }; +/* This one is always defined */ +#define HAVE_XPRISON_V2 1 + + +/* + * Third jail structure kernel version, used by FreeBSD + * 7.2 and later. + */ + +#if XPRISON_VERSION == 3 + +/* The system definition is V3 */ +#define xprison_v3 xprison +#define HAVE_XPRISON_V3 1 + +#endif + +  /* -------------------------------------------------------------------   * DECLARATIONS   */ @@ -1048,7 +1084,7 @@ jail_free (struct jaildat *jail)  static int  jail_update (struct jaildat *jail, int jailid, const char *host, -             const char *path, u_int32_t *ips, u_int n_ips) +             const char *path, struct in_addr *ips, u_int n_ips)  {  	struct monitor *mon = NULL;  	struct sockaddr_in addr; @@ -1100,13 +1136,15 @@ jail_update (struct jaildat *jail, int jailid, const char *host,  	top = (jail->n_addrs > n_ips ? jail->n_addrs : n_ips);  	for (i = 0; i < top; ++i) { +fprintf (stderr, "IP: %s\n", inet_ntoa (ips[i])); +  		/* Setup the address */  		if (i < n_ips) {  			memset (&addr, 0, sizeof (addr));  			addr.sin_family = AF_INET;  			addr.sin_len = sizeof (addr);  			addr.sin_port = 0; -			addr.sin_addr.s_addr = ntohl (ips[i]); +			addr.sin_addr.s_addr = ips[i].s_addr;  			/* Same? skip. */  			if (i < jail->n_addrs && @@ -1151,7 +1189,7 @@ jail_update (struct jaildat *jail, int jailid, const char *host,  static struct jaildat*  jail_alloc (int jailid, const char *host, const char *path, -            u_int32_t *ips, u_int n_ips) +            struct in_addr *ips, u_int n_ips)  {  	struct jaildat *jail; @@ -1171,10 +1209,13 @@ jail_alloc (int jailid, const char *host, const char *path,  	return jail;  } +#ifdef HAVE_XPRISON_V1 +  static void  jail_refresh_v1 (struct xprison_v1 *xp, size_t len)  {  	struct jaildat *jail; +	struct in_addr in;  	int i;  	/* Make sure its kosher */ @@ -1189,23 +1230,29 @@ jail_refresh_v1 (struct xprison_v1 *xp, size_t len)  	 * (some possibly zombies), then we'll see the most recent one.  	 */  	for (i = (len / sizeof (*xp)) - 1; i >= 0; --i) { +		in.s_addr = htonl (xp[i].pr_ip);  		jail = hsh_get (jaildat_by_host, xp[i].pr_host, HSH_KEY_STRING);  		if (!jail)  			jail = jail_alloc (xp[i].pr_id, xp[i].pr_host, xp[i].pr_path, -			                   &xp[i].pr_ip, 1); +			                   &in, 1);  		else  			jail_update (jail, xp[i].pr_id, xp[i].pr_host, xp[i].pr_path, -			             &xp[i].pr_ip, 1); +			             &in, 1);  		if (jail)  			jail->mark = 0;  	}  } +#endif /* HAVE_XPRISON_V1 */ + +#ifdef HAVE_XPRISON_V2 +  static void  jail_refresh_v2 (struct xprison_v2 *xp, size_t len)  { +	struct in_addr ins[JAIL_MAX_IPS];  	struct jaildat *jail; -	int i; +	int i, j;  	/* Make sure its kosher */  	if (len < sizeof (*xp) || len % sizeof (*xp)) { @@ -1219,18 +1266,68 @@ jail_refresh_v2 (struct xprison_v2 *xp, size_t len)  	 * (some possibly zombies), then we'll see the most recent one.  	 */  	for (i = (len / sizeof (*xp)) - 1; i >= 0; --i) { +		for (j = 0; j < xp[i].pr_nips; ++j) +			ins[j].s_addr = htonl (xp[i].pr_ips[j]);  		jail = hsh_get (jaildat_by_host, xp[i].pr_host, HSH_KEY_STRING);  		if (!jail)  			jail = jail_alloc (xp[i].pr_id, xp[i].pr_host, xp[i].pr_path, -			                   xp[i].pr_ips, xp[i].pr_nips); +			                   ins, xp[i].pr_nips);  		else  			jail_update (jail, xp[i].pr_id, xp[i].pr_host, xp[i].pr_path, -			             xp[i].pr_ips, xp[i].pr_nips); +			             ins, xp[i].pr_nips);  		if (jail)  			jail->mark = 0;  	}  } +#endif /* HAVE_XPRISON_V2 */ + +#ifdef HAVE_XPRISON_V3 + +static void +jail_refresh_v3 (struct xprison_v3 *xp, size_t len) +{ +	struct jaildat *jail; +	size_t xlen; + +	while (len > 0) { + +		/* Make sure its kosher */ +		if (len < sizeof (*xp)) { +			emsg ("not a valid v3 xprison. kernel and userland out of sync?"); +			return; +		} + +		/* The length of this block */ +		xlen = sizeof (*xp) + (xp->pr_ip4s * sizeof (struct in_addr)) + +		       (xp->pr_ip6s * sizeof (struct in6_addr)); + +		/* Make sure its kosher */ +		if (len < xlen) { +			emsg ("not a valid v3 xprison struct. kernel and userland out of sync?"); +			return; +		} + +		if (xp->pr_state == PRISON_STATE_ALIVE) { +			jail = hsh_get (jaildat_by_host, xp->pr_host, HSH_KEY_STRING); +			if (!jail) +				jail = jail_alloc (xp->pr_id, xp->pr_host, xp->pr_path, +				                   (struct in_addr*)(xp + 1), xp->pr_ip4s); +			else +				jail_update (jail, xp->pr_id, xp->pr_host, xp->pr_path, +				             (struct in_addr*)(xp + 1), xp->pr_ip4s); + +			if (jail) +				jail->mark = 0; +		} + +		xp = (struct xprison_v3*)(((unsigned char*)xp) + xlen); +		len -= xlen; +	} +} + +#endif /* HAVE_XPRISON_V3 */ +  static void  jail_refresh_all (void* unused)  { @@ -1276,12 +1373,29 @@ jail_refresh_all (void* unused)  		jail->mark = 1;  	if (len > 0) { -		if (sxp->pr_version == 1) +		switch (sxp->pr_version) { + +#ifdef HAVE_XPRISON_V1 +		case 1:  			jail_refresh_v1 ((struct xprison_v1*)sxp, len); -		else if (sxp->pr_version == 2) +			break; +#endif + +#ifdef HAVE_XPRISON_V2 +		case 2:  			jail_refresh_v2 ((struct xprison_v2*)sxp, len); -		else +			break; +#endif + +#ifdef HAVE_XPRISON_V3 +		case 3: +			jail_refresh_v3 ((struct xprison_v3*)sxp, len); +			break; +#endif + +		default:  			emsg ("unsupported kernel structure version: %d\n", sxp->pr_version); +		}  		free (sxp);  	}  | 
