Changeset View
Changeset View
Standalone View
Standalone View
lib/libpfctl/libpfctl.c
Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
#include <assert.h> | #include <assert.h> | ||||
#include <err.h> | #include <err.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "libpfctl.h" | #include "libpfctl.h" | ||||
const char* PFCTL_SYNCOOKIES_MODE_NAMES[] = { | |||||
"never", | |||||
"always", | |||||
"adaptive" | |||||
}; | |||||
static int _pfctl_clear_states(int , const struct pfctl_kill *, | static int _pfctl_clear_states(int , const struct pfctl_kill *, | ||||
unsigned int *, uint64_t); | unsigned int *, uint64_t); | ||||
static void | static void | ||||
pf_nvuint_8_array(const nvlist_t *nvl, const char *name, size_t maxelems, | pf_nvuint_8_array(const nvlist_t *nvl, const char *name, size_t maxelems, | ||||
u_int8_t *numbers, size_t *nelems) | u_int8_t *numbers, size_t *nelems) | ||||
{ | { | ||||
const uint64_t *tmp; | const uint64_t *tmp; | ||||
▲ Show 20 Lines • Show All 872 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
int | int | ||||
pfctl_kill_states(int dev, const struct pfctl_kill *kill, unsigned int *killed) | pfctl_kill_states(int dev, const struct pfctl_kill *kill, unsigned int *killed) | ||||
{ | { | ||||
return (_pfctl_clear_states(dev, kill, killed, DIOCKILLSTATESNV)); | return (_pfctl_clear_states(dev, kill, killed, DIOCKILLSTATESNV)); | ||||
} | } | ||||
static int | |||||
pfctl_get_limit(int dev, const int index, u_int *limit) | |||||
{ | |||||
struct pfioc_limit pl; | |||||
bzero(&pl, sizeof(pl)); | |||||
pl.index = index; | |||||
if (ioctl(dev, DIOCGETLIMIT, &pl) == -1) | |||||
return (errno); | |||||
*limit = pl.limit; | |||||
return (0); | |||||
} | |||||
int | int | ||||
pfctl_set_syncookies(int dev, const struct pfctl_syncookies *s) | pfctl_set_syncookies(int dev, const struct pfctl_syncookies *s) | ||||
{ | { | ||||
struct pfioc_nv nv; | struct pfioc_nv nv; | ||||
nvlist_t *nvl; | nvlist_t *nvl; | ||||
int ret; | int ret; | ||||
u_int state_limit; | |||||
ret = pfctl_get_limit(dev, PF_LIMIT_STATES, &state_limit); | |||||
if (ret != 0) | |||||
return (ret); | |||||
nvl = nvlist_create(0); | nvl = nvlist_create(0); | ||||
nvlist_add_bool(nvl, "enabled", s->mode != PFCTL_SYNCOOKIES_NEVER); | nvlist_add_bool(nvl, "enabled", s->mode != PFCTL_SYNCOOKIES_NEVER); | ||||
nvlist_add_bool(nvl, "adaptive", false); /* XXX TODO */ | nvlist_add_bool(nvl, "adaptive", s->mode == PFCTL_SYNCOOKIES_ADAPTIVE); | ||||
nvlist_add_number(nvl, "highwater", state_limit * s->highwater / 100); | |||||
nvlist_add_number(nvl, "lowwater", state_limit * s->lowwater / 100); | |||||
nv.data = nvlist_pack(nvl, &nv.len); | nv.data = nvlist_pack(nvl, &nv.len); | ||||
nv.size = nv.len; | nv.size = nv.len; | ||||
nvlist_destroy(nvl); | nvlist_destroy(nvl); | ||||
nvl = NULL; | nvl = NULL; | ||||
ret = ioctl(dev, DIOCSETSYNCOOKIES, &nv); | ret = ioctl(dev, DIOCSETSYNCOOKIES, &nv); | ||||
free(nv.data); | free(nv.data); | ||||
return (ret); | return (ret); | ||||
} | } | ||||
int | int | ||||
pfctl_get_syncookies(int dev, struct pfctl_syncookies *s) | pfctl_get_syncookies(int dev, struct pfctl_syncookies *s) | ||||
{ | { | ||||
struct pfioc_nv nv; | struct pfioc_nv nv; | ||||
nvlist_t *nvl; | nvlist_t *nvl; | ||||
int ret; | |||||
u_int state_limit; | |||||
bool enabled, adaptive; | bool enabled, adaptive; | ||||
ret = pfctl_get_limit(dev, PF_LIMIT_STATES, &state_limit); | |||||
if (ret != 0) | |||||
return (ret); | |||||
bzero(s, sizeof(*s)); | bzero(s, sizeof(*s)); | ||||
nv.data = malloc(128); | nv.data = malloc(256); | ||||
nv.len = nv.size = 128; | nv.len = nv.size = 256; | ||||
if (ioctl(dev, DIOCGETSYNCOOKIES, &nv)) { | if (ioctl(dev, DIOCGETSYNCOOKIES, &nv)) { | ||||
free(nv.data); | free(nv.data); | ||||
return (errno); | return (errno); | ||||
} | } | ||||
nvl = nvlist_unpack(nv.data, nv.len, 0); | nvl = nvlist_unpack(nv.data, nv.len, 0); | ||||
free(nv.data); | free(nv.data); | ||||
if (nvl == NULL) { | if (nvl == NULL) { | ||||
return (EIO); | return (EIO); | ||||
} | } | ||||
enabled = nvlist_get_bool(nvl, "enabled"); | enabled = nvlist_get_bool(nvl, "enabled"); | ||||
adaptive = nvlist_get_bool(nvl, "adaptive"); | adaptive = nvlist_get_bool(nvl, "adaptive"); | ||||
s->mode = enabled ? PFCTL_SYNCOOKIES_ALWAYS : PFCTL_SYNCOOKIES_NEVER; | if (enabled) { | ||||
if (adaptive) | |||||
s->mode = PFCTL_SYNCOOKIES_ADAPTIVE; | |||||
else | |||||
s->mode = PFCTL_SYNCOOKIES_ALWAYS; | |||||
} else { | |||||
s->mode = PFCTL_SYNCOOKIES_NEVER; | |||||
} | |||||
s->highwater = nvlist_get_number(nvl, "highwater") * 100 / state_limit; | |||||
s->lowwater = nvlist_get_number(nvl, "lowwater") * 100 / state_limit; | |||||
nvlist_destroy(nvl); | nvlist_destroy(nvl); | ||||
return (0); | return (0); | ||||
} | } |