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: releng/10.2/sbin/ifconfig/ifpfsync.c 233847 2012-04-03 18:10:48Z glebius $
27142215Sglebius */
28142215Sglebius
29142215Sglebius#include <sys/types.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");
123145842Smlaier}
124145842Smlaier
125145842Smlaier/* ARGSUSED */
126145842Smlaiervoid
127145842Smlaierunsetpfsync_syncpeer(const char *val, int d, int s, const struct afswtch *rafp)
128145842Smlaier{
129145842Smlaier	struct pfsyncreq preq;
130145842Smlaier
131145842Smlaier	bzero((char *)&preq, sizeof(struct pfsyncreq));
132145842Smlaier	ifr.ifr_data = (caddr_t)&preq;
133145842Smlaier
134145842Smlaier	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
135145842Smlaier		err(1, "SIOCGETPFSYNC");
136145842Smlaier
137145842Smlaier	preq.pfsyncr_syncpeer.s_addr = 0;
138145842Smlaier
139145842Smlaier	if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
140145842Smlaier		err(1, "SIOCSETPFSYNC");
141145842Smlaier}
142145842Smlaier
143145842Smlaier/* ARGSUSED */
144145842Smlaiervoid
145142215Sglebiussetpfsync_maxupd(const char *val, int d, int s, const struct afswtch *rafp)
146142215Sglebius{
147145842Smlaier	struct pfsyncreq preq;
148142215Sglebius	int maxupdates;
149142215Sglebius
150142215Sglebius	maxupdates = atoi(val);
151145842Smlaier	if ((maxupdates < 0) || (maxupdates > 255))
152145842Smlaier		errx(1, "maxupd %s: out of range", val);
153142215Sglebius
154142215Sglebius	memset((char *)&preq, 0, sizeof(struct pfsyncreq));
155142215Sglebius	ifr.ifr_data = (caddr_t)&preq;
156142215Sglebius
157142215Sglebius	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
158142215Sglebius		err(1, "SIOCGETPFSYNC");
159142215Sglebius
160142215Sglebius	preq.pfsyncr_maxupdates = maxupdates;
161142215Sglebius
162142215Sglebius	if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
163142215Sglebius		err(1, "SIOCSETPFSYNC");
164142215Sglebius}
165142215Sglebius
166233847Sglebius/* ARGSUSED */
167142215Sglebiusvoid
168233847Sglebiussetpfsync_defer(const char *val, int d, int s, const struct afswtch *rafp)
169233847Sglebius{
170233847Sglebius	struct pfsyncreq preq;
171233847Sglebius
172233847Sglebius	memset((char *)&preq, 0, sizeof(struct pfsyncreq));
173233847Sglebius	ifr.ifr_data = (caddr_t)&preq;
174233847Sglebius
175233847Sglebius	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
176233847Sglebius		err(1, "SIOCGETPFSYNC");
177233847Sglebius
178233847Sglebius	preq.pfsyncr_defer = d;
179233847Sglebius	if (ioctl(s, SIOCSETPFSYNC, (caddr_t)&ifr) == -1)
180233847Sglebius		err(1, "SIOCSETPFSYNC");
181233847Sglebius}
182233847Sglebius
183233847Sglebiusvoid
184142224Sglebiuspfsync_status(int s)
185142215Sglebius{
186142215Sglebius	struct pfsyncreq preq;
187142215Sglebius
188142215Sglebius	bzero((char *)&preq, sizeof(struct pfsyncreq));
189142215Sglebius	ifr.ifr_data = (caddr_t)&preq;
190142215Sglebius
191142215Sglebius	if (ioctl(s, SIOCGETPFSYNC, (caddr_t)&ifr) == -1)
192142215Sglebius		return;
193142215Sglebius
194159336Sglebius	if (preq.pfsyncr_syncdev[0] != '\0' ||
195159336Sglebius	    preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP)
196159336Sglebius			printf("\t");
197159336Sglebius
198159336Sglebius	if (preq.pfsyncr_syncdev[0] != '\0')
199159336Sglebius		printf("pfsync: syncdev: %s ", preq.pfsyncr_syncdev);
200159336Sglebius	if (preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP)
201159336Sglebius		printf("syncpeer: %s ", inet_ntoa(preq.pfsyncr_syncpeer));
202159336Sglebius
203159336Sglebius	if (preq.pfsyncr_syncdev[0] != '\0' ||
204233847Sglebius	    preq.pfsyncr_syncpeer.s_addr != INADDR_PFSYNC_GROUP) {
205233847Sglebius		printf("maxupd: %d ", preq.pfsyncr_maxupdates);
206233847Sglebius		printf("defer: %s\n", preq.pfsyncr_defer ? "on" : "off");
207233847Sglebius	}
208142215Sglebius}
209142215Sglebius
210142215Sglebiusstatic struct cmd pfsync_cmds[] = {
211145842Smlaier	DEF_CMD_ARG("syncdev",		setpfsync_syncdev),
212145842Smlaier	DEF_CMD("-syncdev",	1,	unsetpfsync_syncdev),
213145842Smlaier	DEF_CMD_ARG("syncif",		setpfsync_syncdev),
214145842Smlaier	DEF_CMD("-syncif",	1,	unsetpfsync_syncdev),
215145842Smlaier	DEF_CMD_ARG("syncpeer",		setpfsync_syncpeer),
216145842Smlaier	DEF_CMD("-syncpeer",	1,	unsetpfsync_syncpeer),
217233847Sglebius	DEF_CMD_ARG("maxupd",		setpfsync_maxupd),
218233847Sglebius	DEF_CMD("defer",	1,	setpfsync_defer),
219233847Sglebius	DEF_CMD("-defer",	0,	setpfsync_defer),
220142215Sglebius};
221142215Sglebiusstatic struct afswtch af_pfsync = {
222142215Sglebius	.af_name	= "af_pfsync",
223142215Sglebius	.af_af		= AF_UNSPEC,
224142224Sglebius	.af_other_status = pfsync_status,
225142215Sglebius};
226142215Sglebius
227142215Sglebiusstatic __constructor void
228142215Sglebiuspfsync_ctor(void)
229142215Sglebius{
230142215Sglebius#define	N(a)	(sizeof(a) / sizeof(a[0]))
231142215Sglebius	int i;
232142215Sglebius
233142215Sglebius	for (i = 0; i < N(pfsync_cmds);  i++)
234142215Sglebius		cmd_register(&pfsync_cmds[i]);
235142215Sglebius	af_register(&af_pfsync);
236142215Sglebius#undef N
237142215Sglebius}
238