1be4f3cd0SPaolo Pisati /*- 2*fe267a55SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*fe267a55SPedro F. Giffuni * 4be4f3cd0SPaolo Pisati * Copyright (c) 2005 Paolo Pisati <piso@FreeBSD.org> 5be4f3cd0SPaolo Pisati * All rights reserved. 6be4f3cd0SPaolo Pisati * 7be4f3cd0SPaolo Pisati * Redistribution and use in source and binary forms, with or without 8be4f3cd0SPaolo Pisati * modification, are permitted provided that the following conditions 9be4f3cd0SPaolo Pisati * are met: 10be4f3cd0SPaolo Pisati * 1. Redistributions of source code must retain the above copyright 11be4f3cd0SPaolo Pisati * notice, this list of conditions and the following disclaimer. 12be4f3cd0SPaolo Pisati * 2. Redistributions in binary form must reproduce the above copyright 13be4f3cd0SPaolo Pisati * notice, this list of conditions and the following disclaimer in the 14be4f3cd0SPaolo Pisati * documentation and/or other materials provided with the distribution. 15be4f3cd0SPaolo Pisati * 16be4f3cd0SPaolo Pisati * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17be4f3cd0SPaolo Pisati * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18be4f3cd0SPaolo Pisati * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19be4f3cd0SPaolo Pisati * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20be4f3cd0SPaolo Pisati * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21be4f3cd0SPaolo Pisati * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22be4f3cd0SPaolo Pisati * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23be4f3cd0SPaolo Pisati * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24be4f3cd0SPaolo Pisati * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25be4f3cd0SPaolo Pisati * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26be4f3cd0SPaolo Pisati * SUCH DAMAGE. 27be4f3cd0SPaolo Pisati * 28be4f3cd0SPaolo Pisati */ 297c00cc76SPaolo Pisati #include <sys/cdefs.h> 30be4f3cd0SPaolo Pisati __FBSDID("$FreeBSD$"); 31be4f3cd0SPaolo Pisati 32be4f3cd0SPaolo Pisati #ifdef _KERNEL 33be4f3cd0SPaolo Pisati #include <sys/libkern.h> 34be4f3cd0SPaolo Pisati #include <sys/param.h> 35be4f3cd0SPaolo Pisati #include <sys/lock.h> 36be4f3cd0SPaolo Pisati #include <sys/rwlock.h> 37be4f3cd0SPaolo Pisati #else 38be4f3cd0SPaolo Pisati #include <stdio.h> 39be4f3cd0SPaolo Pisati #include <string.h> 40be4f3cd0SPaolo Pisati #include <sys/types.h> 41be4f3cd0SPaolo Pisati #include <errno.h> 42be4f3cd0SPaolo Pisati #endif 43be4f3cd0SPaolo Pisati 44be4f3cd0SPaolo Pisati #include <netinet/in_systm.h> 45be4f3cd0SPaolo Pisati #include <netinet/in.h> 46be4f3cd0SPaolo Pisati #include <netinet/ip.h> 47be4f3cd0SPaolo Pisati 48be4f3cd0SPaolo Pisati #ifdef _KERNEL 49be4f3cd0SPaolo Pisati #include <netinet/libalias/alias_local.h> 50be4f3cd0SPaolo Pisati #include <netinet/libalias/alias_mod.h> 51be4f3cd0SPaolo Pisati #else 52be4f3cd0SPaolo Pisati #include "alias_local.h" 53be4f3cd0SPaolo Pisati #include "alias_mod.h" 54be4f3cd0SPaolo Pisati #endif 55be4f3cd0SPaolo Pisati 56be4f3cd0SPaolo Pisati /* Protocol and userland module handlers chains. */ 57535e0a09SGleb Smirnoff static TAILQ_HEAD(handler_chain, proto_handler) handler_chain = 58535e0a09SGleb Smirnoff TAILQ_HEAD_INITIALIZER(handler_chain); 59be4f3cd0SPaolo Pisati 60be4f3cd0SPaolo Pisati static int 61535e0a09SGleb Smirnoff attach_handler(struct proto_handler *p) 62be4f3cd0SPaolo Pisati { 6343197d29SPaolo Pisati struct proto_handler *b; 64be4f3cd0SPaolo Pisati 65535e0a09SGleb Smirnoff TAILQ_FOREACH(b, &handler_chain, link) { 66be4f3cd0SPaolo Pisati if ((b->pri == p->pri) && 67be4f3cd0SPaolo Pisati (b->dir == p->dir) && 68be4f3cd0SPaolo Pisati (b->proto == p->proto)) 69535e0a09SGleb Smirnoff return (EEXIST); 70be4f3cd0SPaolo Pisati if (b->pri > p->pri) { 71535e0a09SGleb Smirnoff TAILQ_INSERT_BEFORE(b, p, link); 72be4f3cd0SPaolo Pisati return (0); 73be4f3cd0SPaolo Pisati } 74be4f3cd0SPaolo Pisati } 75535e0a09SGleb Smirnoff 76535e0a09SGleb Smirnoff TAILQ_INSERT_TAIL(&handler_chain, p, link); 77535e0a09SGleb Smirnoff 78be4f3cd0SPaolo Pisati return (0); 79be4f3cd0SPaolo Pisati } 80be4f3cd0SPaolo Pisati 81be4f3cd0SPaolo Pisati int 82535e0a09SGleb Smirnoff LibAliasAttachHandlers(struct proto_handler *p) 83be4f3cd0SPaolo Pisati { 8443197d29SPaolo Pisati int error; 85be4f3cd0SPaolo Pisati 86535e0a09SGleb Smirnoff while (p->dir != NODIR) { 87535e0a09SGleb Smirnoff error = attach_handler(p); 88535e0a09SGleb Smirnoff if (error) 89be4f3cd0SPaolo Pisati return (error); 90535e0a09SGleb Smirnoff p++; 91535e0a09SGleb Smirnoff } 92535e0a09SGleb Smirnoff 93535e0a09SGleb Smirnoff return (0); 94535e0a09SGleb Smirnoff } 95535e0a09SGleb Smirnoff 96535e0a09SGleb Smirnoff /* XXXGL: should be void, but no good reason to break ABI */ 97535e0a09SGleb Smirnoff int 98535e0a09SGleb Smirnoff LibAliasDetachHandlers(struct proto_handler *p) 99535e0a09SGleb Smirnoff { 100535e0a09SGleb Smirnoff 101535e0a09SGleb Smirnoff while (p->dir != NODIR) { 102535e0a09SGleb Smirnoff TAILQ_REMOVE(&handler_chain, p, link); 103535e0a09SGleb Smirnoff p++; 104535e0a09SGleb Smirnoff } 105535e0a09SGleb Smirnoff 106535e0a09SGleb Smirnoff return (0); 107be4f3cd0SPaolo Pisati } 108be4f3cd0SPaolo Pisati 109be4f3cd0SPaolo Pisati int 110535e0a09SGleb Smirnoff find_handler(int8_t dir, int8_t proto, struct libalias *la, struct ip *ip, 111be4f3cd0SPaolo Pisati struct alias_data *ad) 112be4f3cd0SPaolo Pisati { 113be4f3cd0SPaolo Pisati struct proto_handler *p; 114be4f3cd0SPaolo Pisati 115535e0a09SGleb Smirnoff TAILQ_FOREACH(p, &handler_chain, link) 116535e0a09SGleb Smirnoff if ((p->dir & dir) && (p->proto & proto) && 117535e0a09SGleb Smirnoff p->fingerprint(la, ad) == 0) 118535e0a09SGleb Smirnoff return (p->protohandler(la, ip, ad)); 119535e0a09SGleb Smirnoff 120535e0a09SGleb Smirnoff return (ENOENT); 121be4f3cd0SPaolo Pisati } 122be4f3cd0SPaolo Pisati 123be4f3cd0SPaolo Pisati struct proto_handler * 124be4f3cd0SPaolo Pisati first_handler(void) 125be4f3cd0SPaolo Pisati { 126be4f3cd0SPaolo Pisati 127535e0a09SGleb Smirnoff return (TAILQ_FIRST(&handler_chain)); 128be4f3cd0SPaolo Pisati } 129be4f3cd0SPaolo Pisati 1301019f603SGleb Smirnoff #ifndef _KERNEL 131be4f3cd0SPaolo Pisati /* Dll manipulation code - this code is not thread safe... */ 132535e0a09SGleb Smirnoff SLIST_HEAD(dll_chain, dll) dll_chain = SLIST_HEAD_INITIALIZER(dll_chain); 133be4f3cd0SPaolo Pisati int 134be4f3cd0SPaolo Pisati attach_dll(struct dll *p) 135be4f3cd0SPaolo Pisati { 136be4f3cd0SPaolo Pisati struct dll *b; 137be4f3cd0SPaolo Pisati 138be4f3cd0SPaolo Pisati SLIST_FOREACH(b, &dll_chain, next) { 139be4f3cd0SPaolo Pisati if (!strncmp(b->name, p->name, DLL_LEN)) 140be4f3cd0SPaolo Pisati return (EEXIST); /* Dll name conflict. */ 141be4f3cd0SPaolo Pisati } 142be4f3cd0SPaolo Pisati SLIST_INSERT_HEAD(&dll_chain, p, next); 143be4f3cd0SPaolo Pisati return (0); 144be4f3cd0SPaolo Pisati } 145be4f3cd0SPaolo Pisati 146be4f3cd0SPaolo Pisati void * 147be4f3cd0SPaolo Pisati detach_dll(char *p) 148be4f3cd0SPaolo Pisati { 14943197d29SPaolo Pisati struct dll *b, *b_tmp; 15043197d29SPaolo Pisati void *error; 151be4f3cd0SPaolo Pisati 15243197d29SPaolo Pisati b = NULL; 15343197d29SPaolo Pisati error = NULL; 154be4f3cd0SPaolo Pisati SLIST_FOREACH_SAFE(b, &dll_chain, next, b_tmp) 155be4f3cd0SPaolo Pisati if (!strncmp(b->name, p, DLL_LEN)) { 156be4f3cd0SPaolo Pisati SLIST_REMOVE(&dll_chain, b, dll, next); 157be4f3cd0SPaolo Pisati error = b; 158be4f3cd0SPaolo Pisati break; 159be4f3cd0SPaolo Pisati } 160be4f3cd0SPaolo Pisati return (error); 161be4f3cd0SPaolo Pisati } 162be4f3cd0SPaolo Pisati 163be4f3cd0SPaolo Pisati struct dll * 164be4f3cd0SPaolo Pisati walk_dll_chain(void) 165be4f3cd0SPaolo Pisati { 166be4f3cd0SPaolo Pisati struct dll *t; 167be4f3cd0SPaolo Pisati 168be4f3cd0SPaolo Pisati t = SLIST_FIRST(&dll_chain); 169be4f3cd0SPaolo Pisati if (t == NULL) 170be4f3cd0SPaolo Pisati return (NULL); 171be4f3cd0SPaolo Pisati SLIST_REMOVE_HEAD(&dll_chain, next); 172be4f3cd0SPaolo Pisati return (t); 173be4f3cd0SPaolo Pisati } 1741019f603SGleb Smirnoff #endif /* !_KERNEL */ 175