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