11de7b4b8SPedro F. Giffuni /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 4a9771948SGleb Smirnoff * Copyright (c) 2003 Ryan McBride. All rights reserved. 5a9771948SGleb Smirnoff * Copyright (c) 2004 Max Laier. All rights reserved. 6a9771948SGleb Smirnoff * 7a9771948SGleb Smirnoff * Redistribution and use in source and binary forms, with or without 8a9771948SGleb Smirnoff * modification, are permitted provided that the following conditions 9a9771948SGleb Smirnoff * are met: 10a9771948SGleb Smirnoff * 1. Redistributions of source code must retain the above copyright 11a9771948SGleb Smirnoff * notice, this list of conditions and the following disclaimer. 12a9771948SGleb Smirnoff * 2. Redistributions in binary form must reproduce the above copyright 13a9771948SGleb Smirnoff * notice, this list of conditions and the following disclaimer in the 14a9771948SGleb Smirnoff * documentation and/or other materials provided with the distribution. 15a9771948SGleb Smirnoff * 16a9771948SGleb Smirnoff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17a9771948SGleb Smirnoff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18a9771948SGleb Smirnoff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19a9771948SGleb Smirnoff * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20a9771948SGleb Smirnoff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21a9771948SGleb Smirnoff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22a9771948SGleb Smirnoff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23a9771948SGleb Smirnoff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24a9771948SGleb Smirnoff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25a9771948SGleb Smirnoff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26a9771948SGleb Smirnoff * SUCH DAMAGE. 27a9771948SGleb Smirnoff * 28a9771948SGleb Smirnoff * $FreeBSD$ 29a9771948SGleb Smirnoff */ 30a9771948SGleb Smirnoff 31abd71050SEnji Cooper #include <sys/param.h> 32813c5b75SLuiz Amaral #include <sys/errno.h> 33a9771948SGleb Smirnoff #include <sys/ioctl.h> 34813c5b75SLuiz Amaral #include <sys/nv.h> 35a9771948SGleb Smirnoff #include <sys/socket.h> 36a9771948SGleb Smirnoff 37a9771948SGleb Smirnoff #include <net/if.h> 38a9771948SGleb Smirnoff #include <netinet/in.h> 39a9771948SGleb Smirnoff #include <net/pfvar.h> 40a9771948SGleb Smirnoff #include <net/if_pfsync.h> 41a9771948SGleb Smirnoff #include <net/route.h> 4210a51bf5SMax Laier #include <arpa/inet.h> 43a9771948SGleb Smirnoff 44a9771948SGleb Smirnoff #include <err.h> 4510a51bf5SMax Laier #include <netdb.h> 46a9771948SGleb Smirnoff #include <stdio.h> 47a9771948SGleb Smirnoff #include <stdlib.h> 48a9771948SGleb Smirnoff #include <string.h> 49a9771948SGleb Smirnoff #include <unistd.h> 50a9771948SGleb Smirnoff 51a9771948SGleb Smirnoff #include "ifconfig.h" 52a9771948SGleb Smirnoff 5310a51bf5SMax Laier void setpfsync_syncdev(const char *, int, int, const struct afswtch *); 5410a51bf5SMax Laier void unsetpfsync_syncdev(const char *, int, int, const struct afswtch *); 5510a51bf5SMax Laier void setpfsync_syncpeer(const char *, int, int, const struct afswtch *); 5610a51bf5SMax Laier void unsetpfsync_syncpeer(const char *, int, int, const struct afswtch *); 5710a51bf5SMax Laier void setpfsync_syncpeer(const char *, int, int, const struct afswtch *); 5810a51bf5SMax Laier void setpfsync_maxupd(const char *, int, int, const struct afswtch *); 5974e9ff65SGleb Smirnoff void setpfsync_defer(const char *, int, int, const struct afswtch *); 60ef3abbe8SGleb Smirnoff void pfsync_status(int); 61a9771948SGleb Smirnoff 62813c5b75SLuiz Amaral static int 63813c5b75SLuiz Amaral pfsync_do_ioctl(int s, uint cmd, nvlist_t **nvl) 64813c5b75SLuiz Amaral { 65813c5b75SLuiz Amaral void *data; 66813c5b75SLuiz Amaral size_t nvlen; 67813c5b75SLuiz Amaral 68813c5b75SLuiz Amaral data = nvlist_pack(*nvl, &nvlen); 69813c5b75SLuiz Amaral 70813c5b75SLuiz Amaral ifr.ifr_cap_nv.buffer = malloc(IFR_CAP_NV_MAXBUFSIZE); 71813c5b75SLuiz Amaral memcpy(ifr.ifr_cap_nv.buffer, data, nvlen); 72813c5b75SLuiz Amaral ifr.ifr_cap_nv.buf_length = IFR_CAP_NV_MAXBUFSIZE; 73813c5b75SLuiz Amaral ifr.ifr_cap_nv.length = nvlen; 74813c5b75SLuiz Amaral free(data); 75813c5b75SLuiz Amaral 76813c5b75SLuiz Amaral if (ioctl(s, cmd, (caddr_t)&ifr) == -1) { 77813c5b75SLuiz Amaral free(ifr.ifr_cap_nv.buffer); 78813c5b75SLuiz Amaral return -1; 79813c5b75SLuiz Amaral } 80813c5b75SLuiz Amaral 81813c5b75SLuiz Amaral nvlist_destroy(*nvl); 82813c5b75SLuiz Amaral *nvl = NULL; 83813c5b75SLuiz Amaral 84813c5b75SLuiz Amaral *nvl = nvlist_unpack(ifr.ifr_cap_nv.buffer, ifr.ifr_cap_nv.length, 0); 85813c5b75SLuiz Amaral if (*nvl == NULL) { 86813c5b75SLuiz Amaral free(ifr.ifr_cap_nv.buffer); 87813c5b75SLuiz Amaral return (EIO); 88813c5b75SLuiz Amaral } 89813c5b75SLuiz Amaral 90813c5b75SLuiz Amaral free(ifr.ifr_cap_nv.buffer); 91813c5b75SLuiz Amaral return (errno); 92813c5b75SLuiz Amaral } 93813c5b75SLuiz Amaral 94813c5b75SLuiz Amaral static nvlist_t * 95813c5b75SLuiz Amaral pfsync_sockaddr_to_syncpeer_nvlist(struct sockaddr_storage *sa) 96813c5b75SLuiz Amaral { 97813c5b75SLuiz Amaral nvlist_t *nvl; 98813c5b75SLuiz Amaral 99813c5b75SLuiz Amaral nvl = nvlist_create(0); 100813c5b75SLuiz Amaral if (nvl == NULL) { 101813c5b75SLuiz Amaral return (nvl); 102813c5b75SLuiz Amaral } 103813c5b75SLuiz Amaral 104813c5b75SLuiz Amaral switch (sa->ss_family) { 105813c5b75SLuiz Amaral #ifdef INET 106813c5b75SLuiz Amaral case AF_INET: { 107813c5b75SLuiz Amaral struct sockaddr_in *in = (struct sockaddr_in *)sa; 108813c5b75SLuiz Amaral nvlist_add_number(nvl, "af", in->sin_family); 109813c5b75SLuiz Amaral nvlist_add_binary(nvl, "address", in, sizeof(*in)); 110813c5b75SLuiz Amaral break; 111813c5b75SLuiz Amaral } 112813c5b75SLuiz Amaral #endif 113813c5b75SLuiz Amaral #ifdef INET6 114813c5b75SLuiz Amaral case AF_INET6: { 115813c5b75SLuiz Amaral struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; 116813c5b75SLuiz Amaral nvlist_add_number(nvl, "af", in6->sin6_family); 117813c5b75SLuiz Amaral nvlist_add_binary(nvl, "address", in6, sizeof(*in6)); 118813c5b75SLuiz Amaral break; 119813c5b75SLuiz Amaral } 120813c5b75SLuiz Amaral #endif 121813c5b75SLuiz Amaral default: 122813c5b75SLuiz Amaral nvlist_add_number(nvl, "af", AF_UNSPEC); 123813c5b75SLuiz Amaral nvlist_add_binary(nvl, "address", sa, sizeof(*sa)); 124813c5b75SLuiz Amaral break; 125813c5b75SLuiz Amaral } 126813c5b75SLuiz Amaral 127813c5b75SLuiz Amaral return (nvl); 128813c5b75SLuiz Amaral } 129813c5b75SLuiz Amaral 130813c5b75SLuiz Amaral static int 131813c5b75SLuiz Amaral pfsync_syncpeer_nvlist_to_sockaddr(const nvlist_t *nvl, 132813c5b75SLuiz Amaral struct sockaddr_storage *sa) 133813c5b75SLuiz Amaral { 134813c5b75SLuiz Amaral int af; 135813c5b75SLuiz Amaral 136813c5b75SLuiz Amaral if (!nvlist_exists_number(nvl, "af")) 137813c5b75SLuiz Amaral return (EINVAL); 138813c5b75SLuiz Amaral if (!nvlist_exists_binary(nvl, "address")) 139813c5b75SLuiz Amaral return (EINVAL); 140813c5b75SLuiz Amaral 141813c5b75SLuiz Amaral af = nvlist_get_number(nvl, "af"); 142813c5b75SLuiz Amaral 143813c5b75SLuiz Amaral switch (af) { 144813c5b75SLuiz Amaral #ifdef INET 145813c5b75SLuiz Amaral case AF_INET: { 146813c5b75SLuiz Amaral struct sockaddr_in *in = (struct sockaddr_in *)sa; 147813c5b75SLuiz Amaral size_t len; 148813c5b75SLuiz Amaral const void *addr = nvlist_get_binary(nvl, "address", &len); 149813c5b75SLuiz Amaral in->sin_family = af; 150813c5b75SLuiz Amaral if (len != sizeof(*in)) 151813c5b75SLuiz Amaral return (EINVAL); 152813c5b75SLuiz Amaral 153813c5b75SLuiz Amaral memcpy(in, addr, sizeof(*in)); 154813c5b75SLuiz Amaral break; 155813c5b75SLuiz Amaral } 156813c5b75SLuiz Amaral #endif 157813c5b75SLuiz Amaral #ifdef INET6 158813c5b75SLuiz Amaral case AF_INET6: { 159813c5b75SLuiz Amaral struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; 160813c5b75SLuiz Amaral size_t len; 161813c5b75SLuiz Amaral const void *addr = nvlist_get_binary(nvl, "address", &len); 162813c5b75SLuiz Amaral if (len != sizeof(*in6)) 163813c5b75SLuiz Amaral return (EINVAL); 164813c5b75SLuiz Amaral 165813c5b75SLuiz Amaral memcpy(in6, addr, sizeof(*in6)); 166813c5b75SLuiz Amaral break; 167813c5b75SLuiz Amaral } 168813c5b75SLuiz Amaral #endif 169813c5b75SLuiz Amaral default: 170813c5b75SLuiz Amaral return (EINVAL); 171813c5b75SLuiz Amaral } 172813c5b75SLuiz Amaral 173813c5b75SLuiz Amaral return (0); 174813c5b75SLuiz Amaral } 175813c5b75SLuiz Amaral 176a9771948SGleb Smirnoff void 17710a51bf5SMax Laier setpfsync_syncdev(const char *val, int d, int s, const struct afswtch *rafp) 178a9771948SGleb Smirnoff { 179813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 180a9771948SGleb Smirnoff 181813c5b75SLuiz Amaral if (strlen(val) > IFNAMSIZ) 182813c5b75SLuiz Amaral errx(1, "interface name %s is too long", val); 183a9771948SGleb Smirnoff 184813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1) 185813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 186a9771948SGleb Smirnoff 187813c5b75SLuiz Amaral if (nvlist_exists_string(nvl, "syncdev")) 188813c5b75SLuiz Amaral nvlist_free_string(nvl, "syncdev"); 189a9771948SGleb Smirnoff 190813c5b75SLuiz Amaral nvlist_add_string(nvl, "syncdev", val); 191813c5b75SLuiz Amaral 192813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1) 193813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 194a9771948SGleb Smirnoff } 195a9771948SGleb Smirnoff 19610a51bf5SMax Laier /* ARGSUSED */ 197a9771948SGleb Smirnoff void 19810a51bf5SMax Laier unsetpfsync_syncdev(const char *val, int d, int s, const struct afswtch *rafp) 199a9771948SGleb Smirnoff { 200813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 201a9771948SGleb Smirnoff 202813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1) 203813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 204a9771948SGleb Smirnoff 205813c5b75SLuiz Amaral if (nvlist_exists_string(nvl, "syncdev")) 206813c5b75SLuiz Amaral nvlist_free_string(nvl, "syncdev"); 207a9771948SGleb Smirnoff 208813c5b75SLuiz Amaral nvlist_add_string(nvl, "syncdev", ""); 209a9771948SGleb Smirnoff 210813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1) 211813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 212a9771948SGleb Smirnoff } 213a9771948SGleb Smirnoff 21410a51bf5SMax Laier /* ARGSUSED */ 21510a51bf5SMax Laier void 21610a51bf5SMax Laier setpfsync_syncpeer(const char *val, int d, int s, const struct afswtch *rafp) 21710a51bf5SMax Laier { 218813c5b75SLuiz Amaral struct addrinfo *peerres; 219813c5b75SLuiz Amaral struct sockaddr_storage addr; 22010a51bf5SMax Laier int ecode; 22110a51bf5SMax Laier 222813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 22310a51bf5SMax Laier 224813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1) 225813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 22610a51bf5SMax Laier 227813c5b75SLuiz Amaral if ((ecode = getaddrinfo(val, NULL, NULL, &peerres)) != 0) 22810a51bf5SMax Laier errx(1, "error in parsing address string: %s", 22910a51bf5SMax Laier gai_strerror(ecode)); 23010a51bf5SMax Laier 231813c5b75SLuiz Amaral switch (peerres->ai_family) { 232813c5b75SLuiz Amaral #ifdef INET 233813c5b75SLuiz Amaral case AF_INET: { 234813c5b75SLuiz Amaral struct sockaddr_in *sin = (struct sockaddr_in *) 235813c5b75SLuiz Amaral peerres->ai_addr; 23610a51bf5SMax Laier 237813c5b75SLuiz Amaral if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) 238813c5b75SLuiz Amaral errx(1, "syncpeer address cannot be multicast"); 23910a51bf5SMax Laier 240813c5b75SLuiz Amaral memcpy(&addr, sin, sizeof(*sin)); 241813c5b75SLuiz Amaral break; 242813c5b75SLuiz Amaral } 243813c5b75SLuiz Amaral #endif 244813c5b75SLuiz Amaral default: 245813c5b75SLuiz Amaral errx(1, "syncpeer address %s not supported", val); 246813c5b75SLuiz Amaral } 247813c5b75SLuiz Amaral 248813c5b75SLuiz Amaral if (nvlist_exists_nvlist(nvl, "syncpeer")) 249813c5b75SLuiz Amaral nvlist_free_nvlist(nvl, "syncpeer"); 250813c5b75SLuiz Amaral 251813c5b75SLuiz Amaral nvlist_add_nvlist(nvl, "syncpeer", 252813c5b75SLuiz Amaral pfsync_sockaddr_to_syncpeer_nvlist(&addr)); 253813c5b75SLuiz Amaral 254813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1) 255813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 256813c5b75SLuiz Amaral 257813c5b75SLuiz Amaral nvlist_destroy(nvl); 2586223cc33SAlan Somers freeaddrinfo(peerres); 25910a51bf5SMax Laier } 26010a51bf5SMax Laier 26110a51bf5SMax Laier /* ARGSUSED */ 26210a51bf5SMax Laier void 26310a51bf5SMax Laier unsetpfsync_syncpeer(const char *val, int d, int s, const struct afswtch *rafp) 26410a51bf5SMax Laier { 265813c5b75SLuiz Amaral struct sockaddr_storage addr; 266813c5b75SLuiz Amaral memset(&addr, 0, sizeof(addr)); 26710a51bf5SMax Laier 268813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 26910a51bf5SMax Laier 270813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1) 271813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 27210a51bf5SMax Laier 273813c5b75SLuiz Amaral if (nvlist_exists_nvlist(nvl, "syncpeer")) 274813c5b75SLuiz Amaral nvlist_free_nvlist(nvl, "syncpeer"); 27510a51bf5SMax Laier 276813c5b75SLuiz Amaral nvlist_add_nvlist(nvl, "syncpeer", 277813c5b75SLuiz Amaral pfsync_sockaddr_to_syncpeer_nvlist(&addr)); 278813c5b75SLuiz Amaral 279813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1) 280813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 281813c5b75SLuiz Amaral 282813c5b75SLuiz Amaral nvlist_destroy(nvl); 28310a51bf5SMax Laier } 28410a51bf5SMax Laier 28510a51bf5SMax Laier /* ARGSUSED */ 286a9771948SGleb Smirnoff void 287a9771948SGleb Smirnoff setpfsync_maxupd(const char *val, int d, int s, const struct afswtch *rafp) 288a9771948SGleb Smirnoff { 28910a51bf5SMax Laier int maxupdates; 290813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 291a9771948SGleb Smirnoff 292a9771948SGleb Smirnoff maxupdates = atoi(val); 29310a51bf5SMax Laier if ((maxupdates < 0) || (maxupdates > 255)) 29410a51bf5SMax Laier errx(1, "maxupd %s: out of range", val); 295a9771948SGleb Smirnoff 296813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1) 297813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 298a9771948SGleb Smirnoff 299813c5b75SLuiz Amaral nvlist_free_number(nvl, "maxupdates"); 300813c5b75SLuiz Amaral nvlist_add_number(nvl, "maxupdates", maxupdates); 301a9771948SGleb Smirnoff 302813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1) 303813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 304a9771948SGleb Smirnoff 305813c5b75SLuiz Amaral nvlist_destroy(nvl); 306a9771948SGleb Smirnoff } 307a9771948SGleb Smirnoff 30874e9ff65SGleb Smirnoff /* ARGSUSED */ 30974e9ff65SGleb Smirnoff void 31074e9ff65SGleb Smirnoff setpfsync_defer(const char *val, int d, int s, const struct afswtch *rafp) 31174e9ff65SGleb Smirnoff { 312813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 31374e9ff65SGleb Smirnoff 314813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1) 315813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 31674e9ff65SGleb Smirnoff 317813c5b75SLuiz Amaral nvlist_free_number(nvl, "flags"); 318813c5b75SLuiz Amaral nvlist_add_number(nvl, "flags", d ? PFSYNCF_DEFER : 0); 31974e9ff65SGleb Smirnoff 320813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCSETPFSYNCNV, &nvl) == -1) 321813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 322813c5b75SLuiz Amaral 323813c5b75SLuiz Amaral nvlist_destroy(nvl); 32474e9ff65SGleb Smirnoff } 32574e9ff65SGleb Smirnoff 326a9771948SGleb Smirnoff void 327ef3abbe8SGleb Smirnoff pfsync_status(int s) 328a9771948SGleb Smirnoff { 329813c5b75SLuiz Amaral nvlist_t *nvl; 330813c5b75SLuiz Amaral char syncdev[IFNAMSIZ]; 331813c5b75SLuiz Amaral char syncpeer_str[NI_MAXHOST]; 332813c5b75SLuiz Amaral struct sockaddr_storage syncpeer; 333*44cd85d4SAlexander V. Chernikov int maxupdates = 0; 334*44cd85d4SAlexander V. Chernikov int flags = 0; 335813c5b75SLuiz Amaral int error; 336a9771948SGleb Smirnoff 337813c5b75SLuiz Amaral nvl = nvlist_create(0); 338a9771948SGleb Smirnoff 339813c5b75SLuiz Amaral if (pfsync_do_ioctl(s, SIOCGETPFSYNCNV, &nvl) == -1) { 340813c5b75SLuiz Amaral nvlist_destroy(nvl); 341a9771948SGleb Smirnoff return; 342813c5b75SLuiz Amaral } 343a9771948SGleb Smirnoff 344813c5b75SLuiz Amaral memset((char *)&syncdev, 0, IFNAMSIZ); 345813c5b75SLuiz Amaral if (nvlist_exists_string(nvl, "syncdev")) 346813c5b75SLuiz Amaral strlcpy(syncdev, nvlist_get_string(nvl, "syncdev"), 347813c5b75SLuiz Amaral IFNAMSIZ); 348813c5b75SLuiz Amaral if (nvlist_exists_number(nvl, "maxupdates")) 349813c5b75SLuiz Amaral maxupdates = nvlist_get_number(nvl, "maxupdates"); 350813c5b75SLuiz Amaral if (nvlist_exists_number(nvl, "flags")) 351813c5b75SLuiz Amaral flags = nvlist_get_number(nvl, "flags"); 352813c5b75SLuiz Amaral if (nvlist_exists_nvlist(nvl, "syncpeer")) { 353813c5b75SLuiz Amaral pfsync_syncpeer_nvlist_to_sockaddr(nvlist_get_nvlist(nvl, 354813c5b75SLuiz Amaral "syncpeer"), 355813c5b75SLuiz Amaral &syncpeer); 356813c5b75SLuiz Amaral } 357813c5b75SLuiz Amaral 358813c5b75SLuiz Amaral nvlist_destroy(nvl); 359813c5b75SLuiz Amaral 360813c5b75SLuiz Amaral if (syncdev[0] != '\0' || syncpeer.ss_family != AF_UNSPEC) 36111c4984fSGleb Smirnoff printf("\t"); 36211c4984fSGleb Smirnoff 363813c5b75SLuiz Amaral if (syncdev[0] != '\0') 364813c5b75SLuiz Amaral printf("syncdev: %s ", syncdev); 36511c4984fSGleb Smirnoff 366813c5b75SLuiz Amaral if (syncpeer.ss_family == AF_INET && 367813c5b75SLuiz Amaral ((struct sockaddr_in *)&syncpeer)->sin_addr.s_addr != 368813c5b75SLuiz Amaral htonl(INADDR_PFSYNC_GROUP)) { 369813c5b75SLuiz Amaral 370813c5b75SLuiz Amaral struct sockaddr *syncpeer_sa = 371813c5b75SLuiz Amaral (struct sockaddr *)&syncpeer; 372813c5b75SLuiz Amaral if ((error = getnameinfo(syncpeer_sa, syncpeer_sa->sa_len, 373813c5b75SLuiz Amaral syncpeer_str, sizeof(syncpeer_str), NULL, 0, 374813c5b75SLuiz Amaral NI_NUMERICHOST)) != 0) 375813c5b75SLuiz Amaral errx(1, "getnameinfo: %s", gai_strerror(error)); 376813c5b75SLuiz Amaral printf("syncpeer: %s ", syncpeer_str); 37774e9ff65SGleb Smirnoff } 378813c5b75SLuiz Amaral 379813c5b75SLuiz Amaral printf("maxupd: %d ", maxupdates); 380813c5b75SLuiz Amaral printf("defer: %s\n", (flags & PFSYNCF_DEFER) ? "on" : "off"); 381813c5b75SLuiz Amaral printf("\tsyncok: %d\n", (flags & PFSYNCF_OK) ? 1 : 0); 382a9771948SGleb Smirnoff } 383a9771948SGleb Smirnoff 384a9771948SGleb Smirnoff static struct cmd pfsync_cmds[] = { 38510a51bf5SMax Laier DEF_CMD_ARG("syncdev", setpfsync_syncdev), 38610a51bf5SMax Laier DEF_CMD("-syncdev", 1, unsetpfsync_syncdev), 38710a51bf5SMax Laier DEF_CMD_ARG("syncif", setpfsync_syncdev), 38810a51bf5SMax Laier DEF_CMD("-syncif", 1, unsetpfsync_syncdev), 38910a51bf5SMax Laier DEF_CMD_ARG("syncpeer", setpfsync_syncpeer), 39010a51bf5SMax Laier DEF_CMD("-syncpeer", 1, unsetpfsync_syncpeer), 39174e9ff65SGleb Smirnoff DEF_CMD_ARG("maxupd", setpfsync_maxupd), 39274e9ff65SGleb Smirnoff DEF_CMD("defer", 1, setpfsync_defer), 39374e9ff65SGleb Smirnoff DEF_CMD("-defer", 0, setpfsync_defer), 394a9771948SGleb Smirnoff }; 395a9771948SGleb Smirnoff static struct afswtch af_pfsync = { 396a9771948SGleb Smirnoff .af_name = "af_pfsync", 397a9771948SGleb Smirnoff .af_af = AF_UNSPEC, 398ef3abbe8SGleb Smirnoff .af_other_status = pfsync_status, 399a9771948SGleb Smirnoff }; 400a9771948SGleb Smirnoff 401a9771948SGleb Smirnoff static __constructor void 402a9771948SGleb Smirnoff pfsync_ctor(void) 403a9771948SGleb Smirnoff { 404*44cd85d4SAlexander V. Chernikov for (size_t i = 0; i < nitems(pfsync_cmds); i++) 405a9771948SGleb Smirnoff cmd_register(&pfsync_cmds[i]); 406a9771948SGleb Smirnoff af_register(&af_pfsync); 407a9771948SGleb Smirnoff } 408