xref: /illumos-gate/usr/src/cmd/ipf/tools/ipfzone.c (revision bbf21555)
194bdecd9SRob Gulewich /*
294bdecd9SRob Gulewich  * Copyright (c) 2014 Joyent, Inc.  All rights reserved.
394bdecd9SRob Gulewich  * Use is subject to license terms.
494bdecd9SRob Gulewich  *
594bdecd9SRob Gulewich  * See the IPFILTER.LICENCE file for details on licensing.
694bdecd9SRob Gulewich  */
794bdecd9SRob Gulewich 
894bdecd9SRob Gulewich 
994bdecd9SRob Gulewich #include <errno.h>
1094bdecd9SRob Gulewich #include <net/if.h>
1194bdecd9SRob Gulewich #include <stdio.h>
1294bdecd9SRob Gulewich #include <string.h>
1394bdecd9SRob Gulewich #include <unistd.h>
1494bdecd9SRob Gulewich #include <zone.h>
1594bdecd9SRob Gulewich 
1694bdecd9SRob Gulewich #include "netinet/ip_fil.h"
1794bdecd9SRob Gulewich #include "ipfzone.h"
1894bdecd9SRob Gulewich 
1994bdecd9SRob Gulewich static ipfzoneobj_t	ipzo;
2094bdecd9SRob Gulewich static boolean_t	do_setzone = 0;
2194bdecd9SRob Gulewich static int		num_setzones = 0;
2294bdecd9SRob Gulewich 
2394bdecd9SRob Gulewich extern int	errno;
2494bdecd9SRob Gulewich extern int	opterr;
2594bdecd9SRob Gulewich extern int	optind;
2694bdecd9SRob Gulewich extern char	*optarg;
2794bdecd9SRob Gulewich 
2894bdecd9SRob Gulewich /*
2994bdecd9SRob Gulewich  * Get the zonename if it's the last argument and set the zonename
30*bbf21555SRichard Lowe  * in ipfzo to it. This is used by ipf(8) only - all of the other tools
3194bdecd9SRob Gulewich  * specify the zone with the -z option, and therefore use getzoneopt() below.
3294bdecd9SRob Gulewich  */
3394bdecd9SRob Gulewich void
getzonearg(int argc,char * argv[],const char * optstr)3494bdecd9SRob Gulewich getzonearg(int argc, char *argv[], const char *optstr)
3594bdecd9SRob Gulewich {
3694bdecd9SRob Gulewich 	int c;
3794bdecd9SRob Gulewich 
3894bdecd9SRob Gulewich 	/*
3994bdecd9SRob Gulewich 	 * Don't warn about unknown options - let subsequent calls to
4094bdecd9SRob Gulewich 	 * getopt() handle this.
4194bdecd9SRob Gulewich 	 */
4294bdecd9SRob Gulewich 	opterr = 0;
4394bdecd9SRob Gulewich 
4494bdecd9SRob Gulewich 	/*
4594bdecd9SRob Gulewich 	 * getopt is also used here to set optind so that we can
4694bdecd9SRob Gulewich 	 * determine if the last argument belongs to a flag or is
4794bdecd9SRob Gulewich 	 * actually a zonename.
4894bdecd9SRob Gulewich 	 */
4994bdecd9SRob Gulewich 	while ((c = getopt(argc, argv, optstr)) != -1) {
5094bdecd9SRob Gulewich 		if (c == 'G')
5194bdecd9SRob Gulewich 			ipzo.ipfz_gz = 1;
5294bdecd9SRob Gulewich 	}
5394bdecd9SRob Gulewich 
5494bdecd9SRob Gulewich 	if (optind < argc)
5594bdecd9SRob Gulewich 		setzonename(argv[optind]);
5694bdecd9SRob Gulewich 
5794bdecd9SRob Gulewich 	/*
5894bdecd9SRob Gulewich 	 * Reset optind and opterr so the next getopt call will go through all
5994bdecd9SRob Gulewich 	 * of argv again and warn about unknown options.
6094bdecd9SRob Gulewich 	 */
6194bdecd9SRob Gulewich 	optind = 1;
6294bdecd9SRob Gulewich 	opterr = 1;
6394bdecd9SRob Gulewich }
6494bdecd9SRob Gulewich 
6594bdecd9SRob Gulewich /*
6694bdecd9SRob Gulewich  * Get a -z option from argv and set the zonename in ipfzo accordingly
6794bdecd9SRob Gulewich  */
6894bdecd9SRob Gulewich void
getzoneopt(int argc,char * argv[],const char * optstr)6994bdecd9SRob Gulewich getzoneopt(int argc, char *argv[], const char *optstr)
7094bdecd9SRob Gulewich {
7194bdecd9SRob Gulewich 	int c;
7294bdecd9SRob Gulewich 
7394bdecd9SRob Gulewich 	/*
7494bdecd9SRob Gulewich 	 * Don't warn about unknown options - let subsequent calls to
7594bdecd9SRob Gulewich 	 * getopt() handle this.
7694bdecd9SRob Gulewich 	 */
7794bdecd9SRob Gulewich 	opterr = 0;
7894bdecd9SRob Gulewich 
7994bdecd9SRob Gulewich 	while ((c = getopt(argc, argv, optstr)) != -1) {
8094bdecd9SRob Gulewich 		if (c == 'G')
8194bdecd9SRob Gulewich 			setzonename_global(optarg);
8294bdecd9SRob Gulewich 
8394bdecd9SRob Gulewich 		if (c == 'z')
8494bdecd9SRob Gulewich 			setzonename(optarg);
8594bdecd9SRob Gulewich 	}
8694bdecd9SRob Gulewich 
8794bdecd9SRob Gulewich 	/*
8894bdecd9SRob Gulewich 	 * Reset optind and opterr so the next getopt call will go through all
8994bdecd9SRob Gulewich 	 * of argv again and warn about unknown options.
9094bdecd9SRob Gulewich 	 */
9194bdecd9SRob Gulewich 	optind = 1;
9294bdecd9SRob Gulewich 	opterr = 1;
9394bdecd9SRob Gulewich }
9494bdecd9SRob Gulewich 
9594bdecd9SRob Gulewich /*
9694bdecd9SRob Gulewich  * Set the zonename in ipfzo to the given string: this is the zone all further
9794bdecd9SRob Gulewich  * ioctls will act on.
9894bdecd9SRob Gulewich  */
9994bdecd9SRob Gulewich void
setzonename(const char * zonename)10094bdecd9SRob Gulewich setzonename(const char *zonename)
10194bdecd9SRob Gulewich {
10294bdecd9SRob Gulewich 	memcpy(ipzo.ipfz_zonename, zonename, sizeof (ipzo.ipfz_zonename));
10394bdecd9SRob Gulewich 	do_setzone = B_TRUE;
10494bdecd9SRob Gulewich 	num_setzones++;
10594bdecd9SRob Gulewich }
10694bdecd9SRob Gulewich 
10794bdecd9SRob Gulewich /*
10894bdecd9SRob Gulewich  * Set the zonename in ipfo, and the gz flag. This indicates that we want all
10994bdecd9SRob Gulewich  * further ioctls to act on the GZ-controlled stack for that zone.
11094bdecd9SRob Gulewich  */
11194bdecd9SRob Gulewich void
setzonename_global(const char * zonename)11294bdecd9SRob Gulewich setzonename_global(const char *zonename)
11394bdecd9SRob Gulewich {
11494bdecd9SRob Gulewich 	setzonename(zonename);
11594bdecd9SRob Gulewich 	ipzo.ipfz_gz = 1;
11694bdecd9SRob Gulewich }
11794bdecd9SRob Gulewich 
11894bdecd9SRob Gulewich /*
11994bdecd9SRob Gulewich  * Set the zone that all further ioctls will operate on. See the "GZ-controlled
12094bdecd9SRob Gulewich  * and per-zone stacks" note at the top of ip_fil_solaris.c for further
12194bdecd9SRob Gulewich  * explanation.
12294bdecd9SRob Gulewich  */
12394bdecd9SRob Gulewich int
setzone(int fd)12494bdecd9SRob Gulewich setzone(int fd)
12594bdecd9SRob Gulewich {
12694bdecd9SRob Gulewich 	if (!do_setzone)
12794bdecd9SRob Gulewich 		return (0);
12894bdecd9SRob Gulewich 
12994bdecd9SRob Gulewich 	if (num_setzones > 1) {
13094bdecd9SRob Gulewich 		(void) fprintf(stderr,
13194bdecd9SRob Gulewich 		    "Only one of -G and -z may be set\n");
13294bdecd9SRob Gulewich 		return (-1);
13394bdecd9SRob Gulewich 	}
13494bdecd9SRob Gulewich 
13594bdecd9SRob Gulewich 	if (ipzo.ipfz_gz == 1 &&
13694bdecd9SRob Gulewich 	    getzoneidbyname(ipzo.ipfz_zonename) == GLOBAL_ZONEID) {
13794bdecd9SRob Gulewich 		(void) fprintf(stderr,
13894bdecd9SRob Gulewich 		    "-G cannot be used with the global zone\n");
13994bdecd9SRob Gulewich 		return (-1);
14094bdecd9SRob Gulewich 	}
14194bdecd9SRob Gulewich 
14294bdecd9SRob Gulewich 	if (ioctl(fd, SIOCIPFZONESET, &ipzo) == -1) {
14394bdecd9SRob Gulewich 		switch (errno) {
14494bdecd9SRob Gulewich 		case ENODEV:
14594bdecd9SRob Gulewich 			(void) fprintf(stderr,
14694bdecd9SRob Gulewich 			    "Could not find running zone: %s\n",
14794bdecd9SRob Gulewich 			    ipzo.ipfz_zonename);
14894bdecd9SRob Gulewich 			break;
14994bdecd9SRob Gulewich 		case EACCES:
15094bdecd9SRob Gulewich 			(void) fprintf(stderr,
15194bdecd9SRob Gulewich 			    "Permission denied setting zone: %s\n",
15294bdecd9SRob Gulewich 			    ipzo.ipfz_zonename);
15394bdecd9SRob Gulewich 			break;
15494bdecd9SRob Gulewich 		default:
15594bdecd9SRob Gulewich 			perror("Error setting zone");
15694bdecd9SRob Gulewich 		}
15794bdecd9SRob Gulewich 		return (-1);
15894bdecd9SRob Gulewich 	}
15994bdecd9SRob Gulewich 
16094bdecd9SRob Gulewich 	return (0);
16194bdecd9SRob Gulewich }
162