1 /*- 2 * Copyright (c) 2012 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Mindaugas Rasiukevicius. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * npfctl(8) extension loading interface. 32 */ 33 34 #include <sys/cdefs.h> 35 __RCSID("$NetBSD: npf_extmod.c,v 1.5 2018/09/29 14:41:36 rmind Exp $"); 36 37 #include <stdlib.h> 38 #include <inttypes.h> 39 #include <string.h> 40 #include <err.h> 41 #include <dlfcn.h> 42 43 #include "npfctl.h" 44 45 struct npf_extmod { 46 char * name; 47 npfext_initfunc_t init; 48 npfext_consfunc_t cons; 49 npfext_paramfunc_t param; 50 struct npf_extmod * next; 51 }; 52 53 static npf_extmod_t * npf_extmod_list; 54 55 static void * 56 npf_extmod_sym(void *handle, const char *name, const char *func) 57 { 58 char buf[64]; 59 void *sym; 60 61 snprintf(buf, sizeof(buf), "npfext_%s_%s", name, func); 62 sym = dlsym(handle, buf); 63 if (sym == NULL) { 64 errx(EXIT_FAILURE, "dlsym: %s", dlerror()); 65 } 66 return sym; 67 } 68 69 static npf_extmod_t * 70 npf_extmod_load(const char *name) 71 { 72 npf_extmod_t *ext; 73 void *handle; 74 char extlib[PATH_MAX]; 75 76 snprintf(extlib, sizeof(extlib), "/lib/npf/ext_%s.so", name); 77 handle = dlopen(extlib, RTLD_LAZY | RTLD_LOCAL); 78 if (handle == NULL) { 79 errx(EXIT_FAILURE, "dlopen: %s", dlerror()); 80 } 81 82 ext = ecalloc(1, sizeof(npf_extmod_t)); 83 ext->name = estrdup(name); 84 ext->init = npf_extmod_sym(handle, name, "init"); 85 ext->cons = npf_extmod_sym(handle, name, "construct"); 86 ext->param = npf_extmod_sym(handle, name, "param"); 87 88 /* Initialise the module. */ 89 if (ext->init() != 0) { 90 free(ext); 91 return NULL; 92 } 93 94 ext->next = npf_extmod_list; 95 npf_extmod_list = ext; 96 return ext; 97 } 98 99 npf_extmod_t * 100 npf_extmod_get(const char *name, nl_ext_t **extcall) 101 { 102 npf_extmod_t *extmod = npf_extmod_list; 103 104 while (extmod) { 105 if ((strcmp(extmod->name, name) == 0) && 106 (*extcall = extmod->cons(name)) != NULL) { 107 return extmod; 108 } 109 extmod = extmod->next; 110 } 111 112 extmod = npf_extmod_load(name); 113 if (extmod && (*extcall = extmod->cons(name)) != NULL) { 114 return extmod; 115 } 116 117 return NULL; 118 } 119 120 int 121 npf_extmod_param(npf_extmod_t *extmod, nl_ext_t *ext, 122 const char *param, const char *val) 123 { 124 return extmod->param(ext, param, val); 125 } 126