1 /* $NetBSD: npf.c,v 1.1 2010/08/22 18:56:22 rmind Exp $ */ 2 3 /*- 4 * Copyright (c) 2009-2010 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This material is based upon work partially supported by The 8 * NetBSD Foundation under a contract with 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 * NPF main: dynamic load/initialisation and unload routines. 34 */ 35 36 #include <sys/cdefs.h> 37 __KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.1 2010/08/22 18:56:22 rmind Exp $"); 38 39 #include <sys/param.h> 40 #include <sys/types.h> 41 42 #include <sys/conf.h> 43 #include <sys/kauth.h> 44 #include <sys/lwp.h> 45 #include <sys/module.h> 46 #include <sys/socketvar.h> 47 #include <sys/uio.h> 48 49 #include "npf_impl.h" 50 51 /* 52 * Module and device structures. 53 */ 54 MODULE(MODULE_CLASS_MISC, npf, NULL); 55 56 void npfattach(int); 57 58 static int npf_dev_open(dev_t, int, int, lwp_t *); 59 static int npf_dev_close(dev_t, int, int, lwp_t *); 60 static int npf_dev_ioctl(dev_t, u_long, void *, int, lwp_t *); 61 static int npf_dev_poll(dev_t, int, lwp_t *); 62 static int npf_dev_read(dev_t, struct uio *, int); 63 64 const struct cdevsw npf_cdevsw = { 65 npf_dev_open, npf_dev_close, npf_dev_read, nowrite, npf_dev_ioctl, 66 nostop, notty, npf_dev_poll, nommap, nokqfilter, D_OTHER | D_MPSAFE 67 }; 68 69 static int 70 npf_init(void) 71 { 72 #ifdef _MODULE 73 devmajor_t bmajor = NODEVMAJOR, cmajor = NODEVMAJOR; 74 #endif 75 int error; 76 77 /* 78 * Initialise ruleset, tables and session structures. 79 */ 80 81 error = npf_ruleset_sysinit(); 82 if (error) 83 return error; 84 85 error = npf_tableset_sysinit(); 86 if (error) { 87 npf_ruleset_sysfini(); 88 return error; 89 } 90 91 error = npf_session_sysinit(); 92 if (error) { 93 npf_tableset_sysfini(); 94 npf_ruleset_sysfini(); 95 return error; 96 } 97 npf_nat_sysinit(); 98 npf_alg_sysinit(); 99 100 #ifdef _MODULE 101 /* Attach /dev/npf device. */ 102 error = devsw_attach("npf", NULL, &bmajor, &npf_cdevsw, &cmajor); 103 if (error) { 104 npf_nat_sysfini(); 105 npf_session_sysfini(); 106 npf_tableset_sysfini(); 107 npf_ruleset_sysfini(); 108 } 109 #endif 110 return error; 111 } 112 113 static int 114 npf_fini(void) 115 { 116 117 #ifdef _MODULE 118 /* At first, detach device and remove pfil hooks. */ 119 devsw_detach(NULL, &npf_cdevsw); 120 #endif 121 npf_nat_sysfini(); 122 npf_alg_sysfini(); 123 npf_session_sysfini(); 124 npf_tableset_sysfini(); 125 npf_ruleset_sysfini(); 126 127 return 0; 128 } 129 130 /* 131 * Module interface. 132 */ 133 static int 134 npf_modcmd(modcmd_t cmd, void *arg) 135 { 136 137 switch (cmd) { 138 case MODULE_CMD_INIT: 139 return npf_init(); 140 case MODULE_CMD_FINI: 141 return npf_fini(); 142 default: 143 return ENOTTY; 144 } 145 return 0; 146 } 147 148 void 149 npfattach(int nunits) 150 { 151 152 /* Void. */ 153 } 154 155 static int 156 npf_dev_open(dev_t dev, int flag, int mode, lwp_t *l) 157 { 158 159 /* Available only for super-user. */ 160 if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL)) { 161 return EPERM; 162 } 163 return 0; 164 } 165 166 static int 167 npf_dev_close(dev_t dev, int flag, int mode, lwp_t *l) 168 { 169 170 return 0; 171 } 172 173 static int 174 npf_dev_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l) 175 { 176 int error; 177 178 /* Available only for super-user. */ 179 if (kauth_authorize_generic(l->l_cred, KAUTH_GENERIC_ISSUSER, NULL)) { 180 return EPERM; 181 } 182 183 switch (cmd) { 184 case IOC_NPF_VERSION: 185 *(int *)data = NPF_VERSION; 186 error = 0; 187 break; 188 case IOC_NPF_SWITCH: 189 error = npfctl_switch(data); 190 break; 191 case IOC_NPF_RELOAD: 192 error = npfctl_reload(cmd, data); 193 break; 194 case IOC_NPF_TABLE: 195 error = npfctl_table(data); 196 break; 197 default: 198 error = ENOTTY; 199 break; 200 } 201 return error; 202 } 203 204 static int 205 npf_dev_poll(dev_t dev, int events, lwp_t *l) 206 { 207 208 return ENOTSUP; 209 } 210 211 static int 212 npf_dev_read(dev_t dev, struct uio *uio, int flag) 213 { 214 215 return ENOTSUP; 216 } 217