1
0
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:
Max Laier 2008-12-10 21:08:42 +00:00
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
25 changed files with 922 additions and 512 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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(&current_base->event_tv);
RB_INIT(&current_base->timetree);
TAILQ_INIT(&current_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);

View File

@ -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

View File

@ -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_ */

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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;
}

View File

@ -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

View File

@ -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 .

View File

@ -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)
{

View File

@ -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");
}
}

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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),
};

View File

@ -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);

View 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",

View File

@ -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__);

View File

@ -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