xref: /titanic_51/usr/src/cmd/ipf/tools/ipfzone.c (revision 94bdecd9e84ae1042607002db3e64a6849da5874)
1*94bdecd9SRob Gulewich /*
2*94bdecd9SRob Gulewich  * Copyright (c) 2014 Joyent, Inc.  All rights reserved.
3*94bdecd9SRob Gulewich  * Use is subject to license terms.
4*94bdecd9SRob Gulewich  *
5*94bdecd9SRob Gulewich  * See the IPFILTER.LICENCE file for details on licensing.
6*94bdecd9SRob Gulewich  */
7*94bdecd9SRob Gulewich 
8*94bdecd9SRob Gulewich 
9*94bdecd9SRob Gulewich #include <errno.h>
10*94bdecd9SRob Gulewich #include <net/if.h>
11*94bdecd9SRob Gulewich #include <stdio.h>
12*94bdecd9SRob Gulewich #include <string.h>
13*94bdecd9SRob Gulewich #include <unistd.h>
14*94bdecd9SRob Gulewich #include <zone.h>
15*94bdecd9SRob Gulewich 
16*94bdecd9SRob Gulewich #include "netinet/ip_fil.h"
17*94bdecd9SRob Gulewich #include "ipfzone.h"
18*94bdecd9SRob Gulewich 
19*94bdecd9SRob Gulewich static ipfzoneobj_t	ipzo;
20*94bdecd9SRob Gulewich static boolean_t	do_setzone = 0;
21*94bdecd9SRob Gulewich static int		num_setzones = 0;
22*94bdecd9SRob Gulewich 
23*94bdecd9SRob Gulewich extern int	errno;
24*94bdecd9SRob Gulewich extern int	opterr;
25*94bdecd9SRob Gulewich extern int	optind;
26*94bdecd9SRob Gulewich extern char	*optarg;
27*94bdecd9SRob Gulewich 
28*94bdecd9SRob Gulewich /*
29*94bdecd9SRob Gulewich  * Get the zonename if it's the last argument and set the zonename
30*94bdecd9SRob Gulewich  * in ipfzo to it. This is used by ipf(1m) only - all of the other tools
31*94bdecd9SRob Gulewich  * specify the zone with the -z option, and therefore use getzoneopt() below.
32*94bdecd9SRob Gulewich  */
33*94bdecd9SRob Gulewich void
34*94bdecd9SRob Gulewich getzonearg(int argc, char *argv[], const char *optstr)
35*94bdecd9SRob Gulewich {
36*94bdecd9SRob Gulewich 	int c;
37*94bdecd9SRob Gulewich 
38*94bdecd9SRob Gulewich 	/*
39*94bdecd9SRob Gulewich 	 * Don't warn about unknown options - let subsequent calls to
40*94bdecd9SRob Gulewich 	 * getopt() handle this.
41*94bdecd9SRob Gulewich 	 */
42*94bdecd9SRob Gulewich 	opterr = 0;
43*94bdecd9SRob Gulewich 
44*94bdecd9SRob Gulewich 	/*
45*94bdecd9SRob Gulewich 	 * getopt is also used here to set optind so that we can
46*94bdecd9SRob Gulewich 	 * determine if the last argument belongs to a flag or is
47*94bdecd9SRob Gulewich 	 * actually a zonename.
48*94bdecd9SRob Gulewich 	 */
49*94bdecd9SRob Gulewich 	while ((c = getopt(argc, argv, optstr)) != -1) {
50*94bdecd9SRob Gulewich 		if (c == 'G')
51*94bdecd9SRob Gulewich 			ipzo.ipfz_gz = 1;
52*94bdecd9SRob Gulewich 	}
53*94bdecd9SRob Gulewich 
54*94bdecd9SRob Gulewich 	if (optind < argc)
55*94bdecd9SRob Gulewich 		setzonename(argv[optind]);
56*94bdecd9SRob Gulewich 
57*94bdecd9SRob Gulewich 	/*
58*94bdecd9SRob Gulewich 	 * Reset optind and opterr so the next getopt call will go through all
59*94bdecd9SRob Gulewich 	 * of argv again and warn about unknown options.
60*94bdecd9SRob Gulewich 	 */
61*94bdecd9SRob Gulewich 	optind = 1;
62*94bdecd9SRob Gulewich 	opterr = 1;
63*94bdecd9SRob Gulewich }
64*94bdecd9SRob Gulewich 
65*94bdecd9SRob Gulewich /*
66*94bdecd9SRob Gulewich  * Get a -z option from argv and set the zonename in ipfzo accordingly
67*94bdecd9SRob Gulewich  */
68*94bdecd9SRob Gulewich void
69*94bdecd9SRob Gulewich getzoneopt(int argc, char *argv[], const char *optstr)
70*94bdecd9SRob Gulewich {
71*94bdecd9SRob Gulewich 	int c;
72*94bdecd9SRob Gulewich 
73*94bdecd9SRob Gulewich 	/*
74*94bdecd9SRob Gulewich 	 * Don't warn about unknown options - let subsequent calls to
75*94bdecd9SRob Gulewich 	 * getopt() handle this.
76*94bdecd9SRob Gulewich 	 */
77*94bdecd9SRob Gulewich 	opterr = 0;
78*94bdecd9SRob Gulewich 
79*94bdecd9SRob Gulewich 	while ((c = getopt(argc, argv, optstr)) != -1) {
80*94bdecd9SRob Gulewich 		if (c == 'G')
81*94bdecd9SRob Gulewich 			setzonename_global(optarg);
82*94bdecd9SRob Gulewich 
83*94bdecd9SRob Gulewich 		if (c == 'z')
84*94bdecd9SRob Gulewich 			setzonename(optarg);
85*94bdecd9SRob Gulewich 	}
86*94bdecd9SRob Gulewich 
87*94bdecd9SRob Gulewich 	/*
88*94bdecd9SRob Gulewich 	 * Reset optind and opterr so the next getopt call will go through all
89*94bdecd9SRob Gulewich 	 * of argv again and warn about unknown options.
90*94bdecd9SRob Gulewich 	 */
91*94bdecd9SRob Gulewich 	optind = 1;
92*94bdecd9SRob Gulewich 	opterr = 1;
93*94bdecd9SRob Gulewich }
94*94bdecd9SRob Gulewich 
95*94bdecd9SRob Gulewich /*
96*94bdecd9SRob Gulewich  * Set the zonename in ipfzo to the given string: this is the zone all further
97*94bdecd9SRob Gulewich  * ioctls will act on.
98*94bdecd9SRob Gulewich  */
99*94bdecd9SRob Gulewich void
100*94bdecd9SRob Gulewich setzonename(const char *zonename)
101*94bdecd9SRob Gulewich {
102*94bdecd9SRob Gulewich 	memcpy(ipzo.ipfz_zonename, zonename, sizeof (ipzo.ipfz_zonename));
103*94bdecd9SRob Gulewich 	do_setzone = B_TRUE;
104*94bdecd9SRob Gulewich 	num_setzones++;
105*94bdecd9SRob Gulewich }
106*94bdecd9SRob Gulewich 
107*94bdecd9SRob Gulewich /*
108*94bdecd9SRob Gulewich  * Set the zonename in ipfo, and the gz flag. This indicates that we want all
109*94bdecd9SRob Gulewich  * further ioctls to act on the GZ-controlled stack for that zone.
110*94bdecd9SRob Gulewich  */
111*94bdecd9SRob Gulewich void
112*94bdecd9SRob Gulewich setzonename_global(const char *zonename)
113*94bdecd9SRob Gulewich {
114*94bdecd9SRob Gulewich 	setzonename(zonename);
115*94bdecd9SRob Gulewich 	ipzo.ipfz_gz = 1;
116*94bdecd9SRob Gulewich }
117*94bdecd9SRob Gulewich 
118*94bdecd9SRob Gulewich /*
119*94bdecd9SRob Gulewich  * Set the zone that all further ioctls will operate on. See the "GZ-controlled
120*94bdecd9SRob Gulewich  * and per-zone stacks" note at the top of ip_fil_solaris.c for further
121*94bdecd9SRob Gulewich  * explanation.
122*94bdecd9SRob Gulewich  */
123*94bdecd9SRob Gulewich int
124*94bdecd9SRob Gulewich setzone(int fd)
125*94bdecd9SRob Gulewich {
126*94bdecd9SRob Gulewich 	if (!do_setzone)
127*94bdecd9SRob Gulewich 		return (0);
128*94bdecd9SRob Gulewich 
129*94bdecd9SRob Gulewich 	if (num_setzones > 1) {
130*94bdecd9SRob Gulewich 		(void) fprintf(stderr,
131*94bdecd9SRob Gulewich 		    "Only one of -G and -z may be set\n");
132*94bdecd9SRob Gulewich 		return (-1);
133*94bdecd9SRob Gulewich 	}
134*94bdecd9SRob Gulewich 
135*94bdecd9SRob Gulewich 	if (ipzo.ipfz_gz == 1 &&
136*94bdecd9SRob Gulewich 	    getzoneidbyname(ipzo.ipfz_zonename) == GLOBAL_ZONEID) {
137*94bdecd9SRob Gulewich 		(void) fprintf(stderr,
138*94bdecd9SRob Gulewich 		    "-G cannot be used with the global zone\n");
139*94bdecd9SRob Gulewich 		return (-1);
140*94bdecd9SRob Gulewich 	}
141*94bdecd9SRob Gulewich 
142*94bdecd9SRob Gulewich 	if (ioctl(fd, SIOCIPFZONESET, &ipzo) == -1) {
143*94bdecd9SRob Gulewich 		switch (errno) {
144*94bdecd9SRob Gulewich 		case ENODEV:
145*94bdecd9SRob Gulewich 			(void) fprintf(stderr,
146*94bdecd9SRob Gulewich 			    "Could not find running zone: %s\n",
147*94bdecd9SRob Gulewich 			    ipzo.ipfz_zonename);
148*94bdecd9SRob Gulewich 			break;
149*94bdecd9SRob Gulewich 		case EACCES:
150*94bdecd9SRob Gulewich 			(void) fprintf(stderr,
151*94bdecd9SRob Gulewich 			    "Permission denied setting zone: %s\n",
152*94bdecd9SRob Gulewich 			    ipzo.ipfz_zonename);
153*94bdecd9SRob Gulewich 			break;
154*94bdecd9SRob Gulewich 		default:
155*94bdecd9SRob Gulewich 			perror("Error setting zone");
156*94bdecd9SRob Gulewich 		}
157*94bdecd9SRob Gulewich 		return (-1);
158*94bdecd9SRob Gulewich 	}
159*94bdecd9SRob Gulewich 
160*94bdecd9SRob Gulewich 	return (0);
161*94bdecd9SRob Gulewich }
162