mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-25 16:13:17 +00:00
Import OPENBSD_4_4_BASE and libevent 1.3e
This commit is contained in:
parent
a13f3058fb
commit
89a3159080
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/pf/dist/; revision=185882 svn path=/vendor/pf/4.4/; revision=185883; tag=vendor/pf/4.4
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: authpf.8,v 1.45 2008/02/14 01:49:17 mcbride Exp $
|
||||
.\" $OpenBSD: authpf.8,v 1.46 2008/03/18 23:03:14 merdely Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 1998-2007 Bob Beck (beck@openbsd.org>. All rights reserved.
|
||||
.\"
|
||||
@ -14,7 +14,7 @@
|
||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 31 2007 $
|
||||
.Dd $Mdocdate: February 14 2008 $
|
||||
.Dt AUTHPF 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -56,7 +56,7 @@ in this case the client's IP address
|
||||
is not provided to the packet filter via the
|
||||
.Ar client_ip
|
||||
macro or the
|
||||
.Ar authpf users
|
||||
.Ar authpf_users
|
||||
table.
|
||||
Additionally, states associated with the client IP address
|
||||
are not purged when the session is ended.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: filter.c,v 1.7 2008/02/26 18:52:53 henning Exp $ */
|
||||
/* $OpenBSD: filter.c,v 1.8 2008/06/13 07:25:26 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
|
||||
@ -173,7 +173,7 @@ init_filter(char *opt_qname, char *opt_tagname, int opt_verbose)
|
||||
|
||||
dev = open("/dev/pf", O_RDWR);
|
||||
if (dev == -1)
|
||||
err(1, "/dev/pf");
|
||||
err(1, "open /dev/pf");
|
||||
if (ioctl(dev, DIOCGETSTATUS, &status) == -1)
|
||||
err(1, "DIOCGETSTATUS");
|
||||
if (!status.running)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ftp-proxy.c,v 1.16 2008/02/26 18:52:53 henning Exp $ */
|
||||
/* $OpenBSD: ftp-proxy.c,v 1.19 2008/06/13 07:25:26 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
|
||||
@ -91,7 +91,7 @@ int client_parse_cmd(struct session *s);
|
||||
void client_read(struct bufferevent *, void *);
|
||||
int drop_privs(void);
|
||||
void end_session(struct session *);
|
||||
int exit_daemon(void);
|
||||
void exit_daemon(void);
|
||||
int getline(char *, size_t *);
|
||||
void handle_connection(const int, short, void *);
|
||||
void handle_signal(int, short, void *);
|
||||
@ -282,6 +282,12 @@ end_session(struct session *s)
|
||||
|
||||
logmsg(LOG_INFO, "#%d ending session", s->id);
|
||||
|
||||
/* Flush output buffers. */
|
||||
if (s->client_bufev && s->client_fd != -1)
|
||||
evbuffer_write(s->client_bufev->output, s->client_fd);
|
||||
if (s->server_bufev && s->server_fd != -1)
|
||||
evbuffer_write(s->server_bufev->output, s->server_fd);
|
||||
|
||||
if (s->client_fd != -1)
|
||||
close(s->client_fd);
|
||||
if (s->server_fd != -1)
|
||||
@ -309,7 +315,7 @@ end_session(struct session *s)
|
||||
session_count--;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
exit_daemon(void)
|
||||
{
|
||||
struct session *s, *next;
|
||||
@ -323,9 +329,6 @@ exit_daemon(void)
|
||||
closelog();
|
||||
|
||||
exit(0);
|
||||
|
||||
/* NOTREACHED */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
@ -519,7 +522,7 @@ handle_signal(int sig, short event, void *arg)
|
||||
* Signal handler rules don't apply, libevent decouples for us.
|
||||
*/
|
||||
|
||||
logmsg(LOG_ERR, "%s exiting on signal %d", __progname, sig);
|
||||
logmsg(LOG_ERR, "exiting on signal %d", sig);
|
||||
|
||||
exit_daemon();
|
||||
}
|
||||
@ -834,8 +837,8 @@ u_int16_t
|
||||
pick_proxy_port(void)
|
||||
{
|
||||
/* Random should be good enough for avoiding port collisions. */
|
||||
return (IPPORT_HIFIRSTAUTO + (arc4random() %
|
||||
(IPPORT_HILASTAUTO - IPPORT_HIFIRSTAUTO)));
|
||||
return (IPPORT_HIFIRSTAUTO +
|
||||
arc4random_uniform(IPPORT_HILASTAUTO - IPPORT_HIFIRSTAUTO));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -106,7 +107,7 @@ evbuffer_add_buffer(struct evbuffer *outbuf, struct evbuffer *inbuf)
|
||||
/*
|
||||
* Optimization comes with a price; we need to notify the
|
||||
* buffer if necessary of the changes. oldoff is the amount
|
||||
* of data that we tranfered from inbuf to outbuf
|
||||
* of data that we transfered from inbuf to outbuf
|
||||
*/
|
||||
if (inbuf->off != oldoff && inbuf->cb != NULL)
|
||||
(*inbuf->cb)(inbuf, oldoff, inbuf->off, inbuf->cbarg);
|
||||
@ -134,9 +135,13 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
|
||||
int sz;
|
||||
va_list aq;
|
||||
|
||||
/* make sure that at least some space is available */
|
||||
evbuffer_expand(buf, 64);
|
||||
for (;;) {
|
||||
size_t used = buf->misalign + buf->off;
|
||||
buffer = (char *)buf->buffer + buf->off;
|
||||
space = buf->totallen - buf->misalign - buf->off;
|
||||
assert(buf->totallen >= used);
|
||||
space = buf->totallen - used;
|
||||
|
||||
#ifndef va_copy
|
||||
#define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list))
|
||||
@ -152,7 +157,7 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
|
||||
|
||||
va_end(aq);
|
||||
|
||||
if (sz == -1)
|
||||
if (sz < 0)
|
||||
return (-1);
|
||||
if (sz < space) {
|
||||
buf->off += sz;
|
||||
@ -244,7 +249,7 @@ evbuffer_readline(struct evbuffer *buffer)
|
||||
|
||||
/* Adds data to an event buffer */
|
||||
|
||||
static inline void
|
||||
static void
|
||||
evbuffer_align(struct evbuffer *buf)
|
||||
{
|
||||
memmove(buf->orig_buffer, buf->buffer, buf->off);
|
||||
@ -431,13 +436,12 @@ evbuffer_write(struct evbuffer *buffer, int fd)
|
||||
u_char *
|
||||
evbuffer_find(struct evbuffer *buffer, const u_char *what, size_t len)
|
||||
{
|
||||
size_t remain = buffer->off;
|
||||
u_char *search = buffer->buffer;
|
||||
u_char *search = buffer->buffer, *end = search + buffer->off;
|
||||
u_char *p;
|
||||
|
||||
while ((p = memchr(search, *what, remain)) != NULL) {
|
||||
remain = buffer->off - (size_t)(search - buffer->buffer);
|
||||
if (remain < len)
|
||||
while (search < end &&
|
||||
(p = memchr(search, *what, end - search)) != NULL) {
|
||||
if (p + len > end)
|
||||
break;
|
||||
if (memcmp(p, what, len) == 0)
|
||||
return (p);
|
||||
|
@ -31,6 +31,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "evsignal.h"
|
||||
|
||||
struct event_base {
|
||||
const struct eventop *evsel;
|
||||
void *evbase;
|
||||
@ -43,6 +45,9 @@ struct event_base {
|
||||
struct event_list **activequeues;
|
||||
int nactivequeues;
|
||||
|
||||
/* signal handling info */
|
||||
struct evsignal_info sig;
|
||||
|
||||
struct event_list eventqueue;
|
||||
struct timeval event_tv;
|
||||
|
||||
|
174
libevent/event.c
174
libevent/event.c
@ -51,6 +51,7 @@
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "event.h"
|
||||
#include "event-internal.h"
|
||||
@ -111,9 +112,9 @@ const struct eventop *eventops[] = {
|
||||
};
|
||||
|
||||
/* Global state */
|
||||
struct event_list signalqueue;
|
||||
|
||||
struct event_base *current_base = NULL;
|
||||
extern struct event_base *evsignal_base;
|
||||
static int use_monotonic;
|
||||
|
||||
/* Handle signals - This is a deprecated interface */
|
||||
int (*event_sigcb)(void); /* Signal callback when gotsig is set */
|
||||
@ -126,7 +127,7 @@ static int event_haveevents(struct event_base *);
|
||||
|
||||
static void event_process_active(struct event_base *);
|
||||
|
||||
static int timeout_next(struct event_base *, struct timeval *);
|
||||
static int timeout_next(struct event_base *, struct timeval **);
|
||||
static void timeout_process(struct event_base *);
|
||||
static void timeout_correct(struct event_base *, struct timeval *);
|
||||
|
||||
@ -144,25 +145,34 @@ compare(struct event *a, struct event *b)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
detect_monotonic(void)
|
||||
{
|
||||
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
|
||||
use_monotonic = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
gettime(struct timeval *tp)
|
||||
{
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||
struct timespec ts;
|
||||
|
||||
#ifdef HAVE_CLOCK_MONOTONIC
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
|
||||
#else
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
|
||||
#endif
|
||||
return (-1);
|
||||
tp->tv_sec = ts.tv_sec;
|
||||
tp->tv_usec = ts.tv_nsec / 1000;
|
||||
#else
|
||||
gettimeofday(tp, NULL);
|
||||
if (use_monotonic) {
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
|
||||
return (-1);
|
||||
|
||||
tp->tv_sec = ts.tv_sec;
|
||||
tp->tv_usec = ts.tv_nsec / 1000;
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
return (0);
|
||||
return (gettimeofday(tp, NULL));
|
||||
}
|
||||
|
||||
RB_PROTOTYPE(event_tree, event, ev_timeout_node, compare);
|
||||
@ -174,36 +184,42 @@ void *
|
||||
event_init(void)
|
||||
{
|
||||
int i;
|
||||
struct event_base *base;
|
||||
|
||||
if ((current_base = calloc(1, sizeof(struct event_base))) == NULL)
|
||||
if ((base = calloc(1, sizeof(struct event_base))) == NULL)
|
||||
event_err(1, "%s: calloc");
|
||||
|
||||
event_sigcb = NULL;
|
||||
event_gotsig = 0;
|
||||
gettime(¤t_base->event_tv);
|
||||
|
||||
RB_INIT(¤t_base->timetree);
|
||||
TAILQ_INIT(¤t_base->eventqueue);
|
||||
TAILQ_INIT(&signalqueue);
|
||||
|
||||
current_base->evbase = NULL;
|
||||
for (i = 0; eventops[i] && !current_base->evbase; i++) {
|
||||
current_base->evsel = eventops[i];
|
||||
|
||||
current_base->evbase = current_base->evsel->init();
|
||||
detect_monotonic();
|
||||
gettime(&base->event_tv);
|
||||
|
||||
RB_INIT(&base->timetree);
|
||||
TAILQ_INIT(&base->eventqueue);
|
||||
TAILQ_INIT(&base->sig.signalqueue);
|
||||
base->sig.ev_signal_pair[0] = -1;
|
||||
base->sig.ev_signal_pair[1] = -1;
|
||||
|
||||
base->evbase = NULL;
|
||||
for (i = 0; eventops[i] && !base->evbase; i++) {
|
||||
base->evsel = eventops[i];
|
||||
|
||||
base->evbase = base->evsel->init(base);
|
||||
}
|
||||
|
||||
if (current_base->evbase == NULL)
|
||||
if (base->evbase == NULL)
|
||||
event_errx(1, "%s: no event mechanism available", __func__);
|
||||
|
||||
if (getenv("EVENT_SHOW_METHOD"))
|
||||
event_msgx("libevent using: %s\n",
|
||||
current_base->evsel->name);
|
||||
base->evsel->name);
|
||||
|
||||
/* allocate a single active event queue */
|
||||
event_base_priority_init(current_base, 1);
|
||||
event_base_priority_init(base, 1);
|
||||
|
||||
return (current_base);
|
||||
current_base = base;
|
||||
return (base);
|
||||
}
|
||||
|
||||
void
|
||||
@ -217,7 +233,8 @@ event_base_free(struct event_base *base)
|
||||
current_base = NULL;
|
||||
|
||||
assert(base);
|
||||
assert(TAILQ_EMPTY(&base->eventqueue));
|
||||
if (base->evsel->dealloc != NULL)
|
||||
base->evsel->dealloc(base, base->evbase);
|
||||
for (i=0; i < base->nactivequeues; ++i)
|
||||
assert(TAILQ_EMPTY(base->activequeues[i]));
|
||||
|
||||
@ -227,8 +244,7 @@ event_base_free(struct event_base *base)
|
||||
free(base->activequeues[i]);
|
||||
free(base->activequeues);
|
||||
|
||||
if (base->evsel->dealloc != NULL)
|
||||
base->evsel->dealloc(base->evbase);
|
||||
assert(TAILQ_EMPTY(&base->eventqueue));
|
||||
|
||||
free(base);
|
||||
}
|
||||
@ -343,7 +359,6 @@ event_loopexit_cb(int fd, short what, void *arg)
|
||||
}
|
||||
|
||||
/* not thread safe */
|
||||
|
||||
int
|
||||
event_loopexit(struct timeval *tv)
|
||||
{
|
||||
@ -354,7 +369,7 @@ event_loopexit(struct timeval *tv)
|
||||
int
|
||||
event_base_loopexit(struct event_base *event_base, struct timeval *tv)
|
||||
{
|
||||
return (event_once(-1, EV_TIMEOUT, event_loopexit_cb,
|
||||
return (event_base_once(event_base, -1, EV_TIMEOUT, event_loopexit_cb,
|
||||
event_base, tv));
|
||||
}
|
||||
|
||||
@ -372,8 +387,13 @@ event_base_loop(struct event_base *base, int flags)
|
||||
const struct eventop *evsel = base->evsel;
|
||||
void *evbase = base->evbase;
|
||||
struct timeval tv;
|
||||
struct timeval *tv_p;
|
||||
int res, done;
|
||||
|
||||
#ifndef WIN32
|
||||
if(!TAILQ_EMPTY(&base->sig.signalqueue))
|
||||
evsignal_base = base;
|
||||
#endif
|
||||
done = 0;
|
||||
while (!done) {
|
||||
/* Calculate the initial events that we are waiting for */
|
||||
@ -398,21 +418,18 @@ event_base_loop(struct event_base *base, int flags)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if time is running backwards */
|
||||
gettime(&tv);
|
||||
if (timercmp(&tv, &base->event_tv, <)) {
|
||||
struct timeval off;
|
||||
event_debug(("%s: time is running backwards, corrected",
|
||||
__func__));
|
||||
timersub(&base->event_tv, &tv, &off);
|
||||
timeout_correct(base, &off);
|
||||
}
|
||||
base->event_tv = tv;
|
||||
timeout_correct(base, &tv);
|
||||
|
||||
if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK))
|
||||
timeout_next(base, &tv);
|
||||
else
|
||||
tv_p = &tv;
|
||||
if (!base->event_count_active && !(flags & EVLOOP_NONBLOCK)) {
|
||||
timeout_next(base, &tv_p);
|
||||
} else {
|
||||
/*
|
||||
* if we have active events, we just poll new events
|
||||
* without waiting.
|
||||
*/
|
||||
timerclear(&tv);
|
||||
}
|
||||
|
||||
/* If we have no events, we just exit */
|
||||
if (!event_haveevents(base)) {
|
||||
@ -420,7 +437,8 @@ event_base_loop(struct event_base *base, int flags)
|
||||
return (1);
|
||||
}
|
||||
|
||||
res = evsel->dispatch(base, evbase, &tv);
|
||||
res = evsel->dispatch(base, evbase, tv_p);
|
||||
|
||||
|
||||
if (res == -1)
|
||||
return (-1);
|
||||
@ -459,11 +477,18 @@ event_once_cb(int fd, short events, void *arg)
|
||||
free(eonce);
|
||||
}
|
||||
|
||||
/* Schedules an event once */
|
||||
|
||||
/* not threadsafe, event scheduled once. */
|
||||
int
|
||||
event_once(int fd, short events,
|
||||
void (*callback)(int, short, void *), void *arg, struct timeval *tv)
|
||||
{
|
||||
return event_base_once(current_base, fd, events, callback, arg, tv);
|
||||
}
|
||||
|
||||
/* Schedules an event once */
|
||||
int
|
||||
event_base_once(struct event_base *base, int fd, short events,
|
||||
void (*callback)(int, short, void *), void *arg, struct timeval *tv)
|
||||
{
|
||||
struct event_once *eonce;
|
||||
struct timeval etv;
|
||||
@ -496,7 +521,9 @@ event_once(int fd, short events,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
res = event_add(&eonce->ev, tv);
|
||||
res = event_base_set(base, &eonce->ev);
|
||||
if (res == 0)
|
||||
res = event_add(&eonce->ev, tv);
|
||||
if (res != 0) {
|
||||
free(eonce);
|
||||
return (res);
|
||||
@ -516,12 +543,14 @@ event_set(struct event *ev, int fd, short events,
|
||||
ev->ev_arg = arg;
|
||||
ev->ev_fd = fd;
|
||||
ev->ev_events = events;
|
||||
ev->ev_res = 0;
|
||||
ev->ev_flags = EVLIST_INIT;
|
||||
ev->ev_ncalls = 0;
|
||||
ev->ev_pncalls = NULL;
|
||||
|
||||
/* by default, we put new events into the middle priority */
|
||||
ev->ev_pri = current_base->nactivequeues/2;
|
||||
if(current_base)
|
||||
ev->ev_pri = current_base->nactivequeues/2;
|
||||
}
|
||||
|
||||
int
|
||||
@ -710,16 +739,16 @@ event_active(struct event *ev, int res, short ncalls)
|
||||
event_queue_insert(ev->ev_base, ev, EVLIST_ACTIVE);
|
||||
}
|
||||
|
||||
int
|
||||
timeout_next(struct event_base *base, struct timeval *tv)
|
||||
static int
|
||||
timeout_next(struct event_base *base, struct timeval **tv_p)
|
||||
{
|
||||
struct timeval dflt = TIMEOUT_DEFAULT;
|
||||
|
||||
struct timeval now;
|
||||
struct event *ev;
|
||||
struct timeval *tv = *tv_p;
|
||||
|
||||
if ((ev = RB_MIN(event_tree, &base->timetree)) == NULL) {
|
||||
*tv = dflt;
|
||||
/* if no time-based events are active wait for I/O */
|
||||
*tv_p = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -740,17 +769,38 @@ timeout_next(struct event_base *base, struct timeval *tv)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines if the time is running backwards by comparing the current
|
||||
* time against the last time we checked. Not needed when using clock
|
||||
* monotonic.
|
||||
*/
|
||||
|
||||
static void
|
||||
timeout_correct(struct event_base *base, struct timeval *off)
|
||||
timeout_correct(struct event_base *base, struct timeval *tv)
|
||||
{
|
||||
struct event *ev;
|
||||
struct timeval off;
|
||||
|
||||
if (use_monotonic)
|
||||
return;
|
||||
|
||||
/* Check if time is running backwards */
|
||||
gettime(tv);
|
||||
if (timercmp(tv, &base->event_tv, >=)) {
|
||||
base->event_tv = *tv;
|
||||
return;
|
||||
}
|
||||
|
||||
event_debug(("%s: time is running backwards, corrected",
|
||||
__func__));
|
||||
timersub(&base->event_tv, tv, &off);
|
||||
|
||||
/*
|
||||
* We can modify the key element of the node without destroying
|
||||
* the key, beause we apply it to all in the right order.
|
||||
*/
|
||||
RB_FOREACH(ev, event_tree, &base->timetree)
|
||||
timersub(&ev->ev_timeout, off, &ev->ev_timeout);
|
||||
timersub(&ev->ev_timeout, &off, &ev->ev_timeout);
|
||||
}
|
||||
|
||||
void
|
||||
@ -801,7 +851,7 @@ event_queue_remove(struct event_base *base, struct event *ev, int queue)
|
||||
ev, ev_active_next);
|
||||
break;
|
||||
case EVLIST_SIGNAL:
|
||||
TAILQ_REMOVE(&signalqueue, ev, ev_signal_next);
|
||||
TAILQ_REMOVE(&base->sig.signalqueue, ev, ev_signal_next);
|
||||
break;
|
||||
case EVLIST_TIMEOUT:
|
||||
RB_REMOVE(event_tree, &base->timetree, ev);
|
||||
@ -843,7 +893,7 @@ event_queue_insert(struct event_base *base, struct event *ev, int queue)
|
||||
ev,ev_active_next);
|
||||
break;
|
||||
case EVLIST_SIGNAL:
|
||||
TAILQ_INSERT_TAIL(&signalqueue, ev, ev_signal_next);
|
||||
TAILQ_INSERT_TAIL(&base->sig.signalqueue, ev, ev_signal_next);
|
||||
break;
|
||||
case EVLIST_TIMEOUT: {
|
||||
struct event *tmp = RB_INSERT(event_tree, &base->timetree, ev);
|
||||
|
@ -31,6 +31,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef WIN32
|
||||
@ -131,16 +133,14 @@ TAILQ_HEAD (evkeyvalq, evkeyval);
|
||||
|
||||
struct eventop {
|
||||
char *name;
|
||||
void *(*init)(void);
|
||||
void *(*init)(struct event_base *);
|
||||
int (*add)(void *, struct event *);
|
||||
int (*del)(void *, struct event *);
|
||||
int (*recalc)(struct event_base *, void *, int);
|
||||
int (*dispatch)(struct event_base *, void *, struct timeval *);
|
||||
void (*dealloc)(void *);
|
||||
void (*dealloc)(struct event_base *, void *);
|
||||
};
|
||||
|
||||
#define TIMEOUT_DEFAULT {5, 0}
|
||||
|
||||
void *event_init(void);
|
||||
int event_dispatch(void);
|
||||
int event_base_dispatch(struct event_base *);
|
||||
@ -184,6 +184,7 @@ int event_base_loopexit(struct event_base *, struct timeval *);
|
||||
|
||||
void event_set(struct event *, int, short, void (*)(int, short, void *), void *);
|
||||
int event_once(int, short, void (*)(int, short, void *), void *, struct timeval *);
|
||||
int event_base_once(struct event_base *, int, short, void (*)(int, short, void *), void *, struct timeval *);
|
||||
|
||||
int event_add(struct event *, struct timeval *);
|
||||
int event_del(struct event *);
|
||||
@ -299,39 +300,37 @@ void evbuffer_setcb(struct evbuffer *, void (*)(struct evbuffer *, size_t, size_
|
||||
|
||||
void evtag_init(void);
|
||||
|
||||
void evtag_marshal(struct evbuffer *evbuf, u_int8_t tag, const void *data,
|
||||
u_int32_t len);
|
||||
void evtag_marshal(struct evbuffer *evbuf, uint8_t tag, const void *data,
|
||||
uint32_t len);
|
||||
|
||||
void encode_int(struct evbuffer *evbuf, u_int32_t number);
|
||||
void encode_int(struct evbuffer *evbuf, uint32_t number);
|
||||
|
||||
void evtag_marshal_int(struct evbuffer *evbuf, u_int8_t tag,
|
||||
u_int32_t integer);
|
||||
void evtag_marshal_int(struct evbuffer *evbuf, uint8_t tag, uint32_t integer);
|
||||
|
||||
void evtag_marshal_string(struct evbuffer *buf, u_int8_t tag,
|
||||
void evtag_marshal_string(struct evbuffer *buf, uint8_t tag,
|
||||
const char *string);
|
||||
|
||||
void evtag_marshal_timeval(struct evbuffer *evbuf, u_int8_t tag,
|
||||
void evtag_marshal_timeval(struct evbuffer *evbuf, uint8_t tag,
|
||||
struct timeval *tv);
|
||||
|
||||
void evtag_test(void);
|
||||
|
||||
int evtag_unmarshal(struct evbuffer *src, u_int8_t *ptag,
|
||||
struct evbuffer *dst);
|
||||
int evtag_peek(struct evbuffer *evbuf, u_int8_t *ptag);
|
||||
int evtag_peek_length(struct evbuffer *evbuf, u_int32_t *plength);
|
||||
int evtag_payload_length(struct evbuffer *evbuf, u_int32_t *plength);
|
||||
int evtag_unmarshal(struct evbuffer *src, uint8_t *ptag, struct evbuffer *dst);
|
||||
int evtag_peek(struct evbuffer *evbuf, uint8_t *ptag);
|
||||
int evtag_peek_length(struct evbuffer *evbuf, uint32_t *plength);
|
||||
int evtag_payload_length(struct evbuffer *evbuf, uint32_t *plength);
|
||||
int evtag_consume(struct evbuffer *evbuf);
|
||||
|
||||
int evtag_unmarshal_int(struct evbuffer *evbuf, u_int8_t need_tag,
|
||||
u_int32_t *pinteger);
|
||||
int evtag_unmarshal_int(struct evbuffer *evbuf, uint8_t need_tag,
|
||||
uint32_t *pinteger);
|
||||
|
||||
int evtag_unmarshal_fixed(struct evbuffer *src, u_int8_t need_tag, void *data,
|
||||
int evtag_unmarshal_fixed(struct evbuffer *src, uint8_t need_tag, void *data,
|
||||
size_t len);
|
||||
|
||||
int evtag_unmarshal_string(struct evbuffer *evbuf, u_int8_t need_tag,
|
||||
int evtag_unmarshal_string(struct evbuffer *evbuf, uint8_t need_tag,
|
||||
char **pstring);
|
||||
|
||||
int evtag_unmarshal_timeval(struct evbuffer *evbuf, u_int8_t need_tag,
|
||||
int evtag_unmarshal_timeval(struct evbuffer *evbuf, uint8_t need_tag,
|
||||
struct timeval *ptv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -27,9 +27,18 @@
|
||||
#ifndef _EVSIGNAL_H_
|
||||
#define _EVSIGNAL_H_
|
||||
|
||||
void evsignal_init(void);
|
||||
void evsignal_process(void);
|
||||
struct evsignal_info {
|
||||
struct event_list signalqueue;
|
||||
struct event ev_signal;
|
||||
int ev_signal_pair[2];
|
||||
int ev_signal_added;
|
||||
volatile sig_atomic_t evsignal_caught;
|
||||
sig_atomic_t evsigcaught[NSIG];
|
||||
};
|
||||
void evsignal_init(struct event_base *);
|
||||
void evsignal_process(struct event_base *);
|
||||
int evsignal_add(struct event *);
|
||||
int evsignal_del(struct event *);
|
||||
void evsignal_dealloc(struct event_base *);
|
||||
|
||||
#endif /* _EVSIGNAL_H_ */
|
||||
|
@ -48,10 +48,13 @@
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
|
||||
#define INTPTR(x) (intptr_t)x
|
||||
/* Some platforms apparently define the udata field of struct kevent as
|
||||
* ntptr_t, whereas others define it as void*. There doesn't seem to be an
|
||||
* easy way to tell them apart via autoconf, so we need to use OS macros. */
|
||||
#if defined(HAVE_INTTYPES_H) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__darwin__) && !defined(__APPLE__)
|
||||
#define PTR_TO_UDATA(x) ((intptr_t)(x))
|
||||
#else
|
||||
#define INTPTR(x) x
|
||||
#define PTR_TO_UDATA(x) (x)
|
||||
#endif
|
||||
|
||||
#include "event.h"
|
||||
@ -69,13 +72,13 @@ struct kqop {
|
||||
int kq;
|
||||
};
|
||||
|
||||
void *kq_init (void);
|
||||
void *kq_init (struct event_base *);
|
||||
int kq_add (void *, struct event *);
|
||||
int kq_del (void *, struct event *);
|
||||
int kq_recalc (struct event_base *, void *, int);
|
||||
int kq_dispatch (struct event_base *, void *, struct timeval *);
|
||||
int kq_insert (struct kqop *, struct kevent *);
|
||||
void kq_dealloc (void *);
|
||||
void kq_dealloc (struct event_base *, void *);
|
||||
|
||||
const struct eventop kqops = {
|
||||
"kqueue",
|
||||
@ -88,7 +91,7 @@ const struct eventop kqops = {
|
||||
};
|
||||
|
||||
void *
|
||||
kq_init(void)
|
||||
kq_init(struct event_base *base)
|
||||
{
|
||||
int kq;
|
||||
struct kqop *kqueueop;
|
||||
@ -212,13 +215,16 @@ kq_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
||||
struct kevent *changes = kqop->changes;
|
||||
struct kevent *events = kqop->events;
|
||||
struct event *ev;
|
||||
struct timespec ts;
|
||||
struct timespec ts, *ts_p = NULL;
|
||||
int i, res;
|
||||
|
||||
TIMEVAL_TO_TIMESPEC(tv, &ts);
|
||||
if (tv != NULL) {
|
||||
TIMEVAL_TO_TIMESPEC(tv, &ts);
|
||||
ts_p = &ts;
|
||||
}
|
||||
|
||||
res = kevent(kqop->kq, changes, kqop->nchanges,
|
||||
events, kqop->nevents, &ts);
|
||||
events, kqop->nevents, ts_p);
|
||||
kqop->nchanges = 0;
|
||||
if (res == -1) {
|
||||
if (errno != EINTR) {
|
||||
@ -294,7 +300,7 @@ kq_add(void *arg, struct event *ev)
|
||||
kev.flags = EV_ADD;
|
||||
if (!(ev->ev_events & EV_PERSIST))
|
||||
kev.flags |= EV_ONESHOT;
|
||||
kev.udata = INTPTR(ev);
|
||||
kev.udata = PTR_TO_UDATA(ev);
|
||||
|
||||
if (kq_insert(kqop, &kev) == -1)
|
||||
return (-1);
|
||||
@ -317,7 +323,7 @@ kq_add(void *arg, struct event *ev)
|
||||
kev.flags = EV_ADD;
|
||||
if (!(ev->ev_events & EV_PERSIST))
|
||||
kev.flags |= EV_ONESHOT;
|
||||
kev.udata = INTPTR(ev);
|
||||
kev.udata = PTR_TO_UDATA(ev);
|
||||
|
||||
if (kq_insert(kqop, &kev) == -1)
|
||||
return (-1);
|
||||
@ -332,7 +338,7 @@ kq_add(void *arg, struct event *ev)
|
||||
kev.flags = EV_ADD;
|
||||
if (!(ev->ev_events & EV_PERSIST))
|
||||
kev.flags |= EV_ONESHOT;
|
||||
kev.udata = INTPTR(ev);
|
||||
kev.udata = PTR_TO_UDATA(ev);
|
||||
|
||||
if (kq_insert(kqop, &kev) == -1)
|
||||
return (-1);
|
||||
@ -398,7 +404,7 @@ kq_del(void *arg, struct event *ev)
|
||||
}
|
||||
|
||||
void
|
||||
kq_dealloc(void *arg)
|
||||
kq_dealloc(struct event_base *base, void *arg)
|
||||
{
|
||||
struct kqop *kqop = arg;
|
||||
|
||||
|
@ -54,8 +54,6 @@
|
||||
#include "evsignal.h"
|
||||
#include "log.h"
|
||||
|
||||
extern volatile sig_atomic_t evsignal_caught;
|
||||
|
||||
struct pollop {
|
||||
int event_count; /* Highest number alloc */
|
||||
int nfds; /* Size of event_* */
|
||||
@ -68,12 +66,12 @@ struct pollop {
|
||||
* "no entry." */
|
||||
};
|
||||
|
||||
void *poll_init (void);
|
||||
void *poll_init (struct event_base *);
|
||||
int poll_add (void *, struct event *);
|
||||
int poll_del (void *, struct event *);
|
||||
int poll_recalc (struct event_base *, void *, int);
|
||||
int poll_dispatch (struct event_base *, void *, struct timeval *);
|
||||
void poll_dealloc (void *);
|
||||
void poll_dealloc (struct event_base *, void *);
|
||||
|
||||
const struct eventop pollops = {
|
||||
"poll",
|
||||
@ -86,7 +84,7 @@ const struct eventop pollops = {
|
||||
};
|
||||
|
||||
void *
|
||||
poll_init(void)
|
||||
poll_init(struct event_base *base)
|
||||
{
|
||||
struct pollop *pollop;
|
||||
|
||||
@ -97,7 +95,7 @@ poll_init(void)
|
||||
if (!(pollop = calloc(1, sizeof(struct pollop))))
|
||||
return (NULL);
|
||||
|
||||
evsignal_init();
|
||||
evsignal_init(base);
|
||||
|
||||
return (pollop);
|
||||
}
|
||||
@ -150,13 +148,16 @@ poll_check_ok(struct pollop *pop)
|
||||
int
|
||||
poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
||||
{
|
||||
int res, i, sec, nfds;
|
||||
int res, i, msec = -1, nfds;
|
||||
struct pollop *pop = arg;
|
||||
|
||||
poll_check_ok(pop);
|
||||
sec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
|
||||
|
||||
if (tv != NULL)
|
||||
msec = tv->tv_sec * 1000 + (tv->tv_usec + 999) / 1000;
|
||||
|
||||
nfds = pop->nfds;
|
||||
res = poll(pop->event_set, nfds, sec);
|
||||
res = poll(pop->event_set, nfds, msec);
|
||||
|
||||
if (res == -1) {
|
||||
if (errno != EINTR) {
|
||||
@ -164,10 +165,11 @@ poll_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
evsignal_process();
|
||||
evsignal_process(base);
|
||||
return (0);
|
||||
} else if (evsignal_caught)
|
||||
evsignal_process();
|
||||
} else if (base->sig.evsignal_caught) {
|
||||
evsignal_process(base);
|
||||
}
|
||||
|
||||
event_debug(("%s: poll reports %d", __func__, res));
|
||||
|
||||
@ -370,10 +372,11 @@ poll_del(void *arg, struct event *ev)
|
||||
}
|
||||
|
||||
void
|
||||
poll_dealloc(void *arg)
|
||||
poll_dealloc(struct event_base *base, void *arg)
|
||||
{
|
||||
struct pollop *pop = arg;
|
||||
|
||||
evsignal_dealloc(base);
|
||||
if (pop->event_set)
|
||||
free(pop->event_set);
|
||||
if (pop->event_r_back)
|
||||
|
@ -36,6 +36,9 @@
|
||||
#else
|
||||
#include <sys/_time.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#include <sys/queue.h>
|
||||
#include <sys/tree.h>
|
||||
#include <signal.h>
|
||||
@ -57,8 +60,6 @@
|
||||
#define howmany(x, y) (((x)+((y)-1))/(y))
|
||||
#endif
|
||||
|
||||
extern volatile sig_atomic_t evsignal_caught;
|
||||
|
||||
struct selectop {
|
||||
int event_fds; /* Highest fd in fd set */
|
||||
int event_fdsz;
|
||||
@ -70,12 +71,12 @@ struct selectop {
|
||||
struct event **event_w_by_fd;
|
||||
};
|
||||
|
||||
void *select_init (void);
|
||||
void *select_init (struct event_base *);
|
||||
int select_add (void *, struct event *);
|
||||
int select_del (void *, struct event *);
|
||||
int select_recalc (struct event_base *, void *, int);
|
||||
int select_dispatch (struct event_base *, void *, struct timeval *);
|
||||
void select_dealloc (void *);
|
||||
void select_dealloc (struct event_base *, void *);
|
||||
|
||||
const struct eventop selectops = {
|
||||
"select",
|
||||
@ -90,7 +91,7 @@ const struct eventop selectops = {
|
||||
static int select_resize(struct selectop *sop, int fdsz);
|
||||
|
||||
void *
|
||||
select_init(void)
|
||||
select_init(struct event_base *base)
|
||||
{
|
||||
struct selectop *sop;
|
||||
|
||||
@ -103,7 +104,7 @@ select_init(void)
|
||||
|
||||
select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask));
|
||||
|
||||
evsignal_init();
|
||||
evsignal_init(base);
|
||||
|
||||
return (sop);
|
||||
}
|
||||
@ -113,7 +114,7 @@ static void
|
||||
check_selectop(struct selectop *sop)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<=sop->event_fds;++i) {
|
||||
for (i = 0; i <= sop->event_fds; ++i) {
|
||||
if (FD_ISSET(i, sop->event_readset_in)) {
|
||||
assert(sop->event_r_by_fd[i]);
|
||||
assert(sop->event_r_by_fd[i]->ev_events & EV_READ);
|
||||
@ -174,10 +175,11 @@ select_dispatch(struct event_base *base, void *arg, struct timeval *tv)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
evsignal_process();
|
||||
evsignal_process(base);
|
||||
return (0);
|
||||
} else if (evsignal_caught)
|
||||
evsignal_process();
|
||||
} else if (base->sig.evsignal_caught) {
|
||||
evsignal_process(base);
|
||||
}
|
||||
|
||||
event_debug(("%s: select reports %d", __func__, res));
|
||||
|
||||
@ -348,10 +350,11 @@ select_del(void *arg, struct event *ev)
|
||||
}
|
||||
|
||||
void
|
||||
select_dealloc(void *arg)
|
||||
select_dealloc(struct event_base *base, void *arg)
|
||||
{
|
||||
struct selectop *sop = arg;
|
||||
|
||||
evsignal_dealloc(base);
|
||||
if (sop->event_readset_in)
|
||||
free(sop->event_readset_in);
|
||||
if (sop->event_writeset_in)
|
||||
|
@ -31,6 +31,7 @@
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/tree.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
@ -47,19 +48,14 @@
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
#include "event.h"
|
||||
#include "event-internal.h"
|
||||
#include "evsignal.h"
|
||||
#include "log.h"
|
||||
|
||||
extern struct event_list signalqueue;
|
||||
|
||||
static sig_atomic_t evsigcaught[NSIG];
|
||||
volatile sig_atomic_t evsignal_caught = 0;
|
||||
|
||||
static struct event ev_signal;
|
||||
static int ev_signal_pair[2];
|
||||
static int ev_signal_added;
|
||||
struct event_base *evsignal_base = NULL;
|
||||
|
||||
static void evsignal_handler(int sig);
|
||||
|
||||
@ -87,24 +83,27 @@ evsignal_cb(int fd, short what, void *arg)
|
||||
#endif
|
||||
|
||||
void
|
||||
evsignal_init(void)
|
||||
evsignal_init(struct event_base *base)
|
||||
{
|
||||
/*
|
||||
* Our signal handler is going to write to one end of the socket
|
||||
* pair to wake up our event loop. The event loop then scans for
|
||||
* signals that got delivered.
|
||||
*/
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, ev_signal_pair) == -1)
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, base->sig.ev_signal_pair) == -1)
|
||||
event_err(1, "%s: socketpair", __func__);
|
||||
|
||||
FD_CLOSEONEXEC(ev_signal_pair[0]);
|
||||
FD_CLOSEONEXEC(ev_signal_pair[1]);
|
||||
FD_CLOSEONEXEC(base->sig.ev_signal_pair[0]);
|
||||
FD_CLOSEONEXEC(base->sig.ev_signal_pair[1]);
|
||||
base->sig.evsignal_caught = 0;
|
||||
memset(&base->sig.evsigcaught, 0, sizeof(sig_atomic_t)*NSIG);
|
||||
|
||||
fcntl(ev_signal_pair[0], F_SETFL, O_NONBLOCK);
|
||||
fcntl(base->sig.ev_signal_pair[0], F_SETFL, O_NONBLOCK);
|
||||
|
||||
event_set(&ev_signal, ev_signal_pair[1], EV_READ,
|
||||
evsignal_cb, &ev_signal);
|
||||
ev_signal.ev_flags |= EVLIST_INTERNAL;
|
||||
event_set(&base->sig.ev_signal, base->sig.ev_signal_pair[1], EV_READ,
|
||||
evsignal_cb, &base->sig.ev_signal);
|
||||
base->sig.ev_signal.ev_base = base;
|
||||
base->sig.ev_signal.ev_flags |= EVLIST_INTERNAL;
|
||||
}
|
||||
|
||||
int
|
||||
@ -112,6 +111,7 @@ evsignal_add(struct event *ev)
|
||||
{
|
||||
int evsignal;
|
||||
struct sigaction sa;
|
||||
struct event_base *base = ev->ev_base;
|
||||
|
||||
if (ev->ev_events & (EV_READ|EV_WRITE))
|
||||
event_errx(1, "%s: EV_SIGNAL incompatible use", __func__);
|
||||
@ -121,29 +121,23 @@ evsignal_add(struct event *ev)
|
||||
sa.sa_handler = evsignal_handler;
|
||||
sigfillset(&sa.sa_mask);
|
||||
sa.sa_flags |= SA_RESTART;
|
||||
/* catch signals if they happen quickly */
|
||||
evsignal_base = base;
|
||||
|
||||
if (sigaction(evsignal, &sa, NULL) == -1)
|
||||
return (-1);
|
||||
|
||||
if (!ev_signal_added) {
|
||||
ev_signal_added = 1;
|
||||
event_add(&ev_signal, NULL);
|
||||
if (!base->sig.ev_signal_added) {
|
||||
base->sig.ev_signal_added = 1;
|
||||
event_add(&base->sig.ev_signal, NULL);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Nothing to be done here.
|
||||
*/
|
||||
|
||||
int
|
||||
evsignal_del(struct event *ev)
|
||||
{
|
||||
int evsignal;
|
||||
|
||||
evsignal = EVENT_SIGNAL(ev);
|
||||
|
||||
return (sigaction(EVENT_SIGNAL(ev),(struct sigaction *)SIG_DFL, NULL));
|
||||
}
|
||||
|
||||
@ -152,29 +146,50 @@ evsignal_handler(int sig)
|
||||
{
|
||||
int save_errno = errno;
|
||||
|
||||
evsigcaught[sig]++;
|
||||
evsignal_caught = 1;
|
||||
if(evsignal_base == NULL) {
|
||||
event_warn(
|
||||
"%s: received signal %s, but have no base configured",
|
||||
__func__, sig);
|
||||
return;
|
||||
}
|
||||
|
||||
evsignal_base->sig.evsigcaught[sig]++;
|
||||
evsignal_base->sig.evsignal_caught = 1;
|
||||
|
||||
/* Wake up our notification mechanism */
|
||||
write(ev_signal_pair[0], "a", 1);
|
||||
write(evsignal_base->sig.ev_signal_pair[0], "a", 1);
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
void
|
||||
evsignal_process(void)
|
||||
evsignal_process(struct event_base *base)
|
||||
{
|
||||
struct event *ev;
|
||||
sig_atomic_t ncalls;
|
||||
|
||||
evsignal_caught = 0;
|
||||
TAILQ_FOREACH(ev, &signalqueue, ev_signal_next) {
|
||||
ncalls = evsigcaught[EVENT_SIGNAL(ev)];
|
||||
base->sig.evsignal_caught = 0;
|
||||
TAILQ_FOREACH(ev, &base->sig.signalqueue, ev_signal_next) {
|
||||
ncalls = base->sig.evsigcaught[EVENT_SIGNAL(ev)];
|
||||
if (ncalls) {
|
||||
if (!(ev->ev_events & EV_PERSIST))
|
||||
event_del(ev);
|
||||
event_active(ev, EV_SIGNAL, ncalls);
|
||||
evsigcaught[EVENT_SIGNAL(ev)] = 0;
|
||||
base->sig.evsigcaught[EVENT_SIGNAL(ev)] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
evsignal_dealloc(struct event_base *base)
|
||||
{
|
||||
if(base->sig.ev_signal_added) {
|
||||
event_del(&base->sig.ev_signal);
|
||||
base->sig.ev_signal_added = 0;
|
||||
}
|
||||
assert(TAILQ_EMPTY(&base->sig.signalqueue));
|
||||
|
||||
close(base->sig.ev_signal_pair[0]);
|
||||
base->sig.ev_signal_pair[0] = -1;
|
||||
close(base->sig.ev_signal_pair[1]);
|
||||
base->sig.ev_signal_pair[1] = -1;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pf.conf.5,v 1.393 2008/02/11 07:46:32 jmc Exp $
|
||||
.\" $OpenBSD: pf.conf.5,v 1.402 2008/06/11 07:21:00 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002, Daniel Hartmeier
|
||||
.\" All rights reserved.
|
||||
@ -27,7 +27,7 @@
|
||||
.\" ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: Febuary 1 2008 $
|
||||
.Dd $Mdocdate: June 10 2008 $
|
||||
.Dt PF.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -164,7 +164,7 @@ A table initialized with the empty list,
|
||||
will be cleared on load.
|
||||
.El
|
||||
.Pp
|
||||
Tables may be defined with the following two attributes:
|
||||
Tables may be defined with the following attributes:
|
||||
.Bl -tag -width persist
|
||||
.It Ar persist
|
||||
The
|
||||
@ -183,6 +183,11 @@ can be used to add or remove addresses from the table at any time, even
|
||||
when running with
|
||||
.Xr securelevel 7
|
||||
= 2.
|
||||
.It Ar counters
|
||||
The
|
||||
.Ar counters
|
||||
flag enables per-address packet and byte counters which can be displayed with
|
||||
.Xr pfctl 8 .
|
||||
.El
|
||||
.Pp
|
||||
For example,
|
||||
@ -629,6 +634,19 @@ modifier to ensure unique IP identifiers.
|
||||
Enforces a minimum TTL for matching IP packets.
|
||||
.It Ar max-mss Aq Ar number
|
||||
Enforces a maximum MSS for matching TCP packets.
|
||||
.It Xo Ar set-tos Aq Ar string
|
||||
.No \*(Ba Aq Ar number
|
||||
.Xc
|
||||
Enforces a
|
||||
.Em TOS
|
||||
for matching IP packets.
|
||||
.Em TOS
|
||||
may be
|
||||
given as one of
|
||||
.Ar lowdelay ,
|
||||
.Ar throughput ,
|
||||
.Ar reliability ,
|
||||
or as either hex or decimal.
|
||||
.It Ar random-id
|
||||
Replaces the IP identification field with random values to compensate
|
||||
for predictable values generated by many hosts.
|
||||
@ -1808,7 +1826,8 @@ or
|
||||
rules in addition to filter rules.
|
||||
Tags take the same macros as labels (see above).
|
||||
.It Ar tagged Aq Ar string
|
||||
Used with filter or translation rules to specify that packets must already
|
||||
Used with filter, translation or scrub rules
|
||||
to specify that packets must already
|
||||
be tagged with the given tag in order to match the rule.
|
||||
Inverse tag matching can also be done
|
||||
by specifying the
|
||||
@ -1819,6 +1838,22 @@ keyword.
|
||||
.It Ar rtable Aq Ar number
|
||||
Used to select an alternate routing table for the routing lookup.
|
||||
Only effective before the route lookup happened, i.e. when filtering inbound.
|
||||
.It Xo Ar divert-to Aq Ar host
|
||||
.Ar port Aq Ar port
|
||||
.Xc
|
||||
Used to redirect packets to a local socket bound to
|
||||
.Ar host
|
||||
and
|
||||
.Ar port .
|
||||
The packets will not be modified, so
|
||||
.Xr getsockname 2
|
||||
on the socket will return the original destination address of the packet.
|
||||
.It Ar divert-reply
|
||||
Used to receive replies for sockets that are bound to addresses
|
||||
which are not local to the machine.
|
||||
See
|
||||
.Xr setsockopt 2
|
||||
for information on how to bind these sockets.
|
||||
.It Ar probability Aq Ar number
|
||||
A probability attribute can be attached to a rule, with a value set between
|
||||
0 and 1, bounds not included.
|
||||
@ -2056,6 +2091,13 @@ Changes the timeout values used for states created by this rule.
|
||||
For a list of all valid timeout names, see
|
||||
.Sx OPTIONS
|
||||
above.
|
||||
.It Ar sloppy
|
||||
Uses a sloppy TCP connection tracker that does not check sequence
|
||||
numbers at all, which makes insertion and ICMP teardown attacks way
|
||||
easier.
|
||||
This is intended to be used in situations where one does not see all
|
||||
packets of a connection, e.g. in asymmetric routing situations.
|
||||
Cannot be used with modulate or synproxy state.
|
||||
.El
|
||||
.Pp
|
||||
Multiple options can be specified, separated by commas:
|
||||
@ -2793,10 +2835,10 @@ logopts = logopt [ "," logopts ]
|
||||
logopt = "all" | "user" | "to" interface-name
|
||||
|
||||
filteropt-list = filteropt-list filteropt | filteropt
|
||||
filteropt = user | group | flags | icmp-type | icmp6-type | tos |
|
||||
filteropt = user | group | flags | icmp-type | icmp6-type | "tos" tos |
|
||||
( "no" | "keep" | "modulate" | "synproxy" ) "state"
|
||||
[ "(" state-opts ")" ] |
|
||||
"fragment" | "no-df" | "min-ttl" number |
|
||||
"fragment" | "no-df" | "min-ttl" number | "set-tos" tos |
|
||||
"max-mss" number | "random-id" | "reassemble tcp" |
|
||||
fragmentation | "allow-opts" |
|
||||
"label" string | "tag" string | [ ! ] "tagged" string |
|
||||
@ -2827,7 +2869,7 @@ antispoof-rule = "antispoof" [ "log" ] [ "quick" ]
|
||||
|
||||
table-rule = "table" "\*(Lt" string "\*(Gt" [ tableopts-list ]
|
||||
tableopts-list = tableopts-list tableopts | tableopts
|
||||
tableopts = "persist" | "const" | "file" string |
|
||||
tableopts = "persist" | "const" | "counters" | "file" string |
|
||||
"{" [ tableaddr-list ] "}"
|
||||
tableaddr-list = tableaddr-list [ "," ] tableaddr-spec | tableaddr-spec
|
||||
tableaddr-spec = [ "!" ] tableaddr [ "/" mask-bits ]
|
||||
@ -2917,11 +2959,11 @@ icmp-type-code = ( icmp-type-name | icmp-type-number )
|
||||
[ "code" ( icmp-code-name | icmp-code-number ) ]
|
||||
icmp-list = icmp-type-code [ [ "," ] icmp-list ]
|
||||
|
||||
tos = "tos" ( "lowdelay" | "throughput" | "reliability" |
|
||||
tos = ( "lowdelay" | "throughput" | "reliability" |
|
||||
[ "0x" ] number )
|
||||
|
||||
state-opts = state-opt [ [ "," ] state-opts ]
|
||||
state-opt = ( "max" number | "no-sync" | timeout |
|
||||
state-opt = ( "max" number | "no-sync" | timeout | sloppy |
|
||||
"source-track" [ ( "rule" | "global" ) ] |
|
||||
"max-src-nodes" number | "max-src-states" number |
|
||||
"max-src-conn" number |
|
||||
@ -2962,6 +3004,7 @@ realtime-sc = "realtime" sc-spec
|
||||
upperlimit-sc = "upperlimit" sc-spec
|
||||
sc-spec = ( bandwidth-spec |
|
||||
"(" bandwidth-spec number bandwidth-spec ")" )
|
||||
include = "include" filename
|
||||
.Ed
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/etc/protocols" -compact
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pfsync.4,v 1.26 2007/09/20 20:50:07 mpf Exp $
|
||||
.\" $OpenBSD: pfsync.4,v 1.27 2008/06/03 19:51:02 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2002 Michael Shalayeff
|
||||
.\" Copyright (c) 2003-2004 Ryan McBride
|
||||
@ -24,7 +24,7 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 31 2007 $
|
||||
.Dd $Mdocdate: September 20 2007 $
|
||||
.Dt PFSYNC 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -121,7 +121,7 @@ e.g.:
|
||||
It is important that the pfsync traffic be well secured
|
||||
as there is no authentication on the protocol and it would
|
||||
be trivial to spoof packets which create states, bypassing the pf ruleset.
|
||||
Either run the pfsync protocol on a trusted network \- ideally a network
|
||||
Either run the pfsync protocol on a trusted network \- ideally a network
|
||||
dedicated to pfsync messages such as a crossover cable between two firewalls,
|
||||
or specify a peer address and protect the traffic with
|
||||
.Xr ipsec 4 .
|
||||
|
505
pfctl/parse.y
505
pfctl/parse.y
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: parse.y,v 1.536 2008/02/01 06:58:45 mcbride Exp $ */
|
||||
/* $OpenBSD: parse.y,v 1.549 2008/07/03 16:09:34 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Markus Friedl. All rights reserved.
|
||||
@ -153,7 +153,7 @@ enum { PF_STATE_OPT_MAX, PF_STATE_OPT_NOSYNC, PF_STATE_OPT_SRCTRACK,
|
||||
PF_STATE_OPT_MAX_SRC_STATES, PF_STATE_OPT_MAX_SRC_CONN,
|
||||
PF_STATE_OPT_MAX_SRC_CONN_RATE, PF_STATE_OPT_MAX_SRC_NODES,
|
||||
PF_STATE_OPT_OVERLOAD, PF_STATE_OPT_STATELOCK,
|
||||
PF_STATE_OPT_TIMEOUT };
|
||||
PF_STATE_OPT_TIMEOUT, PF_STATE_OPT_SLOPPY };
|
||||
|
||||
enum { PF_SRCTRACK_NONE, PF_SRCTRACK, PF_SRCTRACK_GLOBAL, PF_SRCTRACK_RULE };
|
||||
|
||||
@ -232,6 +232,10 @@ struct filter_opts {
|
||||
char *match_tag;
|
||||
u_int8_t match_tag_not;
|
||||
u_int rtableid;
|
||||
struct {
|
||||
struct node_host *addr;
|
||||
u_int16_t port;
|
||||
} divert;
|
||||
} filter_opts;
|
||||
|
||||
struct antispoof_opts {
|
||||
@ -244,12 +248,16 @@ struct scrub_opts {
|
||||
#define SOM_MINTTL 0x01
|
||||
#define SOM_MAXMSS 0x02
|
||||
#define SOM_FRAGCACHE 0x04
|
||||
#define SOM_SETTOS 0x08
|
||||
int nodf;
|
||||
int minttl;
|
||||
int maxmss;
|
||||
int settos;
|
||||
int fragcache;
|
||||
int randomid;
|
||||
int reassemble_tcp;
|
||||
char *match_tag;
|
||||
u_int8_t match_tag_not;
|
||||
u_int rtableid;
|
||||
} scrub_opts;
|
||||
|
||||
@ -410,6 +418,10 @@ typedef struct {
|
||||
int lineno;
|
||||
} YYSTYPE;
|
||||
|
||||
#define PPORT_RANGE 1
|
||||
#define PPORT_STAR 2
|
||||
int parseport(char *, struct range *r, int);
|
||||
|
||||
#define DYNIF_MULTIADDR(addr) ((addr).type == PF_ADDR_DYNIFTL && \
|
||||
(!((addr).iflags & PFI_AFLAG_NOALIAS) || \
|
||||
!isdigit((addr).v.ifname[strlen((addr).v.ifname)-1])))
|
||||
@ -430,8 +442,9 @@ typedef struct {
|
||||
%token QUEUE PRIORITY QLIMIT RTABLE
|
||||
%token LOAD RULESET_OPTIMIZATION
|
||||
%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
|
||||
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH
|
||||
%token TAGGED TAG IFBOUND FLOATING STATEPOLICY ROUTE
|
||||
%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY
|
||||
%token TAGGED TAG IFBOUND FLOATING STATEPOLICY ROUTE SETTOS
|
||||
%token DIVERTTO DIVERTREPLY
|
||||
%token <v.string> STRING
|
||||
%token <v.number> NUMBER
|
||||
%token <v.i> PORTBINARY
|
||||
@ -443,7 +456,7 @@ typedef struct {
|
||||
%type <v.i> sourcetrack flush unaryop statelock
|
||||
%type <v.b> action nataction natpasslog scrubaction
|
||||
%type <v.b> flags flag blockspec
|
||||
%type <v.range> port rport
|
||||
%type <v.range> portplain portstar portrange
|
||||
%type <v.hashkey> hashkey
|
||||
%type <v.proto> proto proto_list proto_item
|
||||
%type <v.number> protoval
|
||||
@ -453,7 +466,7 @@ typedef struct {
|
||||
%type <v.number> reticmpspec reticmp6spec
|
||||
%type <v.fromto> fromto
|
||||
%type <v.peer> ipportspec from to
|
||||
%type <v.host> ipspec xhost host dynaddr host_list
|
||||
%type <v.host> ipspec toipspec xhost host dynaddr host_list
|
||||
%type <v.host> redir_host_list redirspec
|
||||
%type <v.host> route_host route_host_list routespec
|
||||
%type <v.os> os xos os_list
|
||||
@ -462,7 +475,8 @@ typedef struct {
|
||||
%type <v.gid> gids gid_list gid_item
|
||||
%type <v.route> route
|
||||
%type <v.redirection> redirection redirpool
|
||||
%type <v.string> label string stringall tag anchorname
|
||||
%type <v.string> label stringall tag anchorname
|
||||
%type <v.string> string varstring numberstring
|
||||
%type <v.keep_state> keep
|
||||
%type <v.state_opt> state_opt_spec state_opt_list state_opt_item
|
||||
%type <v.logquick> logquick quick log logopts logopt
|
||||
@ -563,9 +577,9 @@ option : SET OPTIMIZATION STRING {
|
||||
}
|
||||
}
|
||||
| SET TIMEOUT timeout_spec
|
||||
| SET TIMEOUT '{' timeout_list '}'
|
||||
| SET TIMEOUT '{' optnl timeout_list '}'
|
||||
| SET LIMIT limit_spec
|
||||
| SET LIMIT '{' limit_list '}'
|
||||
| SET LIMIT '{' optnl limit_list '}'
|
||||
| SET LOGINTERFACE stringall {
|
||||
if (check_rulestate(PFCTL_STATE_OPTION)) {
|
||||
free($3);
|
||||
@ -666,7 +680,7 @@ stringall : STRING { $$ = $1; }
|
||||
}
|
||||
;
|
||||
|
||||
string : string STRING {
|
||||
string : STRING string {
|
||||
if (asprintf(&$$, "%s %s", $1, $2) == -1)
|
||||
err(1, "string: asprintf");
|
||||
free($1);
|
||||
@ -675,7 +689,27 @@ string : string STRING {
|
||||
| STRING
|
||||
;
|
||||
|
||||
varset : STRING '=' string {
|
||||
varstring : numberstring varstring {
|
||||
if (asprintf(&$$, "%s %s", $1, $2) == -1)
|
||||
err(1, "string: asprintf");
|
||||
free($1);
|
||||
free($2);
|
||||
}
|
||||
| numberstring
|
||||
;
|
||||
|
||||
numberstring : NUMBER {
|
||||
char *s;
|
||||
if (asprintf(&s, "%lld", $1) == -1) {
|
||||
yyerror("string: asprintf");
|
||||
YYERROR;
|
||||
}
|
||||
$$ = s;
|
||||
}
|
||||
| STRING
|
||||
;
|
||||
|
||||
varset : STRING '=' varstring {
|
||||
if (pf->opts & PF_OPT_VERBOSE)
|
||||
printf("%s = \"%s\"\n", $1, $3);
|
||||
if (symset($1, $3, 0) == -1)
|
||||
@ -683,33 +717,16 @@ varset : STRING '=' string {
|
||||
free($1);
|
||||
free($3);
|
||||
}
|
||||
| STRING '=' NUMBER {
|
||||
char *s;
|
||||
if (asprintf(&s, "%lld", $3) == -1) {
|
||||
yyerror("string: asprintf");
|
||||
YYERROR;
|
||||
}
|
||||
if (pf->opts & PF_OPT_VERBOSE)
|
||||
printf("%s = \"%s\"\n", $1, s);
|
||||
if (symset($1, s, 0) == -1)
|
||||
err(1, "cannot store variable %s", $1);
|
||||
free($1);
|
||||
free(s);
|
||||
}
|
||||
;
|
||||
|
||||
anchorname : STRING { $$ = $1; }
|
||||
| /* empty */ { $$ = NULL; }
|
||||
;
|
||||
|
||||
optnl : optnl '\n'
|
||||
|
|
||||
;
|
||||
|
||||
pfa_anchorlist : pfrule optnl
|
||||
| anchorrule optnl
|
||||
| pfa_anchorlist pfrule optnl
|
||||
| pfa_anchorlist anchorrule optnl
|
||||
pfa_anchorlist : /* empty */
|
||||
| pfa_anchorlist '\n'
|
||||
| pfa_anchorlist pfrule '\n'
|
||||
| pfa_anchorlist anchorrule '\n'
|
||||
;
|
||||
|
||||
pfa_anchor : '{'
|
||||
@ -1037,8 +1054,20 @@ scrubrule : scrubaction dir logquick interface af proto fromto scrub_opts
|
||||
r.min_ttl = $8.minttl;
|
||||
if ($8.maxmss)
|
||||
r.max_mss = $8.maxmss;
|
||||
if ($8.marker & SOM_SETTOS) {
|
||||
r.rule_flag |= PFRULE_SET_TOS;
|
||||
r.set_tos = $8.settos;
|
||||
}
|
||||
if ($8.fragcache)
|
||||
r.rule_flag |= $8.fragcache;
|
||||
if ($8.match_tag)
|
||||
if (strlcpy(r.match_tagname, $8.match_tag,
|
||||
PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
|
||||
yyerror("tag too long, max %u chars",
|
||||
PF_TAG_NAME_SIZE - 1);
|
||||
YYERROR;
|
||||
}
|
||||
r.match_tag_not = $8.match_tag_not;
|
||||
r.rtableid = $8.rtableid;
|
||||
|
||||
expand_rule(&r, $4, NULL, $6, $7.src_os,
|
||||
@ -1095,6 +1124,14 @@ scrub_opt : NODF {
|
||||
scrub_opts.marker |= SOM_MAXMSS;
|
||||
scrub_opts.maxmss = $2;
|
||||
}
|
||||
| SETTOS tos {
|
||||
if (scrub_opts.marker & SOM_SETTOS) {
|
||||
yyerror("set-tos cannot be respecified");
|
||||
YYERROR;
|
||||
}
|
||||
scrub_opts.marker |= SOM_SETTOS;
|
||||
scrub_opts.settos = $2;
|
||||
}
|
||||
| fragcache {
|
||||
if (scrub_opts.marker & SOM_FRAGCACHE) {
|
||||
yyerror("fragcache cannot be respecified");
|
||||
@ -1131,6 +1168,10 @@ scrub_opt : NODF {
|
||||
}
|
||||
scrub_opts.rtableid = $2;
|
||||
}
|
||||
| not TAGGED string {
|
||||
scrub_opts.match_tag = $3;
|
||||
scrub_opts.match_tag_not = $1;
|
||||
}
|
||||
;
|
||||
|
||||
fragcache : FRAGMENT REASSEMBLE { $$ = 0; /* default */ }
|
||||
@ -1225,11 +1266,11 @@ antispoof : ANTISPOOF logquick antispoof_ifspc af antispoof_opts {
|
||||
;
|
||||
|
||||
antispoof_ifspc : FOR antispoof_if { $$ = $2; }
|
||||
| FOR '{' antispoof_iflst '}' { $$ = $3; }
|
||||
| FOR '{' optnl antispoof_iflst '}' { $$ = $4; }
|
||||
;
|
||||
|
||||
antispoof_iflst : antispoof_if { $$ = $1; }
|
||||
| antispoof_iflst comma antispoof_if {
|
||||
antispoof_iflst : antispoof_if optnl { $$ = $1; }
|
||||
| antispoof_iflst comma antispoof_if optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3;
|
||||
$$ = $1;
|
||||
@ -1333,6 +1374,8 @@ table_opt : STRING {
|
||||
table_opts.flags |= PFR_TFLAG_CONST;
|
||||
else if (!strcmp($1, "persist"))
|
||||
table_opts.flags |= PFR_TFLAG_PERSIST;
|
||||
else if (!strcmp($1, "counters"))
|
||||
table_opts.flags |= PFR_TFLAG_COUNTERS;
|
||||
else {
|
||||
yyerror("invalid table option '%s'", $1);
|
||||
free($1);
|
||||
@ -1340,12 +1383,12 @@ table_opt : STRING {
|
||||
}
|
||||
free($1);
|
||||
}
|
||||
| '{' '}' { table_opts.init_addr = 1; }
|
||||
| '{' host_list '}' {
|
||||
| '{' optnl '}' { table_opts.init_addr = 1; }
|
||||
| '{' optnl host_list '}' {
|
||||
struct node_host *n;
|
||||
struct node_tinit *ti;
|
||||
|
||||
for (n = $2; n != NULL; n = n->next) {
|
||||
for (n = $3; n != NULL; n = n->next) {
|
||||
switch (n->addr.type) {
|
||||
case PF_ADDR_ADDRMASK:
|
||||
continue; /* ok */
|
||||
@ -1376,7 +1419,7 @@ table_opt : STRING {
|
||||
}
|
||||
if (!(ti = calloc(1, sizeof(*ti))))
|
||||
err(1, "table_opt: calloc");
|
||||
ti->host = $2;
|
||||
ti->host = $3;
|
||||
SIMPLEQ_INSERT_TAIL(&table_opts.init_nodes, ti,
|
||||
entries);
|
||||
table_opts.init_addr = 1;
|
||||
@ -1750,11 +1793,11 @@ hfscopts_item : LINKSHARE bandwidth {
|
||||
|
||||
qassign : /* empty */ { $$ = NULL; }
|
||||
| qassign_item { $$ = $1; }
|
||||
| '{' qassign_list '}' { $$ = $2; }
|
||||
| '{' optnl qassign_list '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
qassign_list : qassign_item { $$ = $1; }
|
||||
| qassign_list comma qassign_item {
|
||||
qassign_list : qassign_item optnl { $$ = $1; }
|
||||
| qassign_list comma qassign_item optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3;
|
||||
$$ = $1;
|
||||
@ -2009,6 +2052,14 @@ pfrule : action dir logquick interface route af proto fromto
|
||||
statelock = 1;
|
||||
r.rule_flag |= o->data.statelock;
|
||||
break;
|
||||
case PF_STATE_OPT_SLOPPY:
|
||||
if (r.rule_flag & PFRULE_STATESLOPPY) {
|
||||
yyerror("state sloppy option: "
|
||||
"multiple definitions");
|
||||
YYERROR;
|
||||
}
|
||||
r.rule_flag |= PFRULE_STATESLOPPY;
|
||||
break;
|
||||
case PF_STATE_OPT_TIMEOUT:
|
||||
if (o->data.timeout.number ==
|
||||
PFTM_ADAPTIVE_START ||
|
||||
@ -2145,6 +2196,30 @@ pfrule : action dir logquick interface route af proto fromto
|
||||
}
|
||||
free($9.queues.pqname);
|
||||
}
|
||||
if ((r.divert.port = $9.divert.port)) {
|
||||
if (r.direction == PF_OUT) {
|
||||
if ($9.divert.addr) {
|
||||
yyerror("address specified "
|
||||
"for outgoing divert");
|
||||
YYERROR;
|
||||
}
|
||||
bzero(&r.divert.addr,
|
||||
sizeof(r.divert.addr));
|
||||
} else {
|
||||
if (!$9.divert.addr) {
|
||||
yyerror("no address specified "
|
||||
"for incoming divert");
|
||||
YYERROR;
|
||||
}
|
||||
if ($9.divert.addr->af != r.af) {
|
||||
yyerror("address family "
|
||||
"mismatch for divert");
|
||||
YYERROR;
|
||||
}
|
||||
r.divert.addr =
|
||||
$9.divert.addr->addr.v.a.addr;
|
||||
}
|
||||
}
|
||||
|
||||
expand_rule(&r, $4, $5.host, $7, $8.src_os,
|
||||
$8.src.host, $8.src.port, $8.dst.host, $8.dst.port,
|
||||
@ -2198,13 +2273,13 @@ filter_opt : USER uids {
|
||||
filter_opts.marker |= FOM_ICMP;
|
||||
filter_opts.icmpspec = $1;
|
||||
}
|
||||
| tos {
|
||||
| TOS tos {
|
||||
if (filter_opts.marker & FOM_TOS) {
|
||||
yyerror("tos cannot be redefined");
|
||||
YYERROR;
|
||||
}
|
||||
filter_opts.marker |= FOM_TOS;
|
||||
filter_opts.tos = $1;
|
||||
filter_opts.tos = $2;
|
||||
}
|
||||
| keep {
|
||||
if (filter_opts.marker & FOM_KEEP) {
|
||||
@ -2261,6 +2336,23 @@ filter_opt : USER uids {
|
||||
}
|
||||
filter_opts.rtableid = $2;
|
||||
}
|
||||
| DIVERTTO STRING PORT portplain {
|
||||
if ((filter_opts.divert.addr = host($2)) == NULL) {
|
||||
yyerror("could not parse divert address: %s",
|
||||
$2);
|
||||
free($2);
|
||||
YYERROR;
|
||||
}
|
||||
free($2);
|
||||
filter_opts.divert.port = $4.a;
|
||||
if (!filter_opts.divert.port) {
|
||||
yyerror("invalid divert port: %u", ntohs($4.a));
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
| DIVERTREPLY {
|
||||
filter_opts.divert.port = 1; /* some random value */
|
||||
}
|
||||
;
|
||||
|
||||
probability : STRING {
|
||||
@ -2383,7 +2475,7 @@ reticmp6spec : STRING {
|
||||
}
|
||||
;
|
||||
|
||||
dir : /* empty */ { $$ = 0; }
|
||||
dir : /* empty */ { $$ = PF_INOUT; }
|
||||
| IN { $$ = PF_IN; }
|
||||
| OUT { $$ = PF_OUT; }
|
||||
;
|
||||
@ -2441,11 +2533,11 @@ logopt : ALL { $$.log = PF_LOG_ALL; $$.logif = 0; }
|
||||
|
||||
interface : /* empty */ { $$ = NULL; }
|
||||
| ON if_item_not { $$ = $2; }
|
||||
| ON '{' if_list '}' { $$ = $3; }
|
||||
| ON '{' optnl if_list '}' { $$ = $4; }
|
||||
;
|
||||
|
||||
if_list : if_item_not { $$ = $1; }
|
||||
| if_list comma if_item_not {
|
||||
if_list : if_item_not optnl { $$ = $1; }
|
||||
| if_list comma if_item_not optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3;
|
||||
$$ = $1;
|
||||
@ -2484,13 +2576,13 @@ af : /* empty */ { $$ = 0; }
|
||||
| INET6 { $$ = AF_INET6; }
|
||||
;
|
||||
|
||||
proto : /* empty */ { $$ = NULL; }
|
||||
| PROTO proto_item { $$ = $2; }
|
||||
| PROTO '{' proto_list '}' { $$ = $3; }
|
||||
proto : /* empty */ { $$ = NULL; }
|
||||
| PROTO proto_item { $$ = $2; }
|
||||
| PROTO '{' optnl proto_list '}' { $$ = $4; }
|
||||
;
|
||||
|
||||
proto_list : proto_item { $$ = $1; }
|
||||
| proto_list comma proto_item {
|
||||
proto_list : proto_item optnl { $$ = $1; }
|
||||
| proto_list comma proto_item optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3;
|
||||
$$ = $1;
|
||||
@ -2550,7 +2642,7 @@ fromto : ALL {
|
||||
|
||||
os : /* empty */ { $$ = NULL; }
|
||||
| OS xos { $$ = $2; }
|
||||
| OS '{' os_list '}' { $$ = $3; }
|
||||
| OS '{' optnl os_list '}' { $$ = $4; }
|
||||
;
|
||||
|
||||
xos : STRING {
|
||||
@ -2562,8 +2654,8 @@ xos : STRING {
|
||||
}
|
||||
;
|
||||
|
||||
os_list : xos { $$ = $1; }
|
||||
| os_list comma xos {
|
||||
os_list : xos optnl { $$ = $1; }
|
||||
| os_list comma xos optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3;
|
||||
$$ = $1;
|
||||
@ -2605,13 +2697,21 @@ ipportspec : ipspec {
|
||||
}
|
||||
;
|
||||
|
||||
ipspec : ANY { $$ = NULL; }
|
||||
| xhost { $$ = $1; }
|
||||
| '{' host_list '}' { $$ = $2; }
|
||||
optnl : '\n' optnl
|
||||
|
|
||||
;
|
||||
|
||||
host_list : ipspec { $$ = $1; }
|
||||
| host_list comma ipspec {
|
||||
ipspec : ANY { $$ = NULL; }
|
||||
| xhost { $$ = $1; }
|
||||
| '{' optnl host_list '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
toipspec : TO ipspec { $$ = $2; }
|
||||
| /* empty */ { $$ = NULL; }
|
||||
;
|
||||
|
||||
host_list : ipspec optnl { $$ = $1; }
|
||||
| host_list comma ipspec optnl {
|
||||
if ($3 == NULL)
|
||||
$$ = $1;
|
||||
else if ($1 == NULL)
|
||||
@ -2843,18 +2943,18 @@ dynaddr : '(' STRING ')' {
|
||||
;
|
||||
|
||||
portspec : port_item { $$ = $1; }
|
||||
| '{' port_list '}' { $$ = $2; }
|
||||
| '{' optnl port_list '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
port_list : port_item { $$ = $1; }
|
||||
| port_list comma port_item {
|
||||
port_list : port_item optnl { $$ = $1; }
|
||||
| port_list comma port_item optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3;
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
port_item : port {
|
||||
port_item : portrange {
|
||||
$$ = calloc(1, sizeof(struct node_port));
|
||||
if ($$ == NULL)
|
||||
err(1, "port_item: calloc");
|
||||
@ -2867,7 +2967,7 @@ port_item : port {
|
||||
$$->next = NULL;
|
||||
$$->tail = $$;
|
||||
}
|
||||
| unaryop port {
|
||||
| unaryop portrange {
|
||||
if ($2.t) {
|
||||
yyerror("':' cannot be used with an other "
|
||||
"port operator");
|
||||
@ -2882,7 +2982,7 @@ port_item : port {
|
||||
$$->next = NULL;
|
||||
$$->tail = $$;
|
||||
}
|
||||
| port PORTBINARY port {
|
||||
| portrange PORTBINARY portrange {
|
||||
if ($1.t || $3.t) {
|
||||
yyerror("':' cannot be used with an other "
|
||||
"port operator");
|
||||
@ -2899,46 +2999,30 @@ port_item : port {
|
||||
}
|
||||
;
|
||||
|
||||
port : STRING {
|
||||
char *p = strchr($1, ':');
|
||||
|
||||
if (p == NULL) {
|
||||
if (($$.a = getservice($1)) == -1) {
|
||||
free($1);
|
||||
YYERROR;
|
||||
}
|
||||
$$.b = $$.t = 0;
|
||||
} else {
|
||||
int port[2];
|
||||
|
||||
*p++ = 0;
|
||||
if ((port[0] = getservice($1)) == -1 ||
|
||||
(port[1] = getservice(p)) == -1) {
|
||||
free($1);
|
||||
YYERROR;
|
||||
}
|
||||
$$.a = port[0];
|
||||
$$.b = port[1];
|
||||
$$.t = PF_OP_RRG;
|
||||
portplain : numberstring {
|
||||
if (parseport($1, &$$, 0) == -1) {
|
||||
free($1);
|
||||
YYERROR;
|
||||
}
|
||||
free($1);
|
||||
}
|
||||
| NUMBER {
|
||||
if ($1 < 0 || $1 > 65535) {
|
||||
yyerror("illegal port value %lu", $1);
|
||||
;
|
||||
|
||||
portrange : numberstring {
|
||||
if (parseport($1, &$$, PPORT_RANGE) == -1) {
|
||||
free($1);
|
||||
YYERROR;
|
||||
}
|
||||
$$.a = ntohs($1);
|
||||
$$.b = $$.t = 0;
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
uids : uid_item { $$ = $1; }
|
||||
| '{' uid_list '}' { $$ = $2; }
|
||||
| '{' optnl uid_list '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
uid_list : uid_item { $$ = $1; }
|
||||
| uid_list comma uid_item {
|
||||
uid_list : uid_item optnl { $$ = $1; }
|
||||
| uid_list comma uid_item optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3;
|
||||
$$ = $1;
|
||||
@ -3012,11 +3096,11 @@ uid : STRING {
|
||||
;
|
||||
|
||||
gids : gid_item { $$ = $1; }
|
||||
| '{' gid_list '}' { $$ = $2; }
|
||||
| '{' optnl gid_list '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
gid_list : gid_item { $$ = $1; }
|
||||
| gid_list comma gid_item {
|
||||
gid_list : gid_item optnl { $$ = $1; }
|
||||
| gid_list comma gid_item optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3;
|
||||
$$ = $1;
|
||||
@ -3107,22 +3191,22 @@ flags : FLAGS flag '/' flag { $$.b1 = $2.b1; $$.b2 = $4.b1; }
|
||||
| FLAGS ANY { $$.b1 = 0; $$.b2 = 0; }
|
||||
;
|
||||
|
||||
icmpspec : ICMPTYPE icmp_item { $$ = $2; }
|
||||
| ICMPTYPE '{' icmp_list '}' { $$ = $3; }
|
||||
| ICMP6TYPE icmp6_item { $$ = $2; }
|
||||
| ICMP6TYPE '{' icmp6_list '}' { $$ = $3; }
|
||||
icmpspec : ICMPTYPE icmp_item { $$ = $2; }
|
||||
| ICMPTYPE '{' optnl icmp_list '}' { $$ = $4; }
|
||||
| ICMP6TYPE icmp6_item { $$ = $2; }
|
||||
| ICMP6TYPE '{' optnl icmp6_list '}' { $$ = $4; }
|
||||
;
|
||||
|
||||
icmp_list : icmp_item { $$ = $1; }
|
||||
| icmp_list comma icmp_item {
|
||||
icmp_list : icmp_item optnl { $$ = $1; }
|
||||
| icmp_list comma icmp_item optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3;
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
icmp6_list : icmp6_item { $$ = $1; }
|
||||
| icmp6_list comma icmp6_item {
|
||||
icmp6_list : icmp6_item optnl { $$ = $1; }
|
||||
| icmp6_list comma icmp6_item optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3;
|
||||
$$ = $1;
|
||||
@ -3260,28 +3344,28 @@ icmp6type : STRING {
|
||||
}
|
||||
;
|
||||
|
||||
tos : TOS STRING {
|
||||
if (!strcmp($2, "lowdelay"))
|
||||
tos : STRING {
|
||||
if (!strcmp($1, "lowdelay"))
|
||||
$$ = IPTOS_LOWDELAY;
|
||||
else if (!strcmp($2, "throughput"))
|
||||
else if (!strcmp($1, "throughput"))
|
||||
$$ = IPTOS_THROUGHPUT;
|
||||
else if (!strcmp($2, "reliability"))
|
||||
else if (!strcmp($1, "reliability"))
|
||||
$$ = IPTOS_RELIABILITY;
|
||||
else if ($2[0] == '0' && $2[1] == 'x')
|
||||
$$ = strtoul($2, NULL, 16);
|
||||
else if ($1[0] == '0' && $1[1] == 'x')
|
||||
$$ = strtoul($1, NULL, 16);
|
||||
else
|
||||
$$ = 0; /* flag bad argument */
|
||||
if (!$$ || $$ > 255) {
|
||||
yyerror("illegal tos value %s", $2);
|
||||
free($2);
|
||||
yyerror("illegal tos value %s", $1);
|
||||
free($1);
|
||||
YYERROR;
|
||||
}
|
||||
free($2);
|
||||
free($1);
|
||||
}
|
||||
| TOS NUMBER {
|
||||
$$ = $2;
|
||||
| NUMBER {
|
||||
$$ = $1;
|
||||
if (!$$ || $$ > 255) {
|
||||
yyerror("illegal tos value %s", $2);
|
||||
yyerror("illegal tos value %s", $1);
|
||||
YYERROR;
|
||||
}
|
||||
}
|
||||
@ -3448,6 +3532,14 @@ state_opt_item : MAXIMUM NUMBER {
|
||||
$$->next = NULL;
|
||||
$$->tail = $$;
|
||||
}
|
||||
| SLOPPY {
|
||||
$$ = calloc(1, sizeof(struct node_state_opt));
|
||||
if ($$ == NULL)
|
||||
err(1, "state_opt_item: calloc");
|
||||
$$->type = PF_STATE_OPT_SLOPPY;
|
||||
$$->next = NULL;
|
||||
$$->tail = $$;
|
||||
}
|
||||
| STRING NUMBER {
|
||||
int i;
|
||||
|
||||
@ -3487,9 +3579,11 @@ label : LABEL STRING {
|
||||
|
||||
qname : QUEUE STRING {
|
||||
$$.qname = $2;
|
||||
$$.pqname = NULL;
|
||||
}
|
||||
| QUEUE '(' STRING ')' {
|
||||
$$.qname = $3;
|
||||
$$.pqname = NULL;
|
||||
}
|
||||
| QUEUE '(' STRING comma STRING ')' {
|
||||
$$.qname = $3;
|
||||
@ -3501,52 +3595,21 @@ no : /* empty */ { $$ = 0; }
|
||||
| NO { $$ = 1; }
|
||||
;
|
||||
|
||||
rport : STRING {
|
||||
char *p = strchr($1, ':');
|
||||
|
||||
if (p == NULL) {
|
||||
if (($$.a = getservice($1)) == -1) {
|
||||
free($1);
|
||||
YYERROR;
|
||||
}
|
||||
$$.b = $$.t = 0;
|
||||
} else if (!strcmp(p+1, "*")) {
|
||||
*p = 0;
|
||||
if (($$.a = getservice($1)) == -1) {
|
||||
free($1);
|
||||
YYERROR;
|
||||
}
|
||||
$$.b = 0;
|
||||
$$.t = 1;
|
||||
} else {
|
||||
*p++ = 0;
|
||||
if (($$.a = getservice($1)) == -1 ||
|
||||
($$.b = getservice(p)) == -1) {
|
||||
free($1);
|
||||
YYERROR;
|
||||
}
|
||||
if ($$.a == $$.b)
|
||||
$$.b = 0;
|
||||
$$.t = 0;
|
||||
}
|
||||
free($1);
|
||||
}
|
||||
| NUMBER {
|
||||
if ($1 < 0 || $1 > 65535) {
|
||||
yyerror("illegal port value %ld", $1);
|
||||
portstar : numberstring {
|
||||
if (parseport($1, &$$, PPORT_RANGE|PPORT_STAR) == -1) {
|
||||
free($1);
|
||||
YYERROR;
|
||||
}
|
||||
$$.a = ntohs($1);
|
||||
$$.b = $$.t = 0;
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
redirspec : host { $$ = $1; }
|
||||
| '{' redir_host_list '}' { $$ = $2; }
|
||||
| '{' optnl redir_host_list '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
redir_host_list : host { $$ = $1; }
|
||||
| redir_host_list comma host {
|
||||
redir_host_list : host optnl { $$ = $1; }
|
||||
| redir_host_list comma host optnl {
|
||||
$1->tail->next = $3;
|
||||
$1->tail = $3->tail;
|
||||
$$ = $1;
|
||||
@ -3561,7 +3624,7 @@ redirpool : /* empty */ { $$ = NULL; }
|
||||
$$->host = $2;
|
||||
$$->rport.a = $$->rport.b = $$->rport.t = 0;
|
||||
}
|
||||
| ARROW redirspec PORT rport {
|
||||
| ARROW redirspec PORT portstar {
|
||||
$$ = calloc(1, sizeof(struct redirection));
|
||||
if ($$ == NULL)
|
||||
err(1, "redirection: calloc");
|
||||
@ -3687,7 +3750,7 @@ redirection : /* empty */ { $$ = NULL; }
|
||||
$$->host = $2;
|
||||
$$->rport.a = $$->rport.b = $$->rport.t = 0;
|
||||
}
|
||||
| ARROW host PORT rport {
|
||||
| ARROW host PORT portstar {
|
||||
$$ = calloc(1, sizeof(struct redirection));
|
||||
if ($$ == NULL)
|
||||
err(1, "redirection: calloc");
|
||||
@ -3889,7 +3952,7 @@ natrule : nataction interface af proto fromto tag tagged rtable
|
||||
}
|
||||
;
|
||||
|
||||
binatrule : no BINAT natpasslog interface af proto FROM host TO ipspec tag
|
||||
binatrule : no BINAT natpasslog interface af proto FROM host toipspec tag
|
||||
tagged rtable redirection
|
||||
{
|
||||
struct pf_rule binat;
|
||||
@ -3897,7 +3960,7 @@ binatrule : no BINAT natpasslog interface af proto FROM host TO ipspec tag
|
||||
|
||||
if (check_rulestate(PFCTL_STATE_NAT))
|
||||
YYERROR;
|
||||
if (disallow_urpf_failed($10, "\"urpf-failed\" is not "
|
||||
if (disallow_urpf_failed($9, "\"urpf-failed\" is not "
|
||||
"permitted as a binat destination"))
|
||||
YYERROR;
|
||||
|
||||
@ -3917,11 +3980,11 @@ binatrule : no BINAT natpasslog interface af proto FROM host TO ipspec tag
|
||||
binat.af = $5;
|
||||
if (!binat.af && $8 != NULL && $8->af)
|
||||
binat.af = $8->af;
|
||||
if (!binat.af && $10 != NULL && $10->af)
|
||||
binat.af = $10->af;
|
||||
if (!binat.af && $9 != NULL && $9->af)
|
||||
binat.af = $9->af;
|
||||
|
||||
if (!binat.af && $14 != NULL && $14->host)
|
||||
binat.af = $14->host->af;
|
||||
if (!binat.af && $13 != NULL && $13->host)
|
||||
binat.af = $13->host->af;
|
||||
if (!binat.af) {
|
||||
yyerror("address family (inet/inet6) "
|
||||
"undefined");
|
||||
@ -3935,22 +3998,22 @@ binatrule : no BINAT natpasslog interface af proto FROM host TO ipspec tag
|
||||
free($4);
|
||||
}
|
||||
|
||||
if ($11 != NULL)
|
||||
if (strlcpy(binat.tagname, $11,
|
||||
if ($10 != NULL)
|
||||
if (strlcpy(binat.tagname, $10,
|
||||
PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
|
||||
yyerror("tag too long, max %u chars",
|
||||
PF_TAG_NAME_SIZE - 1);
|
||||
YYERROR;
|
||||
}
|
||||
if ($12.name)
|
||||
if (strlcpy(binat.match_tagname, $12.name,
|
||||
if ($11.name)
|
||||
if (strlcpy(binat.match_tagname, $11.name,
|
||||
PF_TAG_NAME_SIZE) >= PF_TAG_NAME_SIZE) {
|
||||
yyerror("tag too long, max %u chars",
|
||||
PF_TAG_NAME_SIZE - 1);
|
||||
YYERROR;
|
||||
}
|
||||
binat.match_tag_not = $12.neg;
|
||||
binat.rtableid = $13;
|
||||
binat.match_tag_not = $11.neg;
|
||||
binat.rtableid = $12;
|
||||
|
||||
if ($6 != NULL) {
|
||||
binat.proto = $6->proto;
|
||||
@ -3964,12 +4027,12 @@ binatrule : no BINAT natpasslog interface af proto FROM host TO ipspec tag
|
||||
"interface (%s) as the source address of a binat "
|
||||
"rule"))
|
||||
YYERROR;
|
||||
if ($14 != NULL && $14->host != NULL && disallow_table(
|
||||
$14->host, "invalid use of table <%s> as the "
|
||||
if ($13 != NULL && $13->host != NULL && disallow_table(
|
||||
$13->host, "invalid use of table <%s> as the "
|
||||
"redirect address of a binat rule"))
|
||||
YYERROR;
|
||||
if ($14 != NULL && $14->host != NULL && disallow_alias(
|
||||
$14->host, "invalid use of interface (%s) as the "
|
||||
if ($13 != NULL && $13->host != NULL && disallow_alias(
|
||||
$13->host, "invalid use of interface (%s) as the "
|
||||
"redirect address of a binat rule"))
|
||||
YYERROR;
|
||||
|
||||
@ -3990,51 +4053,51 @@ binatrule : no BINAT natpasslog interface af proto FROM host TO ipspec tag
|
||||
sizeof(binat.src.addr));
|
||||
free($8);
|
||||
}
|
||||
if ($10 != NULL) {
|
||||
if ($10->next) {
|
||||
if ($9 != NULL) {
|
||||
if ($9->next) {
|
||||
yyerror("multiple binat ip addresses");
|
||||
YYERROR;
|
||||
}
|
||||
if ($10->af != binat.af && $10->af) {
|
||||
if ($9->af != binat.af && $9->af) {
|
||||
yyerror("binat ip versions must match");
|
||||
YYERROR;
|
||||
}
|
||||
if (check_netmask($10, binat.af))
|
||||
if (check_netmask($9, binat.af))
|
||||
YYERROR;
|
||||
memcpy(&binat.dst.addr, &$10->addr,
|
||||
memcpy(&binat.dst.addr, &$9->addr,
|
||||
sizeof(binat.dst.addr));
|
||||
binat.dst.neg = $10->not;
|
||||
free($10);
|
||||
binat.dst.neg = $9->not;
|
||||
free($9);
|
||||
}
|
||||
|
||||
if (binat.action == PF_NOBINAT) {
|
||||
if ($14 != NULL) {
|
||||
if ($13 != NULL) {
|
||||
yyerror("'no binat' rule does not need"
|
||||
" '->'");
|
||||
YYERROR;
|
||||
}
|
||||
} else {
|
||||
if ($14 == NULL || $14->host == NULL) {
|
||||
if ($13 == NULL || $13->host == NULL) {
|
||||
yyerror("'binat' rule requires"
|
||||
" '-> address'");
|
||||
YYERROR;
|
||||
}
|
||||
|
||||
remove_invalid_hosts(&$14->host, &binat.af);
|
||||
if (invalid_redirect($14->host, binat.af))
|
||||
remove_invalid_hosts(&$13->host, &binat.af);
|
||||
if (invalid_redirect($13->host, binat.af))
|
||||
YYERROR;
|
||||
if ($14->host->next != NULL) {
|
||||
if ($13->host->next != NULL) {
|
||||
yyerror("binat rule must redirect to "
|
||||
"a single address");
|
||||
YYERROR;
|
||||
}
|
||||
if (check_netmask($14->host, binat.af))
|
||||
if (check_netmask($13->host, binat.af))
|
||||
YYERROR;
|
||||
|
||||
if (!PF_AZERO(&binat.src.addr.v.a.mask,
|
||||
binat.af) &&
|
||||
!PF_AEQ(&binat.src.addr.v.a.mask,
|
||||
&$14->host->addr.v.a.mask, binat.af)) {
|
||||
&$13->host->addr.v.a.mask, binat.af)) {
|
||||
yyerror("'binat' source mask and "
|
||||
"redirect mask must be the same");
|
||||
YYERROR;
|
||||
@ -4044,12 +4107,12 @@ binatrule : no BINAT natpasslog interface af proto FROM host TO ipspec tag
|
||||
pa = calloc(1, sizeof(struct pf_pooladdr));
|
||||
if (pa == NULL)
|
||||
err(1, "binat: calloc");
|
||||
pa->addr = $14->host->addr;
|
||||
pa->addr = $13->host->addr;
|
||||
pa->ifname[0] = 0;
|
||||
TAILQ_INSERT_TAIL(&binat.rpool.list,
|
||||
pa, entries);
|
||||
|
||||
free($14);
|
||||
free($13);
|
||||
}
|
||||
|
||||
pfctl_add_rule(pf, &binat, "");
|
||||
@ -4089,8 +4152,8 @@ route_host : STRING {
|
||||
}
|
||||
;
|
||||
|
||||
route_host_list : route_host { $$ = $1; }
|
||||
| route_host_list comma route_host {
|
||||
route_host_list : route_host optnl { $$ = $1; }
|
||||
| route_host_list comma route_host optnl {
|
||||
if ($1->af == 0)
|
||||
$1->af = $3->af;
|
||||
if ($1->af != $3->af) {
|
||||
@ -4105,7 +4168,7 @@ route_host_list : route_host { $$ = $1; }
|
||||
;
|
||||
|
||||
routespec : route_host { $$ = $1; }
|
||||
| '{' route_host_list '}' { $$ = $2; }
|
||||
| '{' optnl route_host_list '}' { $$ = $3; }
|
||||
;
|
||||
|
||||
route : /* empty */ {
|
||||
@ -4160,8 +4223,8 @@ timeout_spec : STRING NUMBER
|
||||
}
|
||||
;
|
||||
|
||||
timeout_list : timeout_list comma timeout_spec
|
||||
| timeout_spec
|
||||
timeout_list : timeout_list comma timeout_spec optnl
|
||||
| timeout_spec optnl
|
||||
;
|
||||
|
||||
limit_spec : STRING NUMBER
|
||||
@ -4183,8 +4246,8 @@ limit_spec : STRING NUMBER
|
||||
}
|
||||
;
|
||||
|
||||
limit_list : limit_list comma limit_spec
|
||||
| limit_spec
|
||||
limit_list : limit_list comma limit_spec optnl
|
||||
| limit_spec optnl
|
||||
;
|
||||
|
||||
comma : ','
|
||||
@ -4343,6 +4406,13 @@ filter_consistent(struct pf_rule *r, int anchor_call)
|
||||
yyerror("keep state on block rules doesn't make sense");
|
||||
problems++;
|
||||
}
|
||||
if (r->rule_flag & PFRULE_STATESLOPPY &&
|
||||
(r->keep_state == PF_STATE_MODULATE ||
|
||||
r->keep_state == PF_STATE_SYNPROXY)) {
|
||||
yyerror("sloppy state matching cannot be used with "
|
||||
"synproxy state or modulate state");
|
||||
problems++;
|
||||
}
|
||||
return (-problems);
|
||||
}
|
||||
|
||||
@ -5133,6 +5203,8 @@ lookup(char *s)
|
||||
{ "code", CODE},
|
||||
{ "crop", FRAGCROP},
|
||||
{ "debug", DEBUG},
|
||||
{ "divert-reply", DIVERTREPLY},
|
||||
{ "divert-to", DIVERTTO},
|
||||
{ "drop", DROP},
|
||||
{ "drop-ovl", FRAGDROP},
|
||||
{ "dup-to", DUPTO},
|
||||
@ -5211,7 +5283,9 @@ lookup(char *s)
|
||||
{ "ruleset-optimization", RULESET_OPTIMIZATION},
|
||||
{ "scrub", SCRUB},
|
||||
{ "set", SET},
|
||||
{ "set-tos", SETTOS},
|
||||
{ "skip", SKIP},
|
||||
{ "sloppy", SLOPPY},
|
||||
{ "source-hash", SOURCEHASH},
|
||||
{ "source-track", SOURCETRACK},
|
||||
{ "state", STATE},
|
||||
@ -5861,6 +5935,41 @@ parseicmpspec(char *w, sa_family_t af)
|
||||
return (icmptype << 8 | ulval);
|
||||
}
|
||||
|
||||
int
|
||||
parseport(char *port, struct range *r, int extensions)
|
||||
{
|
||||
char *p = strchr(port, ':');
|
||||
|
||||
if (p == NULL) {
|
||||
if ((r->a = getservice(port)) == -1)
|
||||
return (-1);
|
||||
r->b = 0;
|
||||
r->t = PF_OP_NONE;
|
||||
return (0);
|
||||
}
|
||||
if ((extensions & PPORT_STAR) && !strcmp(p+1, "*")) {
|
||||
*p = 0;
|
||||
if ((r->a = getservice(port)) == -1)
|
||||
return (-1);
|
||||
r->b = 0;
|
||||
r->t = PF_OP_IRG;
|
||||
return (0);
|
||||
}
|
||||
if ((extensions & PPORT_RANGE)) {
|
||||
*p++ = 0;
|
||||
if ((r->a = getservice(port)) == -1 ||
|
||||
(r->b = getservice(p)) == -1)
|
||||
return (-1);
|
||||
if (r->a == r->b) {
|
||||
r->b = 0;
|
||||
r->t = PF_OP_NONE;
|
||||
} else
|
||||
r->t = PF_OP_RRG;
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_load_anchors(int dev, struct pfctl *pf, struct pfr_buffer *trans)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pf_print_state.c,v 1.46 2007/08/30 09:28:49 dhartmei Exp $ */
|
||||
/* $OpenBSD: pf_print_state.c,v 1.51 2008/06/29 08:42:15 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -165,17 +165,15 @@ print_name(struct pf_addr *addr, sa_family_t af)
|
||||
}
|
||||
|
||||
void
|
||||
print_host(struct pfsync_state_host *h, sa_family_t af, int opts)
|
||||
print_host(struct pf_addr *addr, u_int16_t port, sa_family_t af, int opts)
|
||||
{
|
||||
u_int16_t p = ntohs(h->port);
|
||||
|
||||
if (opts & PF_OPT_USEDNS)
|
||||
print_name(&h->addr, af);
|
||||
print_name(addr, af);
|
||||
else {
|
||||
struct pf_addr_wrap aw;
|
||||
|
||||
memset(&aw, 0, sizeof(aw));
|
||||
aw.v.a.addr = h->addr;
|
||||
aw.v.a.addr = *addr;
|
||||
if (af == AF_INET)
|
||||
aw.v.a.mask.addr32[0] = 0xffffffff;
|
||||
else {
|
||||
@ -185,11 +183,11 @@ print_host(struct pfsync_state_host *h, sa_family_t af, int opts)
|
||||
print_addr(&aw, af, opts & PF_OPT_VERBOSE2);
|
||||
}
|
||||
|
||||
if (p) {
|
||||
if (port) {
|
||||
if (af == AF_INET)
|
||||
printf(":%u", p);
|
||||
printf(":%u", ntohs(port));
|
||||
else
|
||||
printf("[%u]", p);
|
||||
printf("[%u]", ntohs(port));
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,45 +195,60 @@ void
|
||||
print_seq(struct pfsync_state_peer *p)
|
||||
{
|
||||
if (p->seqdiff)
|
||||
printf("[%u + %u](+%u)", p->seqlo, p->seqhi - p->seqlo,
|
||||
p->seqdiff);
|
||||
printf("[%u + %u](+%u)", ntohl(p->seqlo),
|
||||
ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff));
|
||||
else
|
||||
printf("[%u + %u]", p->seqlo, p->seqhi - p->seqlo);
|
||||
printf("[%u + %u]", ntohl(p->seqlo),
|
||||
ntohl(p->seqhi) - ntohl(p->seqlo));
|
||||
}
|
||||
|
||||
void
|
||||
print_state(struct pfsync_state *s, int opts)
|
||||
{
|
||||
struct pfsync_state_peer *src, *dst;
|
||||
struct pfsync_state_key *sk, *nk;
|
||||
struct protoent *p;
|
||||
int min, sec;
|
||||
|
||||
if (s->direction == PF_OUT) {
|
||||
src = &s->src;
|
||||
dst = &s->dst;
|
||||
sk = &s->key[PF_SK_STACK];
|
||||
nk = &s->key[PF_SK_WIRE];
|
||||
if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
|
||||
sk->port[0] = nk->port[0];
|
||||
} else {
|
||||
src = &s->dst;
|
||||
dst = &s->src;
|
||||
sk = &s->key[PF_SK_WIRE];
|
||||
nk = &s->key[PF_SK_STACK];
|
||||
if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
|
||||
sk->port[1] = nk->port[1];
|
||||
}
|
||||
printf("%s ", s->ifname);
|
||||
if ((p = getprotobynumber(s->proto)) != NULL)
|
||||
printf("%s ", p->p_name);
|
||||
else
|
||||
printf("%u ", s->proto);
|
||||
if (PF_ANEQ(&s->lan.addr, &s->gwy.addr, s->af) ||
|
||||
(s->lan.port != s->gwy.port)) {
|
||||
print_host(&s->lan, s->af, opts);
|
||||
if (s->direction == PF_OUT)
|
||||
printf(" -> ");
|
||||
else
|
||||
printf(" <- ");
|
||||
|
||||
print_host(&nk->addr[1], nk->port[1], s->af, opts);
|
||||
if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) ||
|
||||
nk->port[1] != sk->port[1]) {
|
||||
printf(" (");
|
||||
print_host(&sk->addr[1], sk->port[1], s->af, opts);
|
||||
printf(")");
|
||||
}
|
||||
print_host(&s->gwy, s->af, opts);
|
||||
if (s->direction == PF_OUT)
|
||||
printf(" -> ");
|
||||
else
|
||||
printf(" <- ");
|
||||
print_host(&s->ext, s->af, opts);
|
||||
print_host(&nk->addr[0], nk->port[0], s->af, opts);
|
||||
if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) ||
|
||||
nk->port[0] != sk->port[0]) {
|
||||
printf(" (");
|
||||
print_host(&sk->addr[0], sk->port[0], s->af, opts);
|
||||
printf(")");
|
||||
}
|
||||
|
||||
printf(" ");
|
||||
if (s->proto == IPPROTO_TCP) {
|
||||
@ -281,25 +294,37 @@ print_state(struct pfsync_state *s, int opts)
|
||||
}
|
||||
|
||||
if (opts & PF_OPT_VERBOSE) {
|
||||
sec = s->creation % 60;
|
||||
s->creation /= 60;
|
||||
min = s->creation % 60;
|
||||
s->creation /= 60;
|
||||
printf(" age %.2u:%.2u:%.2u", s->creation, min, sec);
|
||||
sec = s->expire % 60;
|
||||
s->expire /= 60;
|
||||
u_int64_t packets[2];
|
||||
u_int64_t bytes[2];
|
||||
u_int32_t creation = ntohl(s->creation);
|
||||
u_int32_t expire = ntohl(s->expire);
|
||||
|
||||
sec = creation % 60;
|
||||
creation /= 60;
|
||||
min = creation % 60;
|
||||
creation /= 60;
|
||||
printf(" age %.2u:%.2u:%.2u", creation, min, sec);
|
||||
sec = expire % 60;
|
||||
expire /= 60;
|
||||
min = s->expire % 60;
|
||||
s->expire /= 60;
|
||||
printf(", expires in %.2u:%.2u:%.2u", s->expire, min, sec);
|
||||
expire /= 60;
|
||||
printf(", expires in %.2u:%.2u:%.2u", expire, min, sec);
|
||||
|
||||
bcopy(s->packets[0], &packets[0], sizeof(u_int64_t));
|
||||
bcopy(s->packets[1], &packets[1], sizeof(u_int64_t));
|
||||
bcopy(s->bytes[0], &bytes[0], sizeof(u_int64_t));
|
||||
bcopy(s->bytes[1], &bytes[1], sizeof(u_int64_t));
|
||||
printf(", %llu:%llu pkts, %llu:%llu bytes",
|
||||
pf_state_counter_from_pfsync(s->packets[0]),
|
||||
pf_state_counter_from_pfsync(s->packets[1]),
|
||||
pf_state_counter_from_pfsync(s->bytes[0]),
|
||||
pf_state_counter_from_pfsync(s->bytes[1]));
|
||||
if (s->anchor != -1)
|
||||
printf(", anchor %u", s->anchor);
|
||||
if (s->rule != -1)
|
||||
printf(", rule %u", s->rule);
|
||||
betoh64(packets[0]),
|
||||
betoh64(packets[1]),
|
||||
betoh64(bytes[0]),
|
||||
betoh64(bytes[1]));
|
||||
if (ntohl(s->anchor) != -1)
|
||||
printf(", anchor %u", ntohl(s->anchor));
|
||||
if (ntohl(s->rule) != -1)
|
||||
printf(", rule %u", ntohl(s->rule));
|
||||
if (s->state_flags & PFSTATE_SLOPPY)
|
||||
printf(", sloppy");
|
||||
if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
|
||||
printf(", source-track");
|
||||
if (s->sync_flags & PFSYNC_FLAG_NATSRCNODE)
|
||||
@ -307,9 +332,12 @@ print_state(struct pfsync_state *s, int opts)
|
||||
printf("\n");
|
||||
}
|
||||
if (opts & PF_OPT_VERBOSE2) {
|
||||
printf(" id: %016llx creatorid: %08x%s\n",
|
||||
pf_state_counter_from_pfsync(s->id), ntohl(s->creatorid),
|
||||
((s->sync_flags & PFSTATE_NOSYNC) ? " (no-sync)" : ""));
|
||||
u_int64_t id;
|
||||
|
||||
bcopy(&s->id, &id, sizeof(u_int64_t));
|
||||
printf(" id: %016llx creatorid: %08x",
|
||||
betoh64(id), ntohl(s->creatorid));
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $OpenBSD: pfctl.8,v 1.133 2007/07/01 11:38:51 henning Exp $
|
||||
.\" $OpenBSD: pfctl.8,v 1.139 2008/06/11 07:23:36 jmc Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2001 Kjell Wooding. All rights reserved.
|
||||
.\"
|
||||
@ -24,12 +24,12 @@
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd $Mdocdate: May 31 2007 $
|
||||
.Dd $Mdocdate: June 10 2008 $
|
||||
.Dt PFCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm pfctl
|
||||
.Nd "control the packet filter (PF) and network address translation (NAT) device"
|
||||
.Nd control the packet filter (PF) device
|
||||
.Sh SYNOPSIS
|
||||
.Nm pfctl
|
||||
.Bk -words
|
||||
@ -41,7 +41,10 @@
|
||||
.Op Fl f Ar file
|
||||
.Op Fl i Ar interface
|
||||
.Op Fl K Ar host | network
|
||||
.Op Fl k Ar host | network
|
||||
.Xo
|
||||
.Oo Fl k
|
||||
.Ar host | network | label | id
|
||||
.Oc Xc
|
||||
.Op Fl o Ar level
|
||||
.Op Fl p Ar device
|
||||
.Op Fl s Ar modifier
|
||||
@ -249,22 +252,28 @@ or
|
||||
.Fl K Ar network
|
||||
option may be specified, which will kill all the source tracking
|
||||
entries from the first host/network to the second.
|
||||
.It Fl k Ar host | network
|
||||
Kill all of the state entries originating from the specified
|
||||
.Ar host
|
||||
.It Xo
|
||||
.Fl k
|
||||
.Ar host | network | label | id
|
||||
.Xc
|
||||
Kill all of the state entries matching the specified
|
||||
.Ar host ,
|
||||
.Ar network ,
|
||||
.Ar label ,
|
||||
or
|
||||
.Ar network .
|
||||
.Ar id .
|
||||
.Pp
|
||||
For example, to kill all of the state entries originating from
|
||||
.Dq host :
|
||||
.Pp
|
||||
.Dl # pfctl -k host
|
||||
.Pp
|
||||
A second
|
||||
.Fl k Ar host
|
||||
or
|
||||
.Fl k Ar network
|
||||
option may be specified, which will kill all the state entries
|
||||
from the first host/network to the second.
|
||||
For example, to kill all of the state entries originating from
|
||||
.Dq host :
|
||||
.Pp
|
||||
.Dl # pfctl -k host
|
||||
.Pp
|
||||
To kill all of the state entries from
|
||||
.Dq host1
|
||||
to
|
||||
@ -281,6 +290,32 @@ To kill all states with the target
|
||||
.Dq host2 :
|
||||
.Pp
|
||||
.Dl # pfctl -k 0.0.0.0/0 -k host2
|
||||
.Pp
|
||||
It is also possible to kill states by rule label or state ID.
|
||||
In this mode the first
|
||||
.Fl k
|
||||
argument is used to specify the type
|
||||
of the second argument.
|
||||
The following command would kill all states that have been created
|
||||
from rules carrying the label
|
||||
.Dq foobar :
|
||||
.Pp
|
||||
.Dl # pfctl -k label -k foobar
|
||||
.Pp
|
||||
To kill one specific state by its unique state ID
|
||||
(as shown by pfctl -s state -vv),
|
||||
use the
|
||||
.Ar id
|
||||
modifier and as a second argument the state ID and optional creator ID.
|
||||
To kill a state with ID 4823e84500000003 use:
|
||||
.Pp
|
||||
.Dl # pfctl -k id -k 4823e84500000003
|
||||
.Pp
|
||||
To kill a state with ID 4823e84500000018 created from a backup
|
||||
firewall with hostid 00000002 use:
|
||||
.Pp
|
||||
.Dl # pfctl -k id -k 4823e84500000018/2
|
||||
.Pp
|
||||
.It Fl m
|
||||
Merge in explicitly given options without resetting those
|
||||
which are omitted.
|
||||
@ -375,7 +410,7 @@ When used together with
|
||||
source tracking statistics are also shown.
|
||||
.It Fl s Cm labels
|
||||
Show per-rule statistics (label, evaluations, packets total, bytes total,
|
||||
packets in, bytes in, packets out, bytes out) of
|
||||
packets in, bytes in, packets out, bytes out, state creations) of
|
||||
filter rules with labels, useful for accounting.
|
||||
.It Fl s Cm timeouts
|
||||
Show the current global timeouts.
|
||||
@ -486,7 +521,7 @@ attributes.
|
||||
The address/network has been cleared (statistics).
|
||||
.El
|
||||
.Pp
|
||||
Each table maintains a set of counters that can be retrieved using the
|
||||
Each table can maintain a set of counters that can be retrieved using the
|
||||
.Fl v
|
||||
flag of
|
||||
.Nm .
|
||||
@ -497,7 +532,7 @@ FTP server.
|
||||
The following commands configure the firewall and send 10 pings to the FTP
|
||||
server:
|
||||
.Bd -literal -offset indent
|
||||
# printf "table <test> { ftp.openbsd.org }\en \e
|
||||
# printf "table <test> counters { ftp.openbsd.org }\en \e
|
||||
pass out to <test>\en" | pfctl -f-
|
||||
# ping -qc10 ftp.openbsd.org
|
||||
.Ed
|
||||
@ -531,7 +566,7 @@ the number of rules which reference the table, and the global
|
||||
packet statistics for the whole table:
|
||||
.Bd -literal -offset indent
|
||||
# pfctl -vvsTables
|
||||
--a-r- test
|
||||
--a-r-C test
|
||||
Addresses: 1
|
||||
Cleared: Thu Feb 13 18:55:18 2003
|
||||
References: [ Anchors: 0 Rules: 1 ]
|
||||
@ -591,6 +626,8 @@ For tables which are referenced (used) by rules.
|
||||
.It h
|
||||
This flag is set when a table in the main ruleset is hidden by one or more
|
||||
tables of the same name from anchors attached below it.
|
||||
.It C
|
||||
This flag is set when per-address counters are enabled on the table.
|
||||
.El
|
||||
.It Fl t Ar table
|
||||
Specify the name of the table.
|
||||
|
132
pfctl/pfctl.c
132
pfctl/pfctl.c
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl.c,v 1.273 2008/02/13 19:55:12 kettenis Exp $ */
|
||||
/* $OpenBSD: pfctl.c,v 1.277 2008/07/24 10:52:43 henning Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -68,7 +68,9 @@ int pfctl_clear_src_nodes(int, int);
|
||||
int pfctl_clear_states(int, const char *, int);
|
||||
void pfctl_addrprefix(char *, struct pf_addr *);
|
||||
int pfctl_kill_src_nodes(int, const char *, int);
|
||||
int pfctl_kill_states(int, const char *, int);
|
||||
int pfctl_net_kill_states(int, const char *, int);
|
||||
int pfctl_label_kill_states(int, const char *, int);
|
||||
int pfctl_id_kill_states(int, const char *, int);
|
||||
void pfctl_init_options(struct pfctl *);
|
||||
int pfctl_load_options(struct pfctl *);
|
||||
int pfctl_load_limit(struct pfctl *, unsigned int, unsigned int);
|
||||
@ -229,7 +231,7 @@ usage(void)
|
||||
fprintf(stderr, "usage: %s [-AdeghmNnOqRrvz] ", __progname);
|
||||
fprintf(stderr, "[-a anchor] [-D macro=value] [-F modifier]\n");
|
||||
fprintf(stderr, "\t[-f file] [-i interface] [-K host | network] ");
|
||||
fprintf(stderr, "[-k host | network]\n");
|
||||
fprintf(stderr, "[-k host | network | label | id]\n");
|
||||
fprintf(stderr, "\t[-o level] [-p device] [-s modifier]\n");
|
||||
fprintf(stderr, "\t[-t table -T command [address ...]] [-x level]\n");
|
||||
exit(1);
|
||||
@ -376,7 +378,7 @@ pfctl_clear_states(int dev, const char *iface, int opts)
|
||||
if (ioctl(dev, DIOCCLRSTATES, &psk))
|
||||
err(1, "DIOCCLRSTATES");
|
||||
if ((opts & PF_OPT_QUIET) == 0)
|
||||
fprintf(stderr, "%d states cleared\n", psk.psk_af);
|
||||
fprintf(stderr, "%d states cleared\n", psk.psk_killed);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -515,17 +517,13 @@ pfctl_kill_src_nodes(int dev, const char *iface, int opts)
|
||||
|
||||
if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
|
||||
err(1, "DIOCKILLSRCNODES");
|
||||
killed += psnk.psnk_af;
|
||||
/* fixup psnk.psnk_af */
|
||||
psnk.psnk_af = resp[1]->ai_family;
|
||||
killed += psnk.psnk_killed;
|
||||
}
|
||||
freeaddrinfo(res[1]);
|
||||
} else {
|
||||
if (ioctl(dev, DIOCKILLSRCNODES, &psnk))
|
||||
err(1, "DIOCKILLSRCNODES");
|
||||
killed += psnk.psnk_af;
|
||||
/* fixup psnk.psnk_af */
|
||||
psnk.psnk_af = res[0]->ai_family;
|
||||
killed += psnk.psnk_killed;
|
||||
}
|
||||
}
|
||||
|
||||
@ -538,7 +536,7 @@ pfctl_kill_src_nodes(int dev, const char *iface, int opts)
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_kill_states(int dev, const char *iface, int opts)
|
||||
pfctl_net_kill_states(int dev, const char *iface, int opts)
|
||||
{
|
||||
struct pfioc_state_kill psk;
|
||||
struct addrinfo *res[2], *resp[2];
|
||||
@ -625,17 +623,13 @@ pfctl_kill_states(int dev, const char *iface, int opts)
|
||||
|
||||
if (ioctl(dev, DIOCKILLSTATES, &psk))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
killed += psk.psk_af;
|
||||
/* fixup psk.psk_af */
|
||||
psk.psk_af = resp[1]->ai_family;
|
||||
killed += psk.psk_killed;
|
||||
}
|
||||
freeaddrinfo(res[1]);
|
||||
} else {
|
||||
if (ioctl(dev, DIOCKILLSTATES, &psk))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
killed += psk.psk_af;
|
||||
/* fixup psk.psk_af */
|
||||
psk.psk_af = res[0]->ai_family;
|
||||
killed += psk.psk_killed;
|
||||
}
|
||||
}
|
||||
|
||||
@ -647,6 +641,68 @@ pfctl_kill_states(int dev, const char *iface, int opts)
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_label_kill_states(int dev, const char *iface, int opts)
|
||||
{
|
||||
struct pfioc_state_kill psk;
|
||||
|
||||
if (state_killers != 2 || (strlen(state_kill[1]) == 0)) {
|
||||
warnx("no label specified");
|
||||
usage();
|
||||
}
|
||||
memset(&psk, 0, sizeof(psk));
|
||||
if (iface != NULL && strlcpy(psk.psk_ifname, iface,
|
||||
sizeof(psk.psk_ifname)) >= sizeof(psk.psk_ifname))
|
||||
errx(1, "invalid interface: %s", iface);
|
||||
|
||||
if (strlcpy(psk.psk_label, state_kill[1], sizeof(psk.psk_label)) >=
|
||||
sizeof(psk.psk_label))
|
||||
errx(1, "label too long: %s", state_kill[1]);
|
||||
|
||||
if (ioctl(dev, DIOCKILLSTATES, &psk))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
|
||||
if ((opts & PF_OPT_QUIET) == 0)
|
||||
fprintf(stderr, "killed %d states\n", psk.psk_killed);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_id_kill_states(int dev, const char *iface, int opts)
|
||||
{
|
||||
struct pfioc_state_kill psk;
|
||||
|
||||
if (state_killers != 2 || (strlen(state_kill[1]) == 0)) {
|
||||
warnx("no id specified");
|
||||
usage();
|
||||
}
|
||||
|
||||
memset(&psk, 0, sizeof(psk));
|
||||
if ((sscanf(state_kill[1], "%llx/%x",
|
||||
&psk.psk_pfcmp.id, &psk.psk_pfcmp.creatorid)) == 2)
|
||||
HTONL(psk.psk_pfcmp.creatorid);
|
||||
else if ((sscanf(state_kill[1], "%llx", &psk.psk_pfcmp.id)) == 1) {
|
||||
psk.psk_pfcmp.creatorid = 0;
|
||||
} else {
|
||||
warnx("wrong id format specified");
|
||||
usage();
|
||||
}
|
||||
if (psk.psk_pfcmp.id == 0) {
|
||||
warnx("cannot kill id 0");
|
||||
usage();
|
||||
}
|
||||
|
||||
psk.psk_pfcmp.id = htobe64(psk.psk_pfcmp.id);
|
||||
if (ioctl(dev, DIOCKILLSTATES, &psk))
|
||||
err(1, "DIOCKILLSTATES");
|
||||
|
||||
if ((opts & PF_OPT_QUIET) == 0)
|
||||
fprintf(stderr, "killed %d states\n", psk.psk_killed);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pfctl_get_pool(int dev, struct pf_pool *pool, u_int32_t nr,
|
||||
u_int32_t ticket, int r_action, char *anchorname)
|
||||
@ -734,10 +790,12 @@ pfctl_print_rule_counters(struct pf_rule *rule, int opts)
|
||||
(unsigned long long)(rule->packets[0] +
|
||||
rule->packets[1]),
|
||||
(unsigned long long)(rule->bytes[0] +
|
||||
rule->bytes[1]), rule->states);
|
||||
rule->bytes[1]), rule->states_cur);
|
||||
if (!(opts & PF_OPT_DEBUG))
|
||||
printf(" [ Inserted: uid %u pid %u ]\n",
|
||||
(unsigned)rule->cuid, (unsigned)rule->cpid);
|
||||
printf(" [ Inserted: uid %u pid %u "
|
||||
"State Creations: %-6u]\n",
|
||||
(unsigned)rule->cuid, (unsigned)rule->cpid,
|
||||
rule->states_tot);
|
||||
}
|
||||
}
|
||||
|
||||
@ -804,19 +862,6 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
|
||||
|
||||
switch (format) {
|
||||
case PFCTL_SHOW_LABELS:
|
||||
if (pr.rule.label[0]) {
|
||||
printf("%s ", pr.rule.label);
|
||||
printf("%llu %llu %llu %llu %llu %llu %llu\n",
|
||||
(unsigned long long)pr.rule.evaluations,
|
||||
(unsigned long long)(pr.rule.packets[0] +
|
||||
pr.rule.packets[1]),
|
||||
(unsigned long long)(pr.rule.bytes[0] +
|
||||
pr.rule.bytes[1]),
|
||||
(unsigned long long)pr.rule.packets[0],
|
||||
(unsigned long long)pr.rule.bytes[0],
|
||||
(unsigned long long)pr.rule.packets[1],
|
||||
(unsigned long long)pr.rule.bytes[1]);
|
||||
}
|
||||
break;
|
||||
case PFCTL_SHOW_RULES:
|
||||
if (pr.rule.label[0] && (opts & PF_OPT_SHOWALL))
|
||||
@ -850,8 +895,9 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
|
||||
switch (format) {
|
||||
case PFCTL_SHOW_LABELS:
|
||||
if (pr.rule.label[0]) {
|
||||
printf("%s ", pr.rule.label);
|
||||
printf("%llu %llu %llu %llu %llu %llu %llu\n",
|
||||
printf("%s %llu %llu %llu %llu"
|
||||
" %llu %llu %llu %llu\n",
|
||||
pr.rule.label,
|
||||
(unsigned long long)pr.rule.evaluations,
|
||||
(unsigned long long)(pr.rule.packets[0] +
|
||||
pr.rule.packets[1]),
|
||||
@ -860,7 +906,8 @@ pfctl_show_rules(int dev, char *path, int opts, enum pfctl_show format,
|
||||
(unsigned long long)pr.rule.packets[0],
|
||||
(unsigned long long)pr.rule.bytes[0],
|
||||
(unsigned long long)pr.rule.packets[1],
|
||||
(unsigned long long)pr.rule.bytes[1]);
|
||||
(unsigned long long)pr.rule.bytes[1],
|
||||
(unsigned long long)pr.rule.states_tot);
|
||||
}
|
||||
break;
|
||||
case PFCTL_SHOW_RULES:
|
||||
@ -1526,7 +1573,8 @@ pfctl_init_options(struct pfctl *pf)
|
||||
mib[0] = CTL_HW;
|
||||
mib[1] = HW_PHYSMEM64;
|
||||
size = sizeof(mem);
|
||||
(void) sysctl(mib, 2, &mem, &size, NULL, 0);
|
||||
if (sysctl(mib, 2, &mem, &size, NULL, 0) == -1)
|
||||
err(1, "sysctl");
|
||||
if (mem <= 100*1024*1024)
|
||||
pf->limit[PF_LIMIT_TABLE_ENTRIES] = PFR_KENTRY_HIWAT_SMALL;
|
||||
|
||||
@ -2256,8 +2304,14 @@ main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state_killers)
|
||||
pfctl_kill_states(dev, ifaceopt, opts);
|
||||
if (state_killers) {
|
||||
if (!strcmp(state_kill[0], "label"))
|
||||
pfctl_label_kill_states(dev, ifaceopt, opts);
|
||||
else if (!strcmp(state_kill[0], "id"))
|
||||
pfctl_id_kill_states(dev, ifaceopt, opts);
|
||||
else
|
||||
pfctl_net_kill_states(dev, ifaceopt, opts);
|
||||
}
|
||||
|
||||
if (src_node_killers)
|
||||
pfctl_kill_src_nodes(dev, ifaceopt, opts);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl.h,v 1.42 2007/12/05 12:01:47 chl Exp $ */
|
||||
/* $OpenBSD: pfctl.h,v 1.43 2008/05/29 01:00:53 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -109,7 +109,7 @@ struct pf_altq *pfaltq_lookup(const char *);
|
||||
char *rate2str(double);
|
||||
|
||||
void print_addr(struct pf_addr_wrap *, sa_family_t, int);
|
||||
void print_host(struct pfsync_state_host *, sa_family_t, int);
|
||||
void print_host(struct pf_addr *, u_int16_t p, sa_family_t, int);
|
||||
void print_seq(struct pfsync_state_peer *);
|
||||
void print_state(struct pfsync_state *, int);
|
||||
int unmask(struct pf_addr *, sa_family_t);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_altq.c,v 1.93 2007/10/15 02:16:35 deraadt Exp $ */
|
||||
/* $OpenBSD: pfctl_altq.c,v 1.94 2008/07/25 17:43:44 martynas Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002
|
||||
@ -875,7 +875,6 @@ print_hfsc_opts(const struct pf_altq *a, const struct node_queue_opt *qopts)
|
||||
/*
|
||||
* admission control using generalized service curve
|
||||
*/
|
||||
#define INFINITY HUGE_VAL /* positive infinity defined in <math.h> */
|
||||
|
||||
/* add a new service curve to a generalized service curve */
|
||||
static void
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_optimize.c,v 1.16 2008/01/26 13:16:36 mcbride Exp $ */
|
||||
/* $OpenBSD: pfctl_optimize.c,v 1.18 2008/05/07 06:23:30 markus Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Mike Frantzen <frantzen@openbsd.org>
|
||||
@ -182,7 +182,8 @@ struct pf_rule_field {
|
||||
PF_RULE_FIELD(packets, DC),
|
||||
PF_RULE_FIELD(bytes, DC),
|
||||
PF_RULE_FIELD(kif, DC),
|
||||
PF_RULE_FIELD(states, DC),
|
||||
PF_RULE_FIELD(states_cur, DC),
|
||||
PF_RULE_FIELD(states_tot, DC),
|
||||
PF_RULE_FIELD(src_nodes, DC),
|
||||
PF_RULE_FIELD(nr, DC),
|
||||
PF_RULE_FIELD(entries, DC),
|
||||
@ -198,6 +199,7 @@ struct pf_rule_field {
|
||||
PF_RULE_FIELD(natpass, NEVER),
|
||||
PF_RULE_FIELD(max_mss, NEVER),
|
||||
PF_RULE_FIELD(min_ttl, NEVER),
|
||||
PF_RULE_FIELD(set_tos, NEVER),
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_parser.c,v 1.235 2007/10/15 02:16:35 deraadt Exp $ */
|
||||
/* $OpenBSD: pfctl_parser.c,v 1.240 2008/06/10 20:55:02 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Daniel Hartmeier
|
||||
@ -860,6 +860,8 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
|
||||
opts = 1;
|
||||
if (r->rule_flag & PFRULE_IFBOUND)
|
||||
opts = 1;
|
||||
if (r->rule_flag & PFRULE_STATESLOPPY)
|
||||
opts = 1;
|
||||
for (i = 0; !opts && i < PFTM_MAX; ++i)
|
||||
if (r->timeout[i])
|
||||
opts = 1;
|
||||
@ -926,6 +928,12 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
|
||||
printf("if-bound");
|
||||
opts = 0;
|
||||
}
|
||||
if (r->rule_flag & PFRULE_STATESLOPPY) {
|
||||
if (!opts)
|
||||
printf(", ");
|
||||
printf("sloppy");
|
||||
opts = 0;
|
||||
}
|
||||
for (i = 0; i < PFTM_MAX; ++i)
|
||||
if (r->timeout[i]) {
|
||||
int j;
|
||||
@ -953,6 +961,8 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
|
||||
printf(" min-ttl %d", r->min_ttl);
|
||||
if (r->max_mss)
|
||||
printf(" max-mss %d", r->max_mss);
|
||||
if (r->rule_flag & PFRULE_SET_TOS)
|
||||
printf(" set-tos 0x%2.2x", r->set_tos);
|
||||
if (r->allow_opts)
|
||||
printf(" allow-opts");
|
||||
if (r->action == PF_SCRUB) {
|
||||
@ -981,6 +991,22 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
|
||||
}
|
||||
if (r->rtableid != -1)
|
||||
printf(" rtable %u", r->rtableid);
|
||||
if (r->divert.port) {
|
||||
if (PF_AZERO(&r->divert.addr, r->af)) {
|
||||
printf(" divert-reply");
|
||||
} else {
|
||||
/* XXX cut&paste from print_addr */
|
||||
char buf[48];
|
||||
|
||||
printf(" divert-to ");
|
||||
if (inet_ntop(r->af, &r->divert.addr, buf,
|
||||
sizeof(buf)) == NULL)
|
||||
printf("?");
|
||||
else
|
||||
printf("%s", buf);
|
||||
printf(" port %u", ntohs(r->divert.port));
|
||||
}
|
||||
}
|
||||
if (!anchor_call[0] && (r->action == PF_NAT ||
|
||||
r->action == PF_BINAT || r->action == PF_RDR)) {
|
||||
printf(" -> ");
|
||||
@ -1001,6 +1027,8 @@ print_tabledef(const char *name, int flags, int addrs,
|
||||
printf(" const");
|
||||
if (flags & PFR_TFLAG_PERSIST)
|
||||
printf(" persist");
|
||||
if (flags & PFR_TFLAG_COUNTERS)
|
||||
printf(" counters");
|
||||
SIMPLEQ_FOREACH(ti, nodes, entries) {
|
||||
if (ti->file) {
|
||||
printf(" file \"%s\"", ti->file);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pfctl_table.c,v 1.66 2007/03/01 17:20:54 deraadt Exp $ */
|
||||
/* $OpenBSD: pfctl_table.c,v 1.68 2008/06/21 10:34:08 mcbride Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002 Cedric Berger
|
||||
@ -272,12 +272,14 @@ pfctl_table(int argc, char *argv[], char *tname, const char *command,
|
||||
if (b.pfrb_size <= b.pfrb_msize)
|
||||
break;
|
||||
}
|
||||
PFRB_FOREACH(p, &b)
|
||||
PFRB_FOREACH(p, &b) {
|
||||
((struct pfr_astats *)p)->pfras_a.pfra_fback = 0;
|
||||
if (time(NULL) - ((struct pfr_astats *)p)->pfras_tzero >
|
||||
lifetime)
|
||||
if (pfr_buf_add(&b2,
|
||||
&((struct pfr_astats *)p)->pfras_a))
|
||||
err(1, "duplicate buffer");
|
||||
}
|
||||
|
||||
if (opts & PF_OPT_VERBOSE)
|
||||
flags |= PFR_FLAG_FEEDBACK;
|
||||
@ -364,13 +366,14 @@ print_table(struct pfr_table *ta, int verbose, int debug)
|
||||
if (!debug && !(ta->pfrt_flags & PFR_TFLAG_ACTIVE))
|
||||
return;
|
||||
if (verbose) {
|
||||
printf("%c%c%c%c%c%c\t%s",
|
||||
printf("%c%c%c%c%c%c%c\t%s",
|
||||
(ta->pfrt_flags & PFR_TFLAG_CONST) ? 'c' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_PERSIST) ? 'p' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_ACTIVE) ? 'a' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_INACTIVE) ? 'i' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_REFERENCED) ? 'r' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_REFDANCHOR) ? 'h' : '-',
|
||||
(ta->pfrt_flags & PFR_TFLAG_COUNTERS) ? 'C' : '-',
|
||||
ta->pfrt_name);
|
||||
if (ta->pfrt_anchor[0])
|
||||
printf("\t%s", ta->pfrt_anchor);
|
||||
@ -425,7 +428,7 @@ void
|
||||
print_addrx(struct pfr_addr *ad, struct pfr_addr *rad, int dns)
|
||||
{
|
||||
char ch, buf[256] = "{error}";
|
||||
char fb[] = { ' ', 'M', 'A', 'D', 'C', 'Z', 'X', ' ', 'Y' };
|
||||
char fb[] = { ' ', 'M', 'A', 'D', 'C', 'Z', 'X', ' ', 'Y', ' ' };
|
||||
unsigned int fback, hostnet;
|
||||
|
||||
fback = (rad != NULL) ? rad->pfra_fback : ad->pfra_fback;
|
||||
@ -474,6 +477,8 @@ print_astats(struct pfr_astats *as, int dns)
|
||||
|
||||
print_addrx(&as->pfras_a, NULL, dns);
|
||||
printf("\tCleared: %s", ctime(&time));
|
||||
if (as->pfras_a.pfra_fback == PFR_FB_NOCOUNT)
|
||||
return;
|
||||
for (dir = 0; dir < PFR_DIR_MAX; dir++)
|
||||
for (op = 0; op < PFR_OP_ADDR_MAX; op++)
|
||||
printf("\t%-12s [ Packets: %-18llu Bytes: %-18llu ]\n",
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: privsep_fdpass.c,v 1.2 2004/08/13 02:51:48 djm Exp $ */
|
||||
/* $OpenBSD: privsep_fdpass.c,v 1.5 2008/03/24 16:11:08 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2001 Niels Provos <provos@citi.umich.edu>
|
||||
@ -50,7 +50,10 @@ void
|
||||
send_fd(int sock, int fd)
|
||||
{
|
||||
struct msghdr msg;
|
||||
char tmp[CMSG_SPACE(sizeof(int))];
|
||||
union {
|
||||
struct cmsghdr hdr;
|
||||
char buf[CMSG_SPACE(sizeof(int))];
|
||||
} cmsgbuf;
|
||||
struct cmsghdr *cmsg;
|
||||
struct iovec vec;
|
||||
int result = 0;
|
||||
@ -59,8 +62,8 @@ send_fd(int sock, int fd)
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
if (fd >= 0) {
|
||||
msg.msg_control = (caddr_t)tmp;
|
||||
msg.msg_controllen = CMSG_LEN(sizeof(int));
|
||||
msg.msg_control = (caddr_t)&cmsgbuf.buf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
@ -86,7 +89,10 @@ int
|
||||
receive_fd(int sock)
|
||||
{
|
||||
struct msghdr msg;
|
||||
char tmp[CMSG_SPACE(sizeof(int))];
|
||||
union {
|
||||
struct cmsghdr hdr;
|
||||
char buf[CMSG_SPACE(sizeof(int))];
|
||||
} cmsgbuf;
|
||||
struct cmsghdr *cmsg;
|
||||
struct iovec vec;
|
||||
ssize_t n;
|
||||
@ -98,8 +104,8 @@ receive_fd(int sock)
|
||||
vec.iov_len = sizeof(int);
|
||||
msg.msg_iov = &vec;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = tmp;
|
||||
msg.msg_controllen = sizeof(tmp);
|
||||
msg.msg_control = &cmsgbuf.buf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||
|
||||
if ((n = recvmsg(sock, &msg, 0)) == -1)
|
||||
warn("%s: recvmsg", __func__);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: tftp-proxy.c,v 1.2 2006/12/20 03:33:38 joel Exp $
|
||||
/* $OpenBSD: tftp-proxy.c,v 1.6 2008/04/13 00:22:17 djm Exp $
|
||||
*
|
||||
* Copyright (c) 2005 DLS Internet Services
|
||||
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
|
||||
@ -75,8 +75,10 @@ main(int argc, char *argv[])
|
||||
char *p;
|
||||
struct tftphdr *tp;
|
||||
struct passwd *pw;
|
||||
|
||||
char cbuf[CMSG_SPACE(sizeof(struct sockaddr_storage))];
|
||||
union {
|
||||
struct cmsghdr hdr;
|
||||
char buf[CMSG_SPACE(sizeof(struct sockaddr_storage))];
|
||||
} cmsgbuf;
|
||||
char req[PKTSIZE];
|
||||
struct cmsghdr *cmsg;
|
||||
struct msghdr msg;
|
||||
@ -161,8 +163,8 @@ main(int argc, char *argv[])
|
||||
msg.msg_namelen = sizeof(from);
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_control = cbuf;
|
||||
msg.msg_controllen = CMSG_LEN(sizeof(struct sockaddr_storage));
|
||||
msg.msg_control = &cmsgbuf.buf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||
|
||||
if (recvmsg(fd, &msg, 0) < 0) {
|
||||
syslog(LOG_ERR, "recvmsg: %m");
|
||||
@ -381,8 +383,8 @@ sock_ntop(struct sockaddr *sa)
|
||||
u_int16_t
|
||||
pick_proxy_port(void)
|
||||
{
|
||||
return (IPPORT_HIFIRSTAUTO + (arc4random() %
|
||||
(IPPORT_HILASTAUTO - IPPORT_HIFIRSTAUTO)));
|
||||
return (IPPORT_HIFIRSTAUTO +
|
||||
arc4random_uniform(IPPORT_HILASTAUTO - IPPORT_HIFIRSTAUTO));
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user