1142215Sglebius/*
2142215Sglebius * Copyright (c) 2003 Ryan McBride. All rights reserved.
3142215Sglebius * Copyright (c) 2004 Max Laier. All rights reserved.
4142215Sglebius *
5142215Sglebius * Redistribution and use in source and binary forms, with or without
6142215Sglebius * modification, are permitted provided that the following conditions
7142215Sglebius * are met:
8142215Sglebius * 1. Redistributions of source code must retain the above copyright
9142215Sglebius *    notice, this list of conditions and the following disclaimer.
10142215Sglebius * 2. Redistributions in binary form must reproduce the above copyright
11142215Sglebius *    notice, this list of conditions and the following disclaimer in the
12142215Sglebius *    documentation and/or other materials provided with the distribution.
13142215Sglebius *
14142215Sglebius * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15142215Sglebius * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16142215Sglebius * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17142215Sglebius * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18142215Sglebius * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19142215Sglebius * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20142215Sglebius * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21142215Sglebius * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22142215Sglebius * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23142215Sglebius * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24142215Sglebius * SUCH DAMAGE.
25142215Sglebius *
26142215Sglebius * $FreeBSD: stable/10/sbin/ifconfig/ifpfsync.c 319265 2017-05-30 22:45:01Z asomers $
27142215Sglebius */
28142215Sglebius
29289986Sngie#include <sys/param.h>
30142215Sglebius#include <sys/ioctl.h>
31142215Sglebius#include <sys/socket.h>
32142215Sglebius
33142215Sglebius#include <net/if.h>
34142215Sglebius#include <netinet/in.h>
35142215Sglebius#include <net/pfvar.h>
36142215Sglebius#include <net/if_pfsync.h>
37142215Sglebius#include <net/route.h>
38145842Smlaier#include <arpa/inet.h>
39142215Sglebius
40142215Sglebius#include <err.h>
41145842Smlaier#include <netdb.h>
42142215Sglebius#include <stdio.h>
43142215Sglebius#include <stdlib.h>
44142215Sglebius#include <string.h>
45142215Sglebius#include <unistd.h>
46142215Sglebius
47142215Sglebius#include "ifconfig.h"
48142215Sglebius
49145842Smlaiervoid setpfsync_syncdev(const char *, int, int, const struct afswtch *);
50145842Smlaiervoid unsetpfsync_syncdev(const char *, int, int, const struct afswtch *);
51145842Smlaiervoid setpfsync_syncpeer(const char *, int, int, const struct afswtch *);
52145842Smlaiervoid unsetpfsync_syncpeer(const char *, int, int, const struct afswtch *);
53145842Smlaiervoid setpfsync_syncpeer(const char *, int, int, const struct afswtch *);
54145842Smlaiervoid setpfsync_maxupd(const char *, int, int, const struct afswtch *);
55233847Sglebiusvoid setpfsync_defer(const char *, int, int, const struct afswtch *);
56142224Sglebiusvoid pfsync_status(int);
57142215Sglebius
58142215Sglebiusvoid
59145842Smlaiersetpfsync_syncdev(const char *val, int d, int s, const struct afswtch *rafp)
60142215Sglebius{
61142215Sglebius	struct pfsyncreq preq;
62142215Sglebius
63142215Sglebius	bzero((char *)&preq, sizeof(struct pfsyncreq));
64142215Sglebius	ifr.ifr_data = (caddr_t)&preq;
65142215Sglebius
66142215Sglebius	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
67142215Sglebius		err(1, "SIOCGETPFSYNC");
68142215Sglebius
69145842Smlaier	strlcpy(preq.pfsyncr_syncdev, val, sizeof(preq.pfsyncr_syncdev));
70142215Sglebius
71142215Sglebius	if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
72142215Sglebius		err(1, "SIOCSETPFSYNC");
73142215Sglebius}
74142215Sglebius
75145842Smlaier/* ARGSUSED */
76142215Sglebiusvoid
77145842Smlaierunsetpfsync_syncdev(const char *val, int d, int s, const struct afswtch *rafp)
78142215Sglebius{
79142215Sglebius	struct pfsyncreq preq;
80142215Sglebius
81142215Sglebius	bzero((char *)&preq, sizeof(struct pfsyncreq));
82142215Sglebius	ifr.ifr_data = (caddr_t)&preq;
83142215Sglebius
84142215Sglebius	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
85142215Sglebius		err(1, "SIOCGETPFSYNC");
86142215Sglebius
87145842Smlaier	bzero((char *)&preq.pfsyncr_syncdev, sizeof(preq.pfsyncr_syncdev));
88142215Sglebius
89142215Sglebius	if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
90142215Sglebius		err(1, "SIOCSETPFSYNC");
91142215Sglebius}
92142215Sglebius
93145842Smlaier/* ARGSUSED */
94142215Sglebiusvoid
95145842Smlaiersetpfsync_syncpeer(const char *val, int d, int s, const struct afswtch *rafp)
96145842Smlaier{
97145842Smlaier	struct pfsyncreq preq;
98145842Smlaier	struct addrinfo hints, *peerres;
99145842Smlaier	int ecode;
100145842Smlaier
101145842Smlaier	bzero((char *)&preq, sizeof(struct pfsyncreq));
102145842Smlaier	ifr.ifr_data = (caddr_t)&preq;
103145842Smlaier
104145842Smlaier	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
105145842Smlaier		err(1, "SIOCGETPFSYNC");
106145842Smlaier
107145842Smlaier	memset(&hints, 0, sizeof(hints));
108145842Smlaier	hints.ai_family = AF_INET;
109145842Smlaier	hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
110145842Smlaier
111145842Smlaier	if ((ecode = getaddrinfo(val, NULL, &hints, &peerres)) != 0)
112145842Smlaier		errx(1, "error in parsing address string: %s",
113145842Smlaier		    gai_strerror(ecode));
114145842Smlaier
115145842Smlaier	if (peerres->ai_addr->sa_family != AF_INET)
116145842Smlaier		errx(1, "only IPv4 addresses supported for the syncpeer");
117145842Smlaier
118145842Smlaier	preq.pfsyncr_syncpeer.s_addr = ((struct sockaddr_in *)
119145842Smlaier	    peerres->ai_addr)->sin_addr.s_addr;
120145842Smlaier
121145842Smlaier	if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
122145842Smlaier		err(1, "SIOCSETPFSYNC");
123319265Sasomers	freeaddrinfo(peerres);
124145842Smlaier}
125145842Smlaier
126145842Smlaier/* ARGSUSED */
127145842Smlaiervoid
128145842Smlaierunsetpfsync_syncpeer(const char *val, int d, int s, const struct afswtch *rafp)
129145842Smlaier{
130145842Smlaier	struct pfsyncreq preq;
131145842Smlaier
132145842Smlaier	bzero((char *)&preq, sizeof(struct pfsyncreq));
133145842Smlaier	ifr.ifr_data = (caddr_t)&preq;
134145842Smlaier
135145842Smlaier	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
136145842Smlaier		err(1, "SIOCGETPFSYNC");
137145842Smlaier
138145842Smlaier	preq.pfsyncr_syncpeer.s_addr = 0;
139145842Smlaier
140145842Smlaier	if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
141145842Smlaier		err(1, "SIOCSETPFSYNC");
142145842Smlaier}
143145842Smlaier
144145842Smlaier/* ARGSUSED */
145145842Smlaiervoid
146142215Sglebiussetpfsync_maxupd(const char *val, int d, int s, const struct afswtch *rafp)
147142215Sglebius{
148145842Smlaier	struct pfsyncreq preq;
149142215Sglebius	int maxupdates;
150142215Sglebius
151142215Sglebius	maxupdates = atoi(val);
152145842Smlaier	if ((maxupdates < 0) || (maxupdates > 255))
153145842Smlaier		errx(1, "maxupd %s: out of range", val);
154142215Sglebius
155142215Sglebius	memset((char *)&preq, 0, sizeof(struct pfsyncreq));
156142215Sglebius	ifr.ifr_data = (caddr_t)&preq;
157142215Sglebius
158142215Sglebius	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
159142215Sglebius		err(1, "SIOCGETPFSYNC");
160142215Sglebius
161142215Sglebius	preq.pfsyncr_maxupdates = maxupdates;
162142215Sglebius
163142215Sglebius	if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
164142215Sglebius		err(1, "SIOCSETPFSYNC");
165142215Sglebius}
166142215Sglebius
167233847Sglebius/* ARGSUSED */
168142215Sglebiusvoid
169233847Sglebiussetpfsync_defer(const char *val, int d, int s, const struct afswtch *rafp)
170233847Sglebius{
171233847Sglebius	struct pfsyncreq preq;
172233847Sglebius
173233847Sglebius	memset((char *)&preq, 0, sizeof(struct pfsyncreq));
174233847Sglebius	ifr.ifr_data = (caddr_t)&preq;
175233847Sglebius
176233847Sglebius	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
177233847Sglebius		err(1, "SIOCGETPFSYNC");
178233847Sglebius
179233847Sglebius	preq.pfsyncr_defer = d;
180233847Sglebius	if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
181233847Sglebius		err(1, "SIOCSETPFSYNC");
182233847Sglebius}
183233847Sglebius
184233847Sglebiusvoid
185142224Sglebiuspfsync_status(int s)
186142215Sglebius{
187142215Sglebius	struct pfsyncreq preq;
188142215Sglebius
189142215Sglebius	bzero((char *)&preq, sizeof(struct pfsyncreq));
190142215Sglebius	ifr.ifr_data = (caddr_t)&preq;
191142215Sglebius
192142215Sglebius	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
193142215Sglebius		return;
194142215Sglebius
195159336Sglebius	if (preq.pfsyncr_syncdev[0] != '\0' ||
196159336Sglebius	    preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP)
197159336Sglebius			printf("\t");
198159336Sglebius
199159336Sglebius	if (preq.pfsyncr_syncdev[0] != '\0')
200159336Sglebius		printf("pfsync: syncdev: %s ", preq.pfsyncr_syncdev);
201159336Sglebius	if (preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP)
202159336Sglebius		printf("syncpeer: %s ", inet_ntoa(preq.pfsyncr_syncpeer));
203159336Sglebius
204159336Sglebius	if (preq.pfsyncr_syncdev[0] != '\0' ||
205233847Sglebius	    preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP) {
206233847Sglebius		printf("maxupd: %d ", preq.pfsyncr_maxupdates);
207233847Sglebius		printf("defer: %s\n", preq.pfsyncr_defer ? "on" : "off");
208233847Sglebius	}
209142215Sglebius}
210142215Sglebius
211142215Sglebiusstatic struct cmd pfsync_cmds[] = {
212145842Smlaier	DEF_CMD_ARG("syncdev",		setpfsync_syncdev),
213145842Smlaier	DEF_CMD("-syncdev",	1,	unsetpfsync_syncdev),
214145842Smlaier	DEF_CMD_ARG("syncif",		setpfsync_syncdev),
215145842Smlaier	DEF_CMD("-syncif",	1,	unsetpfsync_syncdev),
216145842Smlaier	DEF_CMD_ARG("syncpeer",		setpfsync_syncpeer),
217145842Smlaier	DEF_CMD("-syncpeer",	1,	unsetpfsync_syncpeer),
218233847Sglebius	DEF_CMD_ARG("maxupd",		setpfsync_maxupd),
219233847Sglebius	DEF_CMD("defer",	1,	setpfsync_defer),
220233847Sglebius	DEF_CMD("-defer",	0,	setpfsync_defer),
221142215Sglebius};
222142215Sglebiusstatic struct afswtch af_pfsync = {
223142215Sglebius	.af_name	= "af_pfsync",
224142215Sglebius	.af_af		= AF_UNSPEC,
225142224Sglebius	.af_other_status = pfsync_status,
226142215Sglebius};
227142215Sglebius
228142215Sglebiusstatic __constructor void
229142215Sglebiuspfsync_ctor(void)
230142215Sglebius{
231142215Sglebius	int i;
232142215Sglebius
233289986Sngie	for (i = 0; i < nitems(pfsync_cmds);  i++)
234142215Sglebius		cmd_register(&pfsync_cmds[i]);
235142215Sglebius	af_register(&af_pfsync);
236142215Sglebius}
237