1813c5b75SLuiz Amaral /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3813c5b75SLuiz Amaral * 4813c5b75SLuiz Amaral * Copyright (c) 2022 InnoGames GmbH 5813c5b75SLuiz Amaral * 6813c5b75SLuiz Amaral * Redistribution and use in source and binary forms, with or without 7813c5b75SLuiz Amaral * modification, are permitted provided that the following conditions 8813c5b75SLuiz Amaral * are met: 9813c5b75SLuiz Amaral * 1. Redistributions of source code must retain the above copyright 10813c5b75SLuiz Amaral * notice, this list of conditions and the following disclaimer. 11813c5b75SLuiz Amaral * 2. Redistributions in binary form must reproduce the above copyright 12813c5b75SLuiz Amaral * notice, this list of conditions and the following disclaimer in the 13813c5b75SLuiz Amaral * documentation and/or other materials provided with the distribution. 14813c5b75SLuiz Amaral * 15813c5b75SLuiz Amaral * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16813c5b75SLuiz Amaral * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17813c5b75SLuiz Amaral * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18813c5b75SLuiz Amaral * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19813c5b75SLuiz Amaral * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20813c5b75SLuiz Amaral * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21813c5b75SLuiz Amaral * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22813c5b75SLuiz Amaral * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23813c5b75SLuiz Amaral * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24813c5b75SLuiz Amaral * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25813c5b75SLuiz Amaral * SUCH DAMAGE. 26813c5b75SLuiz Amaral * 27813c5b75SLuiz Amaral */ 28813c5b75SLuiz Amaral 29813c5b75SLuiz Amaral #include <sys/cdefs.h> 30813c5b75SLuiz Amaral __FBSDID("$FreeBSD$"); 31813c5b75SLuiz Amaral 32813c5b75SLuiz Amaral #include "opt_inet.h" 33813c5b75SLuiz Amaral #include "opt_inet6.h" 34813c5b75SLuiz Amaral 35813c5b75SLuiz Amaral #include <sys/param.h> 36813c5b75SLuiz Amaral #include <sys/errno.h> 37813c5b75SLuiz Amaral 386fc7fc2dSLuiz Amaral #include <netinet/in.h> 396fc7fc2dSLuiz Amaral 406fc7fc2dSLuiz Amaral #include <netinet6/ip6_var.h> 416fc7fc2dSLuiz Amaral #include <netinet6/scope6_var.h> 426fc7fc2dSLuiz Amaral 43813c5b75SLuiz Amaral #include <netpfil/pf/pfsync_nv.h> 44813c5b75SLuiz Amaral 45813c5b75SLuiz Amaral int 46813c5b75SLuiz Amaral pfsync_syncpeer_nvlist_to_sockaddr(const nvlist_t *nvl, 47813c5b75SLuiz Amaral struct sockaddr_storage *sa) 48813c5b75SLuiz Amaral { 49813c5b75SLuiz Amaral int af; 50813c5b75SLuiz Amaral 51813c5b75SLuiz Amaral if (!nvlist_exists_number(nvl, "af")) 52813c5b75SLuiz Amaral return (EINVAL); 53813c5b75SLuiz Amaral if (!nvlist_exists_binary(nvl, "address")) 54813c5b75SLuiz Amaral return (EINVAL); 55813c5b75SLuiz Amaral 56813c5b75SLuiz Amaral af = nvlist_get_number(nvl, "af"); 57813c5b75SLuiz Amaral 58813c5b75SLuiz Amaral switch (af) { 59813c5b75SLuiz Amaral #ifdef INET 60813c5b75SLuiz Amaral case AF_INET: { 61813c5b75SLuiz Amaral struct sockaddr_in *in = (struct sockaddr_in *)sa; 62813c5b75SLuiz Amaral size_t len; 63813c5b75SLuiz Amaral const void *addr = nvlist_get_binary(nvl, "address", &len); 64813c5b75SLuiz Amaral in->sin_family = af; 65813c5b75SLuiz Amaral if (len != sizeof(*in)) 66813c5b75SLuiz Amaral return (EINVAL); 67813c5b75SLuiz Amaral 68813c5b75SLuiz Amaral memcpy(in, addr, sizeof(*in)); 69813c5b75SLuiz Amaral break; 70813c5b75SLuiz Amaral } 71813c5b75SLuiz Amaral #endif 72813c5b75SLuiz Amaral #ifdef INET6 73813c5b75SLuiz Amaral case AF_INET6: { 74813c5b75SLuiz Amaral struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; 75813c5b75SLuiz Amaral size_t len; 76*77c9e608SKristof Provost int error; 77813c5b75SLuiz Amaral const void *addr = nvlist_get_binary(nvl, "address", &len); 78813c5b75SLuiz Amaral in6->sin6_family = af; 79813c5b75SLuiz Amaral if (len != sizeof(*in6)) 80813c5b75SLuiz Amaral return (EINVAL); 81813c5b75SLuiz Amaral 82813c5b75SLuiz Amaral memcpy(in6, addr, sizeof(*in6)); 836fc7fc2dSLuiz Amaral 846fc7fc2dSLuiz Amaral error = sa6_embedscope(in6, V_ip6_use_defzone); 856fc7fc2dSLuiz Amaral if (error) 866fc7fc2dSLuiz Amaral return (error); 876fc7fc2dSLuiz Amaral 88813c5b75SLuiz Amaral break; 89813c5b75SLuiz Amaral } 90813c5b75SLuiz Amaral #endif 91813c5b75SLuiz Amaral default: 92813c5b75SLuiz Amaral return (EINVAL); 93813c5b75SLuiz Amaral } 94813c5b75SLuiz Amaral 95813c5b75SLuiz Amaral return (0); 96813c5b75SLuiz Amaral } 97813c5b75SLuiz Amaral 98813c5b75SLuiz Amaral nvlist_t * 99813c5b75SLuiz Amaral pfsync_sockaddr_to_syncpeer_nvlist(struct sockaddr_storage *sa) 100813c5b75SLuiz Amaral { 101813c5b75SLuiz Amaral nvlist_t *nvl; 102813c5b75SLuiz Amaral 103813c5b75SLuiz Amaral nvl = nvlist_create(0); 104813c5b75SLuiz Amaral if (nvl == NULL) { 105813c5b75SLuiz Amaral return (nvl); 106813c5b75SLuiz Amaral } 107813c5b75SLuiz Amaral 108813c5b75SLuiz Amaral switch (sa->ss_family) { 109813c5b75SLuiz Amaral #ifdef INET 110813c5b75SLuiz Amaral case AF_INET: { 111813c5b75SLuiz Amaral struct sockaddr_in *in = (struct sockaddr_in *)sa; 112813c5b75SLuiz Amaral nvlist_add_number(nvl, "af", in->sin_family); 113813c5b75SLuiz Amaral nvlist_add_binary(nvl, "address", in, sizeof(*in)); 114813c5b75SLuiz Amaral break; 115813c5b75SLuiz Amaral } 116813c5b75SLuiz Amaral #endif 117813c5b75SLuiz Amaral #ifdef INET6 118813c5b75SLuiz Amaral case AF_INET6: { 119813c5b75SLuiz Amaral struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)sa; 1206fc7fc2dSLuiz Amaral sa6_recoverscope(in6); 121813c5b75SLuiz Amaral nvlist_add_number(nvl, "af", in6->sin6_family); 122813c5b75SLuiz Amaral nvlist_add_binary(nvl, "address", in6, sizeof(*in6)); 123813c5b75SLuiz Amaral break; 124813c5b75SLuiz Amaral } 125813c5b75SLuiz Amaral #endif 126813c5b75SLuiz Amaral default: 127813c5b75SLuiz Amaral return NULL; 128813c5b75SLuiz Amaral } 129813c5b75SLuiz Amaral 130813c5b75SLuiz Amaral return (nvl); 131813c5b75SLuiz Amaral } 132813c5b75SLuiz Amaral 133813c5b75SLuiz Amaral int 134813c5b75SLuiz Amaral pfsync_nvstatus_to_kstatus(const nvlist_t *nvl, struct pfsync_kstatus *status) 135813c5b75SLuiz Amaral { 136813c5b75SLuiz Amaral struct sockaddr_storage addr; 137813c5b75SLuiz Amaral int error; 138813c5b75SLuiz Amaral 139813c5b75SLuiz Amaral if (!nvlist_exists_number(nvl, "maxupdates")) 140813c5b75SLuiz Amaral return (EINVAL); 141813c5b75SLuiz Amaral if (!nvlist_exists_number(nvl, "flags")) 142813c5b75SLuiz Amaral return (EINVAL); 143813c5b75SLuiz Amaral 144813c5b75SLuiz Amaral status->maxupdates = nvlist_get_number(nvl, "maxupdates"); 1454bf98559SKajetan Staszkiewicz status->version = nvlist_get_number(nvl, "version"); 146813c5b75SLuiz Amaral status->flags = nvlist_get_number(nvl, "flags"); 147813c5b75SLuiz Amaral 148813c5b75SLuiz Amaral if (nvlist_exists_string(nvl, "syncdev")) 149813c5b75SLuiz Amaral strlcpy(status->syncdev, nvlist_get_string(nvl, "syncdev"), 150813c5b75SLuiz Amaral IFNAMSIZ); 151813c5b75SLuiz Amaral 152813c5b75SLuiz Amaral if (nvlist_exists_nvlist(nvl, "syncpeer")) { 153813c5b75SLuiz Amaral memset(&addr, 0, sizeof(addr)); 154813c5b75SLuiz Amaral if ((error = pfsync_syncpeer_nvlist_to_sockaddr(nvlist_get_nvlist(nvl, "syncpeer"), &addr)) != 0) 155813c5b75SLuiz Amaral return (error); 156813c5b75SLuiz Amaral 157813c5b75SLuiz Amaral status->syncpeer = addr; 158813c5b75SLuiz Amaral } else { 159813c5b75SLuiz Amaral memset(&status->syncpeer, 0, sizeof(status->syncpeer)); 160813c5b75SLuiz Amaral } 161813c5b75SLuiz Amaral 162813c5b75SLuiz Amaral return (0); 163813c5b75SLuiz Amaral } 164