xref: /minix3/sbin/ifconfig/pfsync.c (revision 90b801219a391518dca4b04b17c88ad3b82b6ad9)
1*90b80121SDavid van Moolenbroek /*	$NetBSD: pfsync.c,v 1.1 2009/09/14 10:36:49 degroote Exp $	*/
2*90b80121SDavid van Moolenbroek /*-
3*90b80121SDavid van Moolenbroek  * Copyright (c) 2009 The NetBSD Foundation, Inc.
4*90b80121SDavid van Moolenbroek  * All rights reserved.
5*90b80121SDavid van Moolenbroek  *
6*90b80121SDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
7*90b80121SDavid van Moolenbroek  * modification, are permitted provided that the following conditions
8*90b80121SDavid van Moolenbroek  * are met:
9*90b80121SDavid van Moolenbroek  * 1. Redistributions of source code must retain the above copyright
10*90b80121SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer.
11*90b80121SDavid van Moolenbroek  * 2. Redistributions in binary form must reproduce the above copyright
12*90b80121SDavid van Moolenbroek  *    notice, this list of conditions and the following disclaimer in the
13*90b80121SDavid van Moolenbroek  *    documentation and/or other materials provided with the distribution.
14*90b80121SDavid van Moolenbroek  *
15*90b80121SDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16*90b80121SDavid van Moolenbroek  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17*90b80121SDavid van Moolenbroek  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18*90b80121SDavid van Moolenbroek  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19*90b80121SDavid van Moolenbroek  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20*90b80121SDavid van Moolenbroek  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21*90b80121SDavid van Moolenbroek  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22*90b80121SDavid van Moolenbroek  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23*90b80121SDavid van Moolenbroek  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24*90b80121SDavid van Moolenbroek  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25*90b80121SDavid van Moolenbroek  * POSSIBILITY OF SUCH DAMAGE.
26*90b80121SDavid van Moolenbroek  */
27*90b80121SDavid van Moolenbroek 
28*90b80121SDavid van Moolenbroek #include <sys/cdefs.h>
29*90b80121SDavid van Moolenbroek #ifndef lint
30*90b80121SDavid van Moolenbroek __RCSID("$NetBSD: pfsync.c,v 1.1 2009/09/14 10:36:49 degroote Exp $");
31*90b80121SDavid van Moolenbroek #endif /* not lint */
32*90b80121SDavid van Moolenbroek 
33*90b80121SDavid van Moolenbroek #include <sys/param.h>
34*90b80121SDavid van Moolenbroek #include <sys/ioctl.h>
35*90b80121SDavid van Moolenbroek #include <sys/socket.h>
36*90b80121SDavid van Moolenbroek #include <sys/sockio.h>
37*90b80121SDavid van Moolenbroek 
38*90b80121SDavid van Moolenbroek #include <net/if.h>
39*90b80121SDavid van Moolenbroek #include <net/route.h>
40*90b80121SDavid van Moolenbroek #include <net/pfvar.h>
41*90b80121SDavid van Moolenbroek #include <net/if_pfsync.h>
42*90b80121SDavid van Moolenbroek 
43*90b80121SDavid van Moolenbroek #include <arpa/inet.h>
44*90b80121SDavid van Moolenbroek 
45*90b80121SDavid van Moolenbroek #include <stdio.h>
46*90b80121SDavid van Moolenbroek #include <string.h>
47*90b80121SDavid van Moolenbroek #include <stdlib.h>
48*90b80121SDavid van Moolenbroek #include <unistd.h>
49*90b80121SDavid van Moolenbroek #include <err.h>
50*90b80121SDavid van Moolenbroek #include <errno.h>
51*90b80121SDavid van Moolenbroek #include <util.h>
52*90b80121SDavid van Moolenbroek 
53*90b80121SDavid van Moolenbroek #include "env.h"
54*90b80121SDavid van Moolenbroek #include "parse.h"
55*90b80121SDavid van Moolenbroek #include "extern.h"
56*90b80121SDavid van Moolenbroek 
57*90b80121SDavid van Moolenbroek static status_func_t status;
58*90b80121SDavid van Moolenbroek static usage_func_t usage;
59*90b80121SDavid van Moolenbroek static cmdloop_branch_t branch;
60*90b80121SDavid van Moolenbroek 
61*90b80121SDavid van Moolenbroek static void pfsync_constructor(void) __attribute__((constructor));
62*90b80121SDavid van Moolenbroek static void pfsync_status(prop_dictionary_t, prop_dictionary_t);
63*90b80121SDavid van Moolenbroek static int setpfsync_maxupd(prop_dictionary_t, prop_dictionary_t);
64*90b80121SDavid van Moolenbroek static int setpfsync_peer(prop_dictionary_t, prop_dictionary_t);
65*90b80121SDavid van Moolenbroek static int setpfsyncdev(prop_dictionary_t, prop_dictionary_t);
66*90b80121SDavid van Moolenbroek 
67*90b80121SDavid van Moolenbroek struct pinteger parse_maxupd = PINTEGER_INITIALIZER1(&parse_maxupd, "maxupd",
68*90b80121SDavid van Moolenbroek     0, 255, 10, setpfsync_maxupd, "maxupd", &command_root.pb_parser);
69*90b80121SDavid van Moolenbroek 
70*90b80121SDavid van Moolenbroek struct piface pfsyncdev = PIFACE_INITIALIZER(&pfsyncdev, "syncdev", setpfsyncdev,
71*90b80121SDavid van Moolenbroek     "syncdev", &command_root.pb_parser);
72*90b80121SDavid van Moolenbroek 
73*90b80121SDavid van Moolenbroek struct paddr parse_sync_peer = PADDR_INITIALIZER(&parse_sync_peer, "syncpeer",
74*90b80121SDavid van Moolenbroek 		setpfsync_peer, "syncpeer", NULL, NULL, NULL, &command_root.pb_parser);
75*90b80121SDavid van Moolenbroek 
76*90b80121SDavid van Moolenbroek static const struct kwinst pfsynckw[] = {
77*90b80121SDavid van Moolenbroek 	{.k_word = "maxupd", .k_nextparser = &parse_maxupd.pi_parser},
78*90b80121SDavid van Moolenbroek 	{.k_word = "syncdev", .k_nextparser = &pfsyncdev.pif_parser},
79*90b80121SDavid van Moolenbroek 	{.k_word = "-syncdev", .k_key = "syncdev", .k_type = KW_T_STR,
80*90b80121SDavid van Moolenbroek 	    .k_str = "", .k_exec = setpfsyncdev,
81*90b80121SDavid van Moolenbroek 	    .k_nextparser = &command_root.pb_parser},
82*90b80121SDavid van Moolenbroek 	{.k_word = "syncpeer", .k_nextparser = &parse_sync_peer.pa_parser},
83*90b80121SDavid van Moolenbroek 	{.k_word = "-syncpeer", .k_key = "syncpeer", .k_type = KW_T_STR,
84*90b80121SDavid van Moolenbroek 	    .k_str = "", .k_exec = setpfsync_peer,
85*90b80121SDavid van Moolenbroek 	    .k_nextparser = &command_root.pb_parser}
86*90b80121SDavid van Moolenbroek };
87*90b80121SDavid van Moolenbroek 
88*90b80121SDavid van Moolenbroek struct pkw pfsync = PKW_INITIALIZER(&pfsync, "pfsync", NULL, NULL,
89*90b80121SDavid van Moolenbroek     pfsynckw, __arraycount(pfsynckw), NULL);
90*90b80121SDavid van Moolenbroek 
91*90b80121SDavid van Moolenbroek static void
pfsync_set(prop_dictionary_t env,struct pfsyncreq * pfsyncr)92*90b80121SDavid van Moolenbroek pfsync_set(prop_dictionary_t env, struct pfsyncreq *pfsyncr)
93*90b80121SDavid van Moolenbroek {
94*90b80121SDavid van Moolenbroek 	if (indirect_ioctl(env, SIOCSETPFSYNC, pfsyncr) == -1)
95*90b80121SDavid van Moolenbroek 		err(EXIT_FAILURE, "SIOCSETPFSYNC");
96*90b80121SDavid van Moolenbroek }
97*90b80121SDavid van Moolenbroek 
98*90b80121SDavid van Moolenbroek static int
pfsync_get1(prop_dictionary_t env,struct pfsyncreq * pfsyncr)99*90b80121SDavid van Moolenbroek pfsync_get1(prop_dictionary_t env, struct pfsyncreq *pfsyncr)
100*90b80121SDavid van Moolenbroek {
101*90b80121SDavid van Moolenbroek 	memset(pfsyncr, 0, sizeof(*pfsyncr));
102*90b80121SDavid van Moolenbroek 
103*90b80121SDavid van Moolenbroek 	return indirect_ioctl(env, SIOCGETPFSYNC, pfsyncr);
104*90b80121SDavid van Moolenbroek }
105*90b80121SDavid van Moolenbroek 
106*90b80121SDavid van Moolenbroek static void
pfsync_get(prop_dictionary_t env,struct pfsyncreq * pfsyncr)107*90b80121SDavid van Moolenbroek pfsync_get(prop_dictionary_t env, struct pfsyncreq *pfsyncr)
108*90b80121SDavid van Moolenbroek {
109*90b80121SDavid van Moolenbroek 	if (pfsync_get1(env, pfsyncr) == -1)
110*90b80121SDavid van Moolenbroek 		err(EXIT_FAILURE, "SIOCGETPFSYNC");
111*90b80121SDavid van Moolenbroek }
112*90b80121SDavid van Moolenbroek 
113*90b80121SDavid van Moolenbroek static void
pfsync_status(prop_dictionary_t env,prop_dictionary_t oenv)114*90b80121SDavid van Moolenbroek pfsync_status(prop_dictionary_t env, prop_dictionary_t oenv)
115*90b80121SDavid van Moolenbroek {
116*90b80121SDavid van Moolenbroek 	struct pfsyncreq pfsyncr;
117*90b80121SDavid van Moolenbroek 
118*90b80121SDavid van Moolenbroek 	if (pfsync_get1(env, &pfsyncr) == -1)
119*90b80121SDavid van Moolenbroek 		return;
120*90b80121SDavid van Moolenbroek 
121*90b80121SDavid van Moolenbroek 	if (pfsyncr.pfsyncr_syncdev[0] != '\0') {
122*90b80121SDavid van Moolenbroek 		printf("\tpfsync: syncdev: %s ", pfsyncr.pfsyncr_syncdev);
123*90b80121SDavid van Moolenbroek 		if (pfsyncr.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP)
124*90b80121SDavid van Moolenbroek 			printf("syncpeer: %s ",
125*90b80121SDavid van Moolenbroek 			    inet_ntoa(pfsyncr.pfsyncr_syncpeer));
126*90b80121SDavid van Moolenbroek 		printf("maxupd: %d\n", pfsyncr.pfsyncr_maxupdates);
127*90b80121SDavid van Moolenbroek 	}
128*90b80121SDavid van Moolenbroek }
129*90b80121SDavid van Moolenbroek 
130*90b80121SDavid van Moolenbroek /* ARGSUSED */
131*90b80121SDavid van Moolenbroek int
setpfsync_maxupd(prop_dictionary_t env,prop_dictionary_t oenv)132*90b80121SDavid van Moolenbroek setpfsync_maxupd(prop_dictionary_t env, prop_dictionary_t oenv)
133*90b80121SDavid van Moolenbroek {
134*90b80121SDavid van Moolenbroek 	struct pfsyncreq pfsyncr;
135*90b80121SDavid van Moolenbroek 	uint8_t maxupd;
136*90b80121SDavid van Moolenbroek 
137*90b80121SDavid van Moolenbroek 	if (!prop_dictionary_get_uint8(env, "maxupd", &maxupd)) {
138*90b80121SDavid van Moolenbroek 		errno = ENOENT;
139*90b80121SDavid van Moolenbroek 		return -1;
140*90b80121SDavid van Moolenbroek 	}
141*90b80121SDavid van Moolenbroek 
142*90b80121SDavid van Moolenbroek 	pfsync_get(env, &pfsyncr);
143*90b80121SDavid van Moolenbroek 
144*90b80121SDavid van Moolenbroek 	pfsyncr.pfsyncr_maxupdates = maxupd;
145*90b80121SDavid van Moolenbroek 
146*90b80121SDavid van Moolenbroek 	pfsync_set(env, &pfsyncr);
147*90b80121SDavid van Moolenbroek 	return 0;
148*90b80121SDavid van Moolenbroek }
149*90b80121SDavid van Moolenbroek 
150*90b80121SDavid van Moolenbroek 
151*90b80121SDavid van Moolenbroek /* ARGSUSED */
152*90b80121SDavid van Moolenbroek int
setpfsyncdev(prop_dictionary_t env,prop_dictionary_t oenv)153*90b80121SDavid van Moolenbroek setpfsyncdev(prop_dictionary_t env, prop_dictionary_t oenv)
154*90b80121SDavid van Moolenbroek {
155*90b80121SDavid van Moolenbroek 	struct pfsyncreq pfsyncr;
156*90b80121SDavid van Moolenbroek 	const char *dev;
157*90b80121SDavid van Moolenbroek 
158*90b80121SDavid van Moolenbroek 	if (!prop_dictionary_get_cstring_nocopy(env, "syncdev", &dev)) {
159*90b80121SDavid van Moolenbroek 		errno = ENOENT;
160*90b80121SDavid van Moolenbroek 		return -1;
161*90b80121SDavid van Moolenbroek 	}
162*90b80121SDavid van Moolenbroek 
163*90b80121SDavid van Moolenbroek 	pfsync_get(env, &pfsyncr);
164*90b80121SDavid van Moolenbroek 
165*90b80121SDavid van Moolenbroek 	strlcpy(pfsyncr.pfsyncr_syncdev, dev, sizeof(pfsyncr.pfsyncr_syncdev));
166*90b80121SDavid van Moolenbroek 
167*90b80121SDavid van Moolenbroek 	pfsync_set(env, &pfsyncr);
168*90b80121SDavid van Moolenbroek 	return 0;
169*90b80121SDavid van Moolenbroek }
170*90b80121SDavid van Moolenbroek 
171*90b80121SDavid van Moolenbroek /* ARGSUSED */
172*90b80121SDavid van Moolenbroek int
setpfsync_peer(prop_dictionary_t env,prop_dictionary_t oenv)173*90b80121SDavid van Moolenbroek setpfsync_peer(prop_dictionary_t env, prop_dictionary_t oenv)
174*90b80121SDavid van Moolenbroek {
175*90b80121SDavid van Moolenbroek 	struct pfsyncreq pfsyncr;
176*90b80121SDavid van Moolenbroek 	prop_data_t data;
177*90b80121SDavid van Moolenbroek 	const struct paddr_prefix *peerpfx;
178*90b80121SDavid van Moolenbroek 	const struct sockaddr_in *s;
179*90b80121SDavid van Moolenbroek 
180*90b80121SDavid van Moolenbroek 	data = (prop_data_t)prop_dictionary_get(env, "syncpeer");
181*90b80121SDavid van Moolenbroek 	if (data == NULL) {
182*90b80121SDavid van Moolenbroek 		errno = ENOENT;
183*90b80121SDavid van Moolenbroek 		return -1;
184*90b80121SDavid van Moolenbroek 	}
185*90b80121SDavid van Moolenbroek 
186*90b80121SDavid van Moolenbroek 	pfsync_get(env, &pfsyncr);
187*90b80121SDavid van Moolenbroek 
188*90b80121SDavid van Moolenbroek 	peerpfx = prop_data_data_nocopy(data);
189*90b80121SDavid van Moolenbroek 
190*90b80121SDavid van Moolenbroek 	if (peerpfx != NULL) {
191*90b80121SDavid van Moolenbroek 		// Only AF_INET is supported for now
192*90b80121SDavid van Moolenbroek 		if (peerpfx->pfx_addr.sa_family != AF_INET) {
193*90b80121SDavid van Moolenbroek 			errno = ENOENT;
194*90b80121SDavid van Moolenbroek 			return -1;
195*90b80121SDavid van Moolenbroek 		}
196*90b80121SDavid van Moolenbroek 
197*90b80121SDavid van Moolenbroek 
198*90b80121SDavid van Moolenbroek 		s = (const struct sockaddr_in*)&peerpfx->pfx_addr;
199*90b80121SDavid van Moolenbroek 
200*90b80121SDavid van Moolenbroek 		memcpy(&pfsyncr.pfsyncr_syncpeer.s_addr, &s->sin_addr,
201*90b80121SDavid van Moolenbroek 		    MIN(sizeof(pfsyncr.pfsyncr_syncpeer.s_addr),
202*90b80121SDavid van Moolenbroek 		    peerpfx->pfx_addr.sa_len));
203*90b80121SDavid van Moolenbroek 	} else {
204*90b80121SDavid van Moolenbroek 		memset(&pfsyncr.pfsyncr_syncpeer.s_addr, 0,
205*90b80121SDavid van Moolenbroek 		    sizeof(pfsyncr.pfsyncr_syncpeer.s_addr));
206*90b80121SDavid van Moolenbroek 	}
207*90b80121SDavid van Moolenbroek 
208*90b80121SDavid van Moolenbroek 	pfsync_set(env, &pfsyncr);
209*90b80121SDavid van Moolenbroek 
210*90b80121SDavid van Moolenbroek 	return 0;
211*90b80121SDavid van Moolenbroek }
212*90b80121SDavid van Moolenbroek 
213*90b80121SDavid van Moolenbroek static void
pfsync_usage(prop_dictionary_t env)214*90b80121SDavid van Moolenbroek pfsync_usage(prop_dictionary_t env)
215*90b80121SDavid van Moolenbroek {
216*90b80121SDavid van Moolenbroek 	fprintf(stderr,
217*90b80121SDavid van Moolenbroek 	    "\t[ maxupd n ] [ syncdev iface ] [syncpeer peer_addr]\n");
218*90b80121SDavid van Moolenbroek }
219*90b80121SDavid van Moolenbroek 
220*90b80121SDavid van Moolenbroek static void
pfsync_constructor(void)221*90b80121SDavid van Moolenbroek pfsync_constructor(void)
222*90b80121SDavid van Moolenbroek {
223*90b80121SDavid van Moolenbroek 	cmdloop_branch_init(&branch, &pfsync.pk_parser);
224*90b80121SDavid van Moolenbroek 	register_cmdloop_branch(&branch);
225*90b80121SDavid van Moolenbroek 	status_func_init(&status, pfsync_status);
226*90b80121SDavid van Moolenbroek 	usage_func_init(&usage, pfsync_usage);
227*90b80121SDavid van Moolenbroek 	register_status(&status);
228*90b80121SDavid van Moolenbroek 	register_usage(&usage);
229*90b80121SDavid van Moolenbroek }
230