34#define ACCEPT_FILTER_MOD
39#include <sys/domain.h>
40#include <sys/kernel.h>
42#include <sys/malloc.h>
44#include <sys/module.h>
46#include <sys/protosw.h>
47#include <sys/sysctl.h>
48#include <sys/socket.h>
49#include <sys/socketvar.h>
55#define ACCEPT_FILTER_LOCK() mtx_lock(&accept_filter_mtx)
56#define ACCEPT_FILTER_UNLOCK() mtx_unlock(&accept_filter_mtx)
59 SLIST_HEAD_INITIALIZER(accept_filtlsthd);
65SYSCTL_NODE(_net, OID_AUTO, accf, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
68 "Allow unload of accept filters (not recommended)");
76accept_filt_add(
struct accept_filter *filt)
78 struct accept_filter *p;
81 SLIST_FOREACH(p, &accept_filtlsthd, accf_next)
82 if (strcmp(p->accf_name, filt->accf_name) == 0) {
83 if (p->accf_callback != NULL) {
87 p->accf_callback = filt->accf_callback;
95 SLIST_INSERT_HEAD(&accept_filtlsthd, filt, accf_next);
103 struct accept_filter *p;
109 p->accf_callback = NULL;
113struct accept_filter *
116 struct accept_filter *p;
119 SLIST_FOREACH(p, &accept_filtlsthd, accf_next)
120 if (strcmp(p->accf_name,
name) == 0)
130 struct accept_filter *p;
131 struct accept_filter *accfp = (
struct accept_filter *)
data;
136 p =
malloc(
sizeof(*p), M_ACCF, M_WAITOK);
137 bcopy(accfp, p,
sizeof(*p));
138 error = accept_filt_add(p);
169 struct accept_filter_arg *afap;
173 afap =
malloc(
sizeof(*afap), M_TEMP, M_WAITOK | M_ZERO);
175 if (!SOLISTENING(so)) {
179 if (so->sol_accept_filter == NULL) {
183 strcpy(afap->af_name, so->sol_accept_filter->accf_name);
184 if (so->sol_accept_filter_str != NULL)
185 strcpy(afap->af_arg, so->sol_accept_filter_str);
197 struct accept_filter_arg *afap;
198 struct accept_filter *afp;
199 char *accept_filter_str = NULL;
200 void *accept_filter_arg = NULL;
206 if (sopt == NULL || sopt->sopt_val == NULL) {
207 struct socket *sp, *sp1;
211 if (!SOLISTENING(so)) {
215 if (so->sol_accept_filter == NULL) {
219 if (so->sol_accept_filter->accf_destroy != NULL)
220 so->sol_accept_filter->accf_destroy(so);
221 if (so->sol_accept_filter_str != NULL)
222 free(so->sol_accept_filter_str, M_ACCF);
223 so->sol_accept_filter = NULL;
224 so->sol_accept_filter_arg = NULL;
225 so->sol_accept_filter_str = NULL;
226 so->so_options &= ~SO_ACCEPTFILTER;
233 TAILQ_FOREACH_SAFE(sp, &so->sol_incomp, so_list, sp1) {
235 if (sp->so_options & SO_ACCEPTFILTER) {
236 TAILQ_REMOVE(&so->sol_incomp, sp, so_list);
237 TAILQ_INSERT_TAIL(&so->sol_comp, sp, so_list);
238 sp->so_qstate = SQ_COMP;
239 sp->so_options &= ~SO_ACCEPTFILTER;
257 afap =
malloc(
sizeof(*afap), M_TEMP, M_WAITOK);
258 error =
sooptcopyin(sopt, afap,
sizeof *afap,
sizeof *afap);
259 afap->af_name[
sizeof(afap->af_name)-1] =
'\0';
260 afap->af_arg[
sizeof(afap->af_arg)-1] =
'\0';
270 if (afp->accf_create != NULL && afap->af_name[0] !=
'\0') {
271 size_t len = strlen(afap->af_name) + 1;
272 accept_filter_str =
malloc(len, M_ACCF, M_WAITOK);
273 strcpy(accept_filter_str, afap->af_name);
281 if (!SOLISTENING(so) || so->sol_accept_filter != NULL) {
291 if (afp->accf_create != NULL) {
292 accept_filter_arg = afp->accf_create(so, afap->af_arg);
293 if (accept_filter_arg == NULL) {
298 so->sol_accept_filter = afp;
299 so->sol_accept_filter_arg = accept_filter_arg;
300 so->sol_accept_filter_str = accept_filter_str;
301 accept_filter_str = NULL;
302 so->so_options |= SO_ACCEPTFILTER;
305 if (accept_filter_str != NULL)
306 free(accept_filter_str, M_ACCF);
MALLOC_DEFINE(M_BINMISC, KMOD_NAME, "misc binary image activator")
SYSCTL_NODE(_kern, OID_AUTO, binmisc, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "Image activator for miscellaneous binaries")
SYSCTL_INT(ASLR_NODE_OID, OID_AUTO, enable, CTLFLAG_RWTUN, &__elfN(aslr_enabled), 0, ": enable address map randomization")
void *() malloc(size_t size, struct malloc_type *mtp, int flags)
void free(void *addr, struct malloc_type *mtp)
void wakeup(const void *ident)
int accept_filt_generic_mod_event(module_t mod, int event, void *data)
int accept_filt_getopt(struct socket *so, struct sockopt *sopt)
#define ACCEPT_FILTER_LOCK()
int accept_filt_setopt(struct socket *so, struct sockopt *sopt)
#define ACCEPT_FILTER_UNLOCK()
int accept_filt_del(char *name)
struct accept_filter * accept_filt_get(char *name)
MTX_SYSINIT(accept_filter, &accept_filter_mtx, "accept_filter_mtx", MTX_DEF)
static struct mtx accept_filter_mtx
static SLIST_HEAD(accept_filter)
void solisten_wakeup(struct socket *sol)
int sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
int sooptcopyout(struct sockopt *sopt, const void *buf, size_t len)