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 53813c5b75SLuiz Amaral static int 547fa282e6SAlexander V. Chernikov pfsync_do_ioctl(if_ctx *ctx, uint cmd, nvlist_t **nvl) 55813c5b75SLuiz Amaral { 56813c5b75SLuiz Amaral void *data; 57813c5b75SLuiz Amaral size_t nvlen; 587fa282e6SAlexander V. Chernikov struct ifreq ifr = {}; 59813c5b75SLuiz Amaral 60813c5b75SLuiz Amaral data = nvlist_pack(*nvl, &nvlen); 61813c5b75SLuiz Amaral 62813c5b75SLuiz Amaral ifr.ifr_cap_nv.buffer = malloc(IFR_CAP_NV_MAXBUFSIZE); 63813c5b75SLuiz Amaral memcpy(ifr.ifr_cap_nv.buffer, data, nvlen); 64813c5b75SLuiz Amaral ifr.ifr_cap_nv.buf_length = IFR_CAP_NV_MAXBUFSIZE; 65813c5b75SLuiz Amaral ifr.ifr_cap_nv.length = nvlen; 66813c5b75SLuiz Amaral free(data); 67813c5b75SLuiz Amaral 687fa282e6SAlexander V. Chernikov if (ioctl_ctx_ifr(ctx, cmd, &ifr) == -1) { 69813c5b75SLuiz Amaral free(ifr.ifr_cap_nv.buffer); 70813c5b75SLuiz Amaral return -1; 71813c5b75SLuiz Amaral } 72813c5b75SLuiz Amaral 73813c5b75SLuiz Amaral nvlist_destroy(*nvl); 74813c5b75SLuiz Amaral *nvl = NULL; 75813c5b75SLuiz Amaral 76813c5b75SLuiz Amaral *nvl = nvlist_unpack(ifr.ifr_cap_nv.buffer, ifr.ifr_cap_nv.length, 0); 77813c5b75SLuiz Amaral if (*nvl == NULL) { 78813c5b75SLuiz Amaral free(ifr.ifr_cap_nv.buffer); 79813c5b75SLuiz Amaral return (EIO); 80813c5b75SLuiz Amaral } 81813c5b75SLuiz Amaral 82813c5b75SLuiz Amaral free(ifr.ifr_cap_nv.buffer); 83813c5b75SLuiz Amaral return (errno); 84813c5b75SLuiz Amaral } 85813c5b75SLuiz Amaral 86813c5b75SLuiz Amaral static nvlist_t * 87813c5b75SLuiz Amaral pfsync_sockaddr_to_syncpeer_nvlist(struct sockaddr_storage *sa) 88813c5b75SLuiz Amaral { 89813c5b75SLuiz Amaral nvlist_t *nvl; 90813c5b75SLuiz Amaral 91813c5b75SLuiz Amaral nvl = nvlist_create(0); 92813c5b75SLuiz Amaral if (nvl == NULL) { 93813c5b75SLuiz Amaral return (nvl); 94813c5b75SLuiz Amaral } 95813c5b75SLuiz Amaral 96813c5b75SLuiz Amaral switch (sa->ss_family) { 97813c5b75SLuiz Amaral #ifdef INET 98813c5b75SLuiz Amaral case AF_INET: { 99813c5b75SLuiz Amaral struct sockaddr_in *in = (struct sockaddr_in *)sa; 100813c5b75SLuiz Amaral nvlist_add_number(nvl, "af", in->sin_family); 101813c5b75SLuiz Amaral nvlist_add_binary(nvl, "address", in, sizeof(*in)); 102813c5b75SLuiz Amaral break; 103813c5b75SLuiz Amaral } 104813c5b75SLuiz Amaral #endif 105813c5b75SLuiz Amaral #ifdef INET6 106813c5b75SLuiz Amaral case AF_INET6: { 107813c5b75SLuiz Amaral struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; 108813c5b75SLuiz Amaral nvlist_add_number(nvl, "af", in6->sin6_family); 109813c5b75SLuiz Amaral nvlist_add_binary(nvl, "address", in6, sizeof(*in6)); 110813c5b75SLuiz Amaral break; 111813c5b75SLuiz Amaral } 112813c5b75SLuiz Amaral #endif 113813c5b75SLuiz Amaral default: 114813c5b75SLuiz Amaral nvlist_add_number(nvl, "af", AF_UNSPEC); 115813c5b75SLuiz Amaral nvlist_add_binary(nvl, "address", sa, sizeof(*sa)); 116813c5b75SLuiz Amaral break; 117813c5b75SLuiz Amaral } 118813c5b75SLuiz Amaral 119813c5b75SLuiz Amaral return (nvl); 120813c5b75SLuiz Amaral } 121813c5b75SLuiz Amaral 122813c5b75SLuiz Amaral static int 123813c5b75SLuiz Amaral pfsync_syncpeer_nvlist_to_sockaddr(const nvlist_t *nvl, 124813c5b75SLuiz Amaral struct sockaddr_storage *sa) 125813c5b75SLuiz Amaral { 126813c5b75SLuiz Amaral int af; 127813c5b75SLuiz Amaral 128*cea9f49fSMateusz Guzik #if (!defined INET && !defined INET6) 129*cea9f49fSMateusz Guzik (void)sa; 130*cea9f49fSMateusz Guzik #endif 131*cea9f49fSMateusz Guzik 132813c5b75SLuiz Amaral if (!nvlist_exists_number(nvl, "af")) 133813c5b75SLuiz Amaral return (EINVAL); 134813c5b75SLuiz Amaral if (!nvlist_exists_binary(nvl, "address")) 135813c5b75SLuiz Amaral return (EINVAL); 136813c5b75SLuiz Amaral 137813c5b75SLuiz Amaral af = nvlist_get_number(nvl, "af"); 138813c5b75SLuiz Amaral 139813c5b75SLuiz Amaral switch (af) { 140813c5b75SLuiz Amaral #ifdef INET 141813c5b75SLuiz Amaral case AF_INET: { 142813c5b75SLuiz Amaral struct sockaddr_in *in = (struct sockaddr_in *)sa; 143813c5b75SLuiz Amaral size_t len; 144813c5b75SLuiz Amaral const void *addr = nvlist_get_binary(nvl, "address", &len); 145813c5b75SLuiz Amaral in->sin_family = af; 146813c5b75SLuiz Amaral if (len != sizeof(*in)) 147813c5b75SLuiz Amaral return (EINVAL); 148813c5b75SLuiz Amaral 149813c5b75SLuiz Amaral memcpy(in, addr, sizeof(*in)); 150813c5b75SLuiz Amaral break; 151813c5b75SLuiz Amaral } 152813c5b75SLuiz Amaral #endif 153813c5b75SLuiz Amaral #ifdef INET6 154813c5b75SLuiz Amaral case AF_INET6: { 155813c5b75SLuiz Amaral struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; 156813c5b75SLuiz Amaral size_t len; 157813c5b75SLuiz Amaral const void *addr = nvlist_get_binary(nvl, "address", &len); 158813c5b75SLuiz Amaral if (len != sizeof(*in6)) 159813c5b75SLuiz Amaral return (EINVAL); 160813c5b75SLuiz Amaral 161813c5b75SLuiz Amaral memcpy(in6, addr, sizeof(*in6)); 162813c5b75SLuiz Amaral break; 163813c5b75SLuiz Amaral } 164813c5b75SLuiz Amaral #endif 165813c5b75SLuiz Amaral default: 166813c5b75SLuiz Amaral return (EINVAL); 167813c5b75SLuiz Amaral } 168813c5b75SLuiz Amaral 169813c5b75SLuiz Amaral return (0); 170813c5b75SLuiz Amaral } 171813c5b75SLuiz Amaral 1726e3a9d7fSAlexander V. Chernikov static void 1736e3a9d7fSAlexander V. Chernikov setpfsync_syncdev(if_ctx *ctx, const char *val, int dummy __unused) 174a9771948SGleb Smirnoff { 175813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 176a9771948SGleb Smirnoff 177813c5b75SLuiz Amaral if (strlen(val) > IFNAMSIZ) 178813c5b75SLuiz Amaral errx(1, "interface name %s is too long", val); 179a9771948SGleb Smirnoff 1807fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCGETPFSYNCNV, &nvl) == -1) 181813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 182a9771948SGleb Smirnoff 183813c5b75SLuiz Amaral if (nvlist_exists_string(nvl, "syncdev")) 184813c5b75SLuiz Amaral nvlist_free_string(nvl, "syncdev"); 185a9771948SGleb Smirnoff 186813c5b75SLuiz Amaral nvlist_add_string(nvl, "syncdev", val); 187813c5b75SLuiz Amaral 1887fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCSETPFSYNCNV, &nvl) == -1) 189813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 190a9771948SGleb Smirnoff } 191a9771948SGleb Smirnoff 1926e3a9d7fSAlexander V. Chernikov static void 1930c2beef7SAlexander V. Chernikov unsetpfsync_syncdev(if_ctx *ctx, const char *val __unused, int dummy __unused) 194a9771948SGleb Smirnoff { 195813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 196a9771948SGleb Smirnoff 1977fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCGETPFSYNCNV, &nvl) == -1) 198813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 199a9771948SGleb Smirnoff 200813c5b75SLuiz Amaral if (nvlist_exists_string(nvl, "syncdev")) 201813c5b75SLuiz Amaral nvlist_free_string(nvl, "syncdev"); 202a9771948SGleb Smirnoff 203813c5b75SLuiz Amaral nvlist_add_string(nvl, "syncdev", ""); 204a9771948SGleb Smirnoff 2057fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCSETPFSYNCNV, &nvl) == -1) 206813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 207a9771948SGleb Smirnoff } 208a9771948SGleb Smirnoff 2096e3a9d7fSAlexander V. Chernikov static void 2106e3a9d7fSAlexander V. Chernikov setpfsync_syncpeer(if_ctx *ctx, const char *val, int dummy __unused) 21110a51bf5SMax Laier { 212813c5b75SLuiz Amaral struct addrinfo *peerres; 213813c5b75SLuiz Amaral struct sockaddr_storage addr; 21410a51bf5SMax Laier int ecode; 21510a51bf5SMax Laier 216813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 21710a51bf5SMax Laier 2187fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCGETPFSYNCNV, &nvl) == -1) 219813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 22010a51bf5SMax Laier 221813c5b75SLuiz Amaral if ((ecode = getaddrinfo(val, NULL, NULL, &peerres)) != 0) 22210a51bf5SMax Laier errx(1, "error in parsing address string: %s", 22310a51bf5SMax Laier gai_strerror(ecode)); 22410a51bf5SMax Laier 225813c5b75SLuiz Amaral switch (peerres->ai_family) { 226813c5b75SLuiz Amaral #ifdef INET 227813c5b75SLuiz Amaral case AF_INET: { 2280c2beef7SAlexander V. Chernikov struct sockaddr_in *sin = satosin(peerres->ai_addr); 22910a51bf5SMax Laier 230813c5b75SLuiz Amaral if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) 231813c5b75SLuiz Amaral errx(1, "syncpeer address cannot be multicast"); 23210a51bf5SMax Laier 233813c5b75SLuiz Amaral memcpy(&addr, sin, sizeof(*sin)); 234813c5b75SLuiz Amaral break; 235813c5b75SLuiz Amaral } 236813c5b75SLuiz Amaral #endif 237813c5b75SLuiz Amaral default: 238813c5b75SLuiz Amaral errx(1, "syncpeer address %s not supported", val); 239813c5b75SLuiz Amaral } 240813c5b75SLuiz Amaral 241813c5b75SLuiz Amaral if (nvlist_exists_nvlist(nvl, "syncpeer")) 242813c5b75SLuiz Amaral nvlist_free_nvlist(nvl, "syncpeer"); 243813c5b75SLuiz Amaral 244813c5b75SLuiz Amaral nvlist_add_nvlist(nvl, "syncpeer", 245813c5b75SLuiz Amaral pfsync_sockaddr_to_syncpeer_nvlist(&addr)); 246813c5b75SLuiz Amaral 2477fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCSETPFSYNCNV, &nvl) == -1) 248813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 249813c5b75SLuiz Amaral 250813c5b75SLuiz Amaral nvlist_destroy(nvl); 2516223cc33SAlan Somers freeaddrinfo(peerres); 25210a51bf5SMax Laier } 25310a51bf5SMax Laier 2546e3a9d7fSAlexander V. Chernikov static void 2550c2beef7SAlexander V. Chernikov unsetpfsync_syncpeer(if_ctx *ctx, const char *val __unused, int dummy __unused) 25610a51bf5SMax Laier { 257813c5b75SLuiz Amaral struct sockaddr_storage addr; 258813c5b75SLuiz Amaral memset(&addr, 0, sizeof(addr)); 25910a51bf5SMax Laier 260813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 26110a51bf5SMax Laier 2627fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCGETPFSYNCNV, &nvl) == -1) 263813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 26410a51bf5SMax Laier 265813c5b75SLuiz Amaral if (nvlist_exists_nvlist(nvl, "syncpeer")) 266813c5b75SLuiz Amaral nvlist_free_nvlist(nvl, "syncpeer"); 26710a51bf5SMax Laier 268813c5b75SLuiz Amaral nvlist_add_nvlist(nvl, "syncpeer", 269813c5b75SLuiz Amaral pfsync_sockaddr_to_syncpeer_nvlist(&addr)); 270813c5b75SLuiz Amaral 2717fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCSETPFSYNCNV, &nvl) == -1) 272813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 273813c5b75SLuiz Amaral 274813c5b75SLuiz Amaral nvlist_destroy(nvl); 27510a51bf5SMax Laier } 27610a51bf5SMax Laier 2776e3a9d7fSAlexander V. Chernikov static void 2786e3a9d7fSAlexander V. Chernikov setpfsync_maxupd(if_ctx *ctx, const char *val, int dummy __unused) 279a9771948SGleb Smirnoff { 28010a51bf5SMax Laier int maxupdates; 281813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 282a9771948SGleb Smirnoff 283a9771948SGleb Smirnoff maxupdates = atoi(val); 28410a51bf5SMax Laier if ((maxupdates < 0) || (maxupdates > 255)) 28510a51bf5SMax Laier errx(1, "maxupd %s: out of range", val); 286a9771948SGleb Smirnoff 2877fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCGETPFSYNCNV, &nvl) == -1) 288813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 289a9771948SGleb Smirnoff 290813c5b75SLuiz Amaral nvlist_free_number(nvl, "maxupdates"); 291813c5b75SLuiz Amaral nvlist_add_number(nvl, "maxupdates", maxupdates); 292a9771948SGleb Smirnoff 2937fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCSETPFSYNCNV, &nvl) == -1) 294813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 295a9771948SGleb Smirnoff 296813c5b75SLuiz Amaral nvlist_destroy(nvl); 297a9771948SGleb Smirnoff } 298a9771948SGleb Smirnoff 2996e3a9d7fSAlexander V. Chernikov static void 3000c2beef7SAlexander V. Chernikov setpfsync_defer(if_ctx *ctx, const char *val __unused, int d) 30174e9ff65SGleb Smirnoff { 302813c5b75SLuiz Amaral nvlist_t *nvl = nvlist_create(0); 30374e9ff65SGleb Smirnoff 3047fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCGETPFSYNCNV, &nvl) == -1) 305813c5b75SLuiz Amaral err(1, "SIOCGETPFSYNCNV"); 30674e9ff65SGleb Smirnoff 307813c5b75SLuiz Amaral nvlist_free_number(nvl, "flags"); 308813c5b75SLuiz Amaral nvlist_add_number(nvl, "flags", d ? PFSYNCF_DEFER : 0); 30974e9ff65SGleb Smirnoff 3107fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCSETPFSYNCNV, &nvl) == -1) 311813c5b75SLuiz Amaral err(1, "SIOCSETPFSYNCNV"); 312813c5b75SLuiz Amaral 313813c5b75SLuiz Amaral nvlist_destroy(nvl); 31474e9ff65SGleb Smirnoff } 31574e9ff65SGleb Smirnoff 3166e3a9d7fSAlexander V. Chernikov static void 3174bf98559SKajetan Staszkiewicz setpfsync_version(if_ctx *ctx, const char *val, int dummy __unused) 3184bf98559SKajetan Staszkiewicz { 3194bf98559SKajetan Staszkiewicz int version; 3204bf98559SKajetan Staszkiewicz nvlist_t *nvl = nvlist_create(0); 3214bf98559SKajetan Staszkiewicz 3224bf98559SKajetan Staszkiewicz /* Don't verify, kernel knows which versions are supported.*/ 3234bf98559SKajetan Staszkiewicz version = atoi(val); 3244bf98559SKajetan Staszkiewicz 3257fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCGETPFSYNCNV, &nvl) == -1) 3264bf98559SKajetan Staszkiewicz err(1, "SIOCGETPFSYNCNV"); 3274bf98559SKajetan Staszkiewicz 3284bf98559SKajetan Staszkiewicz nvlist_free_number(nvl, "version"); 3294bf98559SKajetan Staszkiewicz nvlist_add_number(nvl, "version", version); 3304bf98559SKajetan Staszkiewicz 3317fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCSETPFSYNCNV, &nvl) == -1) 3324bf98559SKajetan Staszkiewicz err(1, "SIOCSETPFSYNCNV"); 3334bf98559SKajetan Staszkiewicz 3344bf98559SKajetan Staszkiewicz nvlist_destroy(nvl); 3354bf98559SKajetan Staszkiewicz } 3364bf98559SKajetan Staszkiewicz 3374bf98559SKajetan Staszkiewicz static void 3386e3a9d7fSAlexander V. Chernikov pfsync_status(if_ctx *ctx) 339a9771948SGleb Smirnoff { 340813c5b75SLuiz Amaral nvlist_t *nvl; 341813c5b75SLuiz Amaral char syncdev[IFNAMSIZ]; 342813c5b75SLuiz Amaral char syncpeer_str[NI_MAXHOST]; 343813c5b75SLuiz Amaral struct sockaddr_storage syncpeer; 34444cd85d4SAlexander V. Chernikov int maxupdates = 0; 34544cd85d4SAlexander V. Chernikov int flags = 0; 3464bf98559SKajetan Staszkiewicz int version; 347813c5b75SLuiz Amaral int error; 348a9771948SGleb Smirnoff 349813c5b75SLuiz Amaral nvl = nvlist_create(0); 350a9771948SGleb Smirnoff 3517fa282e6SAlexander V. Chernikov if (pfsync_do_ioctl(ctx, SIOCGETPFSYNCNV, &nvl) == -1) { 352813c5b75SLuiz Amaral nvlist_destroy(nvl); 353a9771948SGleb Smirnoff return; 354813c5b75SLuiz Amaral } 355a9771948SGleb Smirnoff 356813c5b75SLuiz Amaral memset((char *)&syncdev, 0, IFNAMSIZ); 357813c5b75SLuiz Amaral if (nvlist_exists_string(nvl, "syncdev")) 358813c5b75SLuiz Amaral strlcpy(syncdev, nvlist_get_string(nvl, "syncdev"), 359813c5b75SLuiz Amaral IFNAMSIZ); 360813c5b75SLuiz Amaral if (nvlist_exists_number(nvl, "maxupdates")) 361813c5b75SLuiz Amaral maxupdates = nvlist_get_number(nvl, "maxupdates"); 3624bf98559SKajetan Staszkiewicz if (nvlist_exists_number(nvl, "version")) 3634bf98559SKajetan Staszkiewicz version = nvlist_get_number(nvl, "version"); 364813c5b75SLuiz Amaral if (nvlist_exists_number(nvl, "flags")) 365813c5b75SLuiz Amaral flags = nvlist_get_number(nvl, "flags"); 366813c5b75SLuiz Amaral if (nvlist_exists_nvlist(nvl, "syncpeer")) { 367813c5b75SLuiz Amaral pfsync_syncpeer_nvlist_to_sockaddr(nvlist_get_nvlist(nvl, 368813c5b75SLuiz Amaral "syncpeer"), 369813c5b75SLuiz Amaral &syncpeer); 370813c5b75SLuiz Amaral } 371813c5b75SLuiz Amaral 372813c5b75SLuiz Amaral nvlist_destroy(nvl); 373813c5b75SLuiz Amaral 374813c5b75SLuiz Amaral if (syncdev[0] != '\0' || syncpeer.ss_family != AF_UNSPEC) 37511c4984fSGleb Smirnoff printf("\t"); 37611c4984fSGleb Smirnoff 377813c5b75SLuiz Amaral if (syncdev[0] != '\0') 378813c5b75SLuiz Amaral printf("syncdev: %s ", syncdev); 37911c4984fSGleb Smirnoff 380813c5b75SLuiz Amaral if (syncpeer.ss_family == AF_INET && 381813c5b75SLuiz Amaral ((struct sockaddr_in *)&syncpeer)->sin_addr.s_addr != 382813c5b75SLuiz Amaral htonl(INADDR_PFSYNC_GROUP)) { 383813c5b75SLuiz Amaral 384813c5b75SLuiz Amaral struct sockaddr *syncpeer_sa = 385813c5b75SLuiz Amaral (struct sockaddr *)&syncpeer; 386813c5b75SLuiz Amaral if ((error = getnameinfo(syncpeer_sa, syncpeer_sa->sa_len, 387813c5b75SLuiz Amaral syncpeer_str, sizeof(syncpeer_str), NULL, 0, 388813c5b75SLuiz Amaral NI_NUMERICHOST)) != 0) 389813c5b75SLuiz Amaral errx(1, "getnameinfo: %s", gai_strerror(error)); 390813c5b75SLuiz Amaral printf("syncpeer: %s ", syncpeer_str); 39174e9ff65SGleb Smirnoff } 392813c5b75SLuiz Amaral 393813c5b75SLuiz Amaral printf("maxupd: %d ", maxupdates); 3944bf98559SKajetan Staszkiewicz printf("defer: %s ", (flags & PFSYNCF_DEFER) ? "on" : "off"); 3954bf98559SKajetan Staszkiewicz printf("version: %d\n", version); 396813c5b75SLuiz Amaral printf("\tsyncok: %d\n", (flags & PFSYNCF_OK) ? 1 : 0); 397a9771948SGleb Smirnoff } 398a9771948SGleb Smirnoff 399a9771948SGleb Smirnoff static struct cmd pfsync_cmds[] = { 40010a51bf5SMax Laier DEF_CMD_ARG("syncdev", setpfsync_syncdev), 40110a51bf5SMax Laier DEF_CMD("-syncdev", 1, unsetpfsync_syncdev), 40210a51bf5SMax Laier DEF_CMD_ARG("syncif", setpfsync_syncdev), 40310a51bf5SMax Laier DEF_CMD("-syncif", 1, unsetpfsync_syncdev), 40410a51bf5SMax Laier DEF_CMD_ARG("syncpeer", setpfsync_syncpeer), 40510a51bf5SMax Laier DEF_CMD("-syncpeer", 1, unsetpfsync_syncpeer), 40674e9ff65SGleb Smirnoff DEF_CMD_ARG("maxupd", setpfsync_maxupd), 40774e9ff65SGleb Smirnoff DEF_CMD("defer", 1, setpfsync_defer), 40874e9ff65SGleb Smirnoff DEF_CMD("-defer", 0, setpfsync_defer), 4094bf98559SKajetan Staszkiewicz DEF_CMD_ARG("version", setpfsync_version), 410a9771948SGleb Smirnoff }; 411a9771948SGleb Smirnoff static struct afswtch af_pfsync = { 412a9771948SGleb Smirnoff .af_name = "af_pfsync", 413a9771948SGleb Smirnoff .af_af = AF_UNSPEC, 414ef3abbe8SGleb Smirnoff .af_other_status = pfsync_status, 415a9771948SGleb Smirnoff }; 416a9771948SGleb Smirnoff 417a9771948SGleb Smirnoff static __constructor void 418a9771948SGleb Smirnoff pfsync_ctor(void) 419a9771948SGleb Smirnoff { 42044cd85d4SAlexander V. Chernikov for (size_t i = 0; i < nitems(pfsync_cmds); i++) 421a9771948SGleb Smirnoff cmd_register(&pfsync_cmds[i]); 422a9771948SGleb Smirnoff af_register(&af_pfsync); 423a9771948SGleb Smirnoff } 424