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