NPF checkpoint:
- Add libnpf(3) - a library to control NPF (configuration, ruleset, etc). - Add NPF support for ftp-proxy(8). - Add rc.d script for NPF. - Convert npfctl(8) to use libnpf(3) and thus make it less depressive. Note: next clean-up step should be a parser, once dholland@ will finish it. - Add more documentation. - Various fixes.
This commit is contained in:
parent
e43028272f
commit
07ac07d35f
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: filter.c,v 1.2 2008/06/18 09:06:26 yamt Exp $ */
|
||||
/* $NetBSD: filter.c,v 1.3 2011/02/02 02:20:26 rmind Exp $ */
|
||||
/* $OpenBSD: filter.c,v 1.6 2007/08/01 09:31:41 henning Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -36,16 +36,26 @@
|
|||
|
||||
#include "filter.h"
|
||||
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
#include "ipf.h"
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
|
||||
/* From netinet/in.h, but only _KERNEL_ gets them. */
|
||||
#define satosin(sa) ((struct sockaddr_in *)(sa))
|
||||
#define satosin6(sa) ((struct sockaddr_in6 *)(sa))
|
||||
|
||||
#define FTP_PROXY_ANCHOR "ftp-proxy"
|
||||
|
||||
enum { TRANS_FILTER = 0, TRANS_NAT, TRANS_RDR, TRANS_SIZE };
|
||||
|
||||
int add_filter(u_int32_t, u_int8_t, struct sockaddr *, struct sockaddr *,
|
||||
u_int16_t);
|
||||
int add_nat(u_int32_t, struct sockaddr *, struct sockaddr *, u_int16_t,
|
||||
struct sockaddr *, u_int16_t, u_int16_t);
|
||||
int add_rdr(u_int32_t, struct sockaddr *, struct sockaddr *, u_int16_t,
|
||||
struct sockaddr *, u_int16_t);
|
||||
int do_commit(void);
|
||||
int do_rollback(void);
|
||||
void init_filter(char *, char *, int);
|
||||
int prepare_commit(u_int32_t);
|
||||
int server_lookup(struct sockaddr *, struct sockaddr *, struct sockaddr *);
|
||||
|
||||
int prepare_rule(u_int32_t, int, struct sockaddr *, struct sockaddr *,
|
||||
u_int16_t);
|
||||
int server_lookup4(struct sockaddr_in *, struct sockaddr_in *,
|
||||
|
@ -60,14 +70,21 @@ static struct pfioc_trans_e pfte[TRANS_SIZE];
|
|||
static int dev, rule_log;
|
||||
static char *qname, *tagname;
|
||||
|
||||
const ftp_proxy_ops_t pf_fprx_ops = {
|
||||
.init_filter = init_filter,
|
||||
.add_filter = add_filter,
|
||||
.add_nat = add_nat,
|
||||
.add_rdr = add_rdr,
|
||||
.server_lookup = server_lookup,
|
||||
.prepare_commit = prepare_commit,
|
||||
.do_commit = do_commit,
|
||||
.do_rollback = do_rollback
|
||||
};
|
||||
|
||||
int
|
||||
add_filter(u_int32_t id, u_int8_t dir, struct sockaddr *src,
|
||||
struct sockaddr *dst, u_int16_t d_port)
|
||||
{
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
if (ipf_enabled)
|
||||
return ipf_add_filter(id, dir, src, dst, d_port);
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
|
||||
if (!src || !dst || !d_port) {
|
||||
errno = EINVAL;
|
||||
|
@ -89,11 +106,6 @@ add_nat(u_int32_t id, struct sockaddr *src, struct sockaddr *dst,
|
|||
u_int16_t d_port, struct sockaddr *nat, u_int16_t nat_range_low,
|
||||
u_int16_t nat_range_high)
|
||||
{
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
if (ipf_enabled)
|
||||
return ipf_add_nat(id, src, dst, d_port, nat, nat_range_low,
|
||||
nat_range_high);
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
|
||||
if (!src || !dst || !d_port || !nat || !nat_range_low ||
|
||||
(src->sa_family != nat->sa_family)) {
|
||||
|
@ -128,10 +140,6 @@ int
|
|||
add_rdr(u_int32_t id, struct sockaddr *src, struct sockaddr *dst,
|
||||
u_int16_t d_port, struct sockaddr *rdr, u_int16_t rdr_port)
|
||||
{
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
if (ipf_enabled)
|
||||
return ipf_add_rdr(id, src, dst, d_port, rdr, rdr_port);
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
|
||||
if (!src || !dst || !d_port || !rdr || !rdr_port ||
|
||||
(src->sa_family != rdr->sa_family)) {
|
||||
|
@ -164,10 +172,6 @@ add_rdr(u_int32_t id, struct sockaddr *src, struct sockaddr *dst,
|
|||
int
|
||||
do_commit(void)
|
||||
{
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
if (ipf_enabled)
|
||||
return ipf_do_commit();
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
|
||||
if (ioctl(dev, DIOCXCOMMIT, &pft) == -1)
|
||||
return (-1);
|
||||
|
@ -178,10 +182,6 @@ do_commit(void)
|
|||
int
|
||||
do_rollback(void)
|
||||
{
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
if (ipf_enabled)
|
||||
return ipf_do_rollback();
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
|
||||
if (ioctl(dev, DIOCXROLLBACK, &pft) == -1)
|
||||
return (-1);
|
||||
|
@ -194,13 +194,6 @@ init_filter(char *opt_qname, char *opt_tagname, int opt_verbose)
|
|||
{
|
||||
struct pf_status status;
|
||||
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
if (ipf_enabled) {
|
||||
ipf_init_filter(opt_qname, opt_tagname, opt_verbose);
|
||||
return;
|
||||
}
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
|
||||
qname = opt_qname;
|
||||
tagname = opt_tagname;
|
||||
|
||||
|
@ -224,11 +217,6 @@ prepare_commit(u_int32_t id)
|
|||
char an[PF_ANCHOR_NAME_SIZE];
|
||||
int i;
|
||||
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
if (ipf_enabled)
|
||||
return ipf_prepare_commit(id);
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
|
||||
memset(&pft, 0, sizeof pft);
|
||||
pft.size = TRANS_SIZE;
|
||||
pft.esize = sizeof pfte[0];
|
||||
|
@ -364,10 +352,6 @@ int
|
|||
server_lookup(struct sockaddr *client, struct sockaddr *proxy,
|
||||
struct sockaddr *server)
|
||||
{
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
if (ipf_enabled)
|
||||
return ipf_server_lookup(client, proxy, server);
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
|
||||
if (client->sa_family == AF_INET)
|
||||
return (server_lookup4(satosin(client), satosin(proxy),
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
/* $NetBSD: filter.h,v 1.2 2008/06/18 09:06:26 yamt Exp $ */
|
||||
/* $OpenBSD: filter.h,v 1.4 2007/08/01 09:31:41 henning Exp $ */
|
||||
/* $NetBSD: filter.h,v 1.3 2011/02/02 02:20:26 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2005 Camiel Dobbelaar, <cd@sentia.nl>
|
||||
|
@ -17,16 +16,34 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#define FTP_PROXY_ANCHOR "ftp-proxy"
|
||||
#ifndef _FTP_PROXY_FILTER_H_
|
||||
#define _FTP_PROXY_FILTER_H_
|
||||
|
||||
int add_filter(u_int32_t, u_int8_t, struct sockaddr *, struct sockaddr *,
|
||||
u_int16_t);
|
||||
int add_nat(u_int32_t, struct sockaddr *, struct sockaddr *, u_int16_t,
|
||||
struct sockaddr *, u_int16_t, u_int16_t);
|
||||
int add_rdr(u_int32_t, struct sockaddr *, struct sockaddr *, u_int16_t,
|
||||
struct sockaddr *, u_int16_t);
|
||||
int do_commit(void);
|
||||
int do_rollback(void);
|
||||
void init_filter(char *, char *, int);
|
||||
int prepare_commit(u_int32_t);
|
||||
int server_lookup(struct sockaddr *, struct sockaddr *, struct sockaddr *);
|
||||
typedef struct {
|
||||
void (*init_filter)(char *, char *, int);
|
||||
int (*add_filter)(uint32_t, uint8_t, struct sockaddr *,
|
||||
struct sockaddr *, uint16_t);
|
||||
int (*add_nat)(uint32_t, struct sockaddr *, struct sockaddr *,
|
||||
uint16_t, struct sockaddr *, u_int16_t, u_int16_t);
|
||||
int (*add_rdr)(uint32_t, struct sockaddr *, struct sockaddr *,
|
||||
uint16_t, struct sockaddr *, uint16_t);
|
||||
int (*server_lookup)(struct sockaddr *, struct sockaddr *,
|
||||
struct sockaddr *);
|
||||
int (*prepare_commit)(u_int32_t);
|
||||
int (*do_commit)(void);
|
||||
int (*do_rollback)(void);
|
||||
} ftp_proxy_ops_t;
|
||||
|
||||
extern const ftp_proxy_ops_t pf_fprx_ops;
|
||||
|
||||
#if defined(__NetBSD__) && defined(WITH_NPF)
|
||||
extern const ftp_proxy_ops_t npf_fprx_ops;
|
||||
extern const char * netif;
|
||||
#endif
|
||||
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
extern const ftp_proxy_ops_t ipf_fprx_ops;
|
||||
extern char * npfopts;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ftp-proxy.c,v 1.3 2009/07/13 19:05:39 roy Exp $ */
|
||||
/* $NetBSD: ftp-proxy.c,v 1.4 2011/02/02 02:20:26 rmind Exp $ */
|
||||
/* $OpenBSD: ftp-proxy.c,v 1.15 2007/08/15 15:18:02 camield Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -45,10 +45,6 @@
|
|||
|
||||
#include "filter.h"
|
||||
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
#include "ipf.h"
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
|
||||
#define CONNECT_TIMEOUT 30
|
||||
#define MIN_PORT 1024
|
||||
#define MAX_LINE 500
|
||||
|
@ -134,9 +130,8 @@ int anonymous_only, daemonize, id_count, ipv6_mode, loglevel, max_sessions,
|
|||
rfc_mode, session_count, timeout, verbose;
|
||||
extern char *__progname;
|
||||
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
int ipf_enabled = 0;
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
/* Default: PF operations. */
|
||||
static const ftp_proxy_ops_t * fops = &pf_fprx_ops;
|
||||
|
||||
void
|
||||
client_error(struct bufferevent *bufev, short what, void *arg)
|
||||
|
@ -321,11 +316,11 @@ end_session(struct session *s)
|
|||
|
||||
/* Remove rulesets by commiting empty ones. */
|
||||
error = 0;
|
||||
if (prepare_commit(s->id) == -1)
|
||||
if (fops->prepare_commit(s->id) == -1)
|
||||
error = errno;
|
||||
else if (do_commit() == -1) {
|
||||
else if (fops->do_commit() == -1) {
|
||||
error = errno;
|
||||
do_rollback();
|
||||
fops->do_rollback();
|
||||
}
|
||||
if (error)
|
||||
logmsg(LOG_ERR, "#%d pf rule removal failed: %s", s->id,
|
||||
|
@ -451,7 +446,7 @@ handle_connection(const int listen_fd, short event, void *ev)
|
|||
strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
if (server_lookup(client_sa, client_to_proxy_sa, server_sa) != 0) {
|
||||
if (fops->server_lookup(client_sa, client_to_proxy_sa, server_sa)) {
|
||||
logmsg(LOG_CRIT, "#%d server lookup failed (no rdr?)", s->id);
|
||||
goto fail;
|
||||
}
|
||||
|
@ -643,11 +638,12 @@ main(int argc, char *argv[])
|
|||
id_count = 1;
|
||||
session_count = 0;
|
||||
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
while ((ch = getopt(argc, argv, "6Aa:b:D:di:m:P:p:q:R:rT:t:v")) != -1) {
|
||||
#else
|
||||
while ((ch = getopt(argc, argv, "6Aa:b:D:dm:P:p:q:R:rT:t:v")) != -1) {
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
#if defined(__NetBSD__)
|
||||
/* Note: both for IPFilter and NPF. */
|
||||
#define NBSD_OPTS "i:N:"
|
||||
#endif
|
||||
while ((ch = getopt(argc, argv,
|
||||
"6Aa:b:D:d" NBSD_OPTS "m:P:p:q:R:rT:t:v")) != -1) {
|
||||
switch (ch) {
|
||||
case '6':
|
||||
ipv6_mode = 1;
|
||||
|
@ -670,17 +666,23 @@ main(int argc, char *argv[])
|
|||
case 'd':
|
||||
daemonize = 0;
|
||||
break;
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
case 'i':
|
||||
ipf_enabled = 1;
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
fops = &ipf_fprx_ops;
|
||||
netif = optarg;
|
||||
#endif
|
||||
break;
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
case 'm':
|
||||
max_sessions = strtonum(optarg, 1, 500, &errstr);
|
||||
if (errstr)
|
||||
errx(1, "max sessions %s", errstr);
|
||||
break;
|
||||
case 'N':
|
||||
#if defined(__NetBSD__) && defined(WITH_NPF)
|
||||
fops = &npf_fprx_ops;
|
||||
npfopts = optarg;
|
||||
#endif
|
||||
break;
|
||||
case 'P':
|
||||
fixed_server_port = optarg;
|
||||
break;
|
||||
|
@ -783,7 +785,7 @@ main(int argc, char *argv[])
|
|||
freeaddrinfo(res);
|
||||
|
||||
/* Initialize pf. */
|
||||
init_filter(qname, tagname, verbose);
|
||||
fops->init_filter(qname, tagname, verbose);
|
||||
|
||||
if (daemonize) {
|
||||
if (daemon(0, 0) == -1)
|
||||
|
@ -1006,7 +1008,7 @@ allow_data_connection(struct session *s)
|
|||
logmsg(LOG_INFO, "#%d passive: client to server port %d"
|
||||
" via port %d", s->id, s->port, s->proxy_port);
|
||||
|
||||
if (prepare_commit(s->id) == -1)
|
||||
if (fops->prepare_commit(s->id) == -1)
|
||||
goto fail;
|
||||
prepared = 1;
|
||||
|
||||
|
@ -1015,22 +1017,23 @@ allow_data_connection(struct session *s)
|
|||
|
||||
/* rdr from $client to $orig_server port $proxy_port -> $server
|
||||
port $port */
|
||||
if (add_rdr(s->id, client_sa, orig_sa, s->proxy_port,
|
||||
if (fops->add_rdr(s->id, client_sa, orig_sa, s->proxy_port,
|
||||
server_sa, s->port) == -1)
|
||||
goto fail;
|
||||
|
||||
/* nat from $client to $server port $port -> $proxy */
|
||||
if (add_nat(s->id, client_sa, server_sa, s->port, proxy_sa,
|
||||
PF_NAT_PROXY_PORT_LOW, PF_NAT_PROXY_PORT_HIGH) == -1)
|
||||
if (fops->add_nat(s->id, client_sa, server_sa, s->port,
|
||||
proxy_sa, PF_NAT_PROXY_PORT_LOW, PF_NAT_PROXY_PORT_HIGH)
|
||||
== -1)
|
||||
goto fail;
|
||||
|
||||
/* pass in from $client to $server port $port */
|
||||
if (add_filter(s->id, PF_IN, client_sa, server_sa,
|
||||
if (fops->add_filter(s->id, PF_IN, client_sa, server_sa,
|
||||
s->port) == -1)
|
||||
goto fail;
|
||||
|
||||
/* pass out from $proxy to $server port $port */
|
||||
if (add_filter(s->id, PF_OUT, proxy_sa, server_sa,
|
||||
if (fops->add_filter(s->id, PF_OUT, proxy_sa, server_sa,
|
||||
s->port) == -1)
|
||||
goto fail;
|
||||
}
|
||||
|
@ -1040,49 +1043,49 @@ allow_data_connection(struct session *s)
|
|||
logmsg(LOG_INFO, "#%d active: server to client port %d"
|
||||
" via port %d", s->id, s->port, s->proxy_port);
|
||||
|
||||
if (prepare_commit(s->id) == -1)
|
||||
if (fops->prepare_commit(s->id) == -1)
|
||||
goto fail;
|
||||
prepared = 1;
|
||||
|
||||
/* rdr from $server to $proxy port $proxy_port -> $client port
|
||||
$port */
|
||||
if (add_rdr(s->id, server_sa, proxy_sa, s->proxy_port,
|
||||
client_sa, s->port) == -1)
|
||||
if (fops->add_rdr(s->id, server_sa, proxy_sa,
|
||||
s->proxy_port, client_sa, s->port) == -1)
|
||||
goto fail;
|
||||
|
||||
/* nat from $server to $client port $port -> $orig_server port
|
||||
$natport */
|
||||
if (rfc_mode && s->cmd == CMD_PORT) {
|
||||
/* Rewrite sourceport to RFC mandated 20. */
|
||||
if (add_nat(s->id, server_sa, client_sa, s->port,
|
||||
orig_sa, 20, 20) == -1)
|
||||
if (fops->add_nat(s->id, server_sa, client_sa,
|
||||
s->port, orig_sa, 20, 20) == -1)
|
||||
goto fail;
|
||||
} else {
|
||||
/* Let pf pick a source port from the standard range. */
|
||||
if (add_nat(s->id, server_sa, client_sa, s->port,
|
||||
orig_sa, PF_NAT_PROXY_PORT_LOW,
|
||||
if (fops->add_nat(s->id, server_sa, client_sa,
|
||||
s->port, orig_sa, PF_NAT_PROXY_PORT_LOW,
|
||||
PF_NAT_PROXY_PORT_HIGH) == -1)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* pass in from $server to $client port $port */
|
||||
if (add_filter(s->id, PF_IN, server_sa, client_sa, s->port) ==
|
||||
-1)
|
||||
if (fops->add_filter(s->id, PF_IN, server_sa, client_sa,
|
||||
s->port) == -1)
|
||||
goto fail;
|
||||
|
||||
/* pass out from $orig_server to $client port $port */
|
||||
if (add_filter(s->id, PF_OUT, orig_sa, client_sa, s->port) ==
|
||||
-1)
|
||||
if (fops->add_filter(s->id, PF_OUT, orig_sa, client_sa,
|
||||
s->port) == -1)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Commit rules if they were prepared. */
|
||||
if (prepared && (do_commit() == -1)) {
|
||||
if (prepared && (fops->do_commit() == -1)) {
|
||||
if (errno != EBUSY)
|
||||
goto fail;
|
||||
/* One more try if busy. */
|
||||
usleep(5000);
|
||||
if (do_commit() == -1)
|
||||
if (fops->do_commit() == -1)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -1094,7 +1097,7 @@ allow_data_connection(struct session *s)
|
|||
fail:
|
||||
logmsg(LOG_CRIT, "#%d pf operation failed: %s", s->id, strerror(errno));
|
||||
if (prepared)
|
||||
do_rollback();
|
||||
fops->do_rollback();
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -1162,9 +1165,14 @@ usage(void)
|
|||
{
|
||||
fprintf(stderr, "usage: %s [-6Adrv] [-a address] [-b address]"
|
||||
" [-D level] [-m maxsessions]\n [-P port]"
|
||||
#if defined(__NetBSD__) && defined(WITH_IPF)
|
||||
#if defined(__NetBSD__)
|
||||
#if defined(WITH_IPF)
|
||||
" [-i netif]"
|
||||
#endif /* __NetBSD__ && WITH_IPF */
|
||||
#endif
|
||||
#if defined(WITH_NPF)
|
||||
" [-N netif:addr:port]"
|
||||
#endif
|
||||
#endif
|
||||
" [-p port] [-q queue] [-R address] [-T tag] [-t timeout]\n",
|
||||
__progname);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ipf.c,v 1.2 2008/06/18 09:06:26 yamt Exp $ */
|
||||
/* $NetBSD: ipf.c,v 1.3 2011/02/02 02:20:26 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -50,7 +50,30 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ipf.h"
|
||||
#include "filter.h"
|
||||
|
||||
void ipf_init_filter(char *, char *, int);
|
||||
int ipf_add_filter(u_int32_t, u_int8_t, struct sockaddr *, struct sockaddr *,
|
||||
u_int16_t);
|
||||
int ipf_add_nat(u_int32_t, struct sockaddr *, struct sockaddr *, u_int16_t,
|
||||
struct sockaddr *, u_int16_t, u_int16_t);
|
||||
int ipf_add_rdr(u_int32_t, struct sockaddr *, struct sockaddr *, u_int16_t,
|
||||
struct sockaddr *, u_int16_t);
|
||||
int ipf_server_lookup(struct sockaddr *, struct sockaddr *, struct sockaddr *);
|
||||
int ipf_prepare_commit(u_int32_t);
|
||||
int ipf_do_commit(void);
|
||||
int ipf_do_rollback(void);
|
||||
|
||||
const ftp_proxy_ops_t ipf_fprx_ops = {
|
||||
.init_filter = ipf_init_filter,
|
||||
.add_filter = ipf_add_filter,
|
||||
.add_nat = ipf_add_nat,
|
||||
.add_rdr = ipf_add_rdr,
|
||||
.server_lookup = ipf_server_lookup,
|
||||
.prepare_commit = ipf_prepare_commit,
|
||||
.do_commit = ipf_do_commit,
|
||||
.do_rollback = ipf_do_rollback
|
||||
};
|
||||
|
||||
/* From netinet/in.h, but only _KERNEL_ gets them. */
|
||||
#define satosin(sa) ((struct sockaddr_in *)(sa))
|
||||
|
|
|
@ -0,0 +1,337 @@
|
|||
/* $NetBSD: npf.c,v 1.1 2011/02/02 02:20:26 rmind Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <net/pfvar.h>
|
||||
#include <net/npf_ncode.h>
|
||||
#include <npf.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "filter.h"
|
||||
|
||||
static void npf_init_filter(char *, char *, int);
|
||||
static int npf_add_filter(uint32_t, uint8_t, struct sockaddr *,
|
||||
struct sockaddr *, uint16_t);
|
||||
static int npf_add_nat(uint32_t, struct sockaddr *, struct sockaddr *,
|
||||
uint16_t, struct sockaddr *, uint16_t, uint16_t);
|
||||
static int npf_add_rdr(uint32_t, struct sockaddr *, struct sockaddr *,
|
||||
uint16_t, struct sockaddr *, uint16_t);
|
||||
static int npf_server_lookup(struct sockaddr *, struct sockaddr *,
|
||||
struct sockaddr *);
|
||||
static int npf_prepare_commit(uint32_t);
|
||||
static int npf_do_commit(void);
|
||||
static int npf_do_rollback(void);
|
||||
|
||||
const ftp_proxy_ops_t npf_fprx_ops = {
|
||||
.init_filter = npf_init_filter,
|
||||
.add_filter = npf_add_filter,
|
||||
.add_nat = npf_add_nat,
|
||||
.add_rdr = npf_add_rdr,
|
||||
.server_lookup = npf_server_lookup,
|
||||
.prepare_commit = npf_prepare_commit,
|
||||
.do_commit = npf_do_commit,
|
||||
.do_rollback = npf_do_rollback
|
||||
};
|
||||
|
||||
#define sa_to_32(sa) (((struct sockaddr_in *)sa)->sin_addr.s_addr)
|
||||
|
||||
#define NPF_DEV_PATH "/dev/npf"
|
||||
#define NPF_FP_RULE_TAG "ftp-proxy"
|
||||
|
||||
typedef struct fp_ent {
|
||||
LIST_ENTRY(fp_ent) fpe_list;
|
||||
uint32_t fpe_id;
|
||||
nl_rule_t * fpe_rl;
|
||||
nl_rule_t * fpe_nat;
|
||||
nl_rule_t * fpe_rdr;
|
||||
} fp_ent_t;
|
||||
|
||||
char * npfopts;
|
||||
|
||||
static LIST_HEAD(, fp_ent) fp_ent_list;
|
||||
static fp_ent_t * fp_ent_hint;
|
||||
static struct sockaddr_in fp_server_sa;
|
||||
static u_int fp_if_idx;
|
||||
static int npf_fd;
|
||||
|
||||
static uint32_t ncode[ ] = {
|
||||
/* from <shost> to <dhost> port <dport> */
|
||||
NPF_OPCODE_IP4MASK, 0x01, 0xdeadbeef, 0xffffffff,
|
||||
NPF_OPCODE_BNE, 15,
|
||||
NPF_OPCODE_IP4MASK, 0x00, 0xdeadbeef, 0xffffffff,
|
||||
NPF_OPCODE_BNE, 9,
|
||||
NPF_OPCODE_TCP_PORTS, 0x00, 0xdeadbeef,
|
||||
NPF_OPCODE_BNE, 4,
|
||||
/* Success (0x0) and failure (0xff) paths. */
|
||||
NPF_OPCODE_RET, 0x00,
|
||||
NPF_OPCODE_RET, 0xff
|
||||
};
|
||||
|
||||
static void
|
||||
ftp_proxy_modify_nc(in_addr_t shost, in_addr_t dhost, in_port_t dport)
|
||||
{
|
||||
/* Source address to match. */
|
||||
ncode[2] = shost;
|
||||
/* Destination address to match. */
|
||||
ncode[8] = shost;
|
||||
/* Destination port to match. */
|
||||
ncode[14] = ((uint32_t)dport << 16) | dport;
|
||||
}
|
||||
|
||||
static fp_ent_t *
|
||||
ftp_proxy_lookup(uint32_t id)
|
||||
{
|
||||
fp_ent_t *fpe;
|
||||
|
||||
/* Look for FTP proxy entry. First, try hint (last used). */
|
||||
if (fp_ent_hint && fp_ent_hint->fpe_id == id) {
|
||||
return fp_ent_hint;
|
||||
}
|
||||
LIST_FOREACH(fpe, &fp_ent_list, fpe_list) {
|
||||
if (fpe->fpe_id == id)
|
||||
break;
|
||||
}
|
||||
return fpe;
|
||||
}
|
||||
|
||||
static void
|
||||
npf_init_filter(char *opt_qname, char *opt_tagname, int opt_verbose)
|
||||
{
|
||||
char *netif = npfopts, *saddr, *port;
|
||||
|
||||
/* XXX get rid of this */
|
||||
saddr = strchr(netif, ':');
|
||||
if (saddr == NULL) {
|
||||
errx(EXIT_FAILURE, "invalid -N option string: %s", npfopts);
|
||||
}
|
||||
*saddr++ = '\0';
|
||||
if (saddr == NULL || (port = strchr(saddr, ':')) == NULL) {
|
||||
errx(EXIT_FAILURE, "invalid -N option string: %s", npfopts);
|
||||
}
|
||||
*port++ = '\0';
|
||||
if (port == NULL) {
|
||||
errx(EXIT_FAILURE, "invalid -N option string: %s", npfopts);
|
||||
}
|
||||
|
||||
fp_if_idx = if_nametoindex(netif);
|
||||
if (fp_if_idx == 0) {
|
||||
errx(EXIT_FAILURE, "invalid network interface '%s'", netif);
|
||||
}
|
||||
|
||||
memset(&fp_server_sa, 0, sizeof(struct sockaddr_in));
|
||||
fp_server_sa.sin_len = sizeof(struct sockaddr_in);
|
||||
fp_server_sa.sin_family = AF_INET;
|
||||
fp_server_sa.sin_addr.s_addr = inet_addr(saddr);
|
||||
fp_server_sa.sin_port = htons(atoi(port));
|
||||
|
||||
npf_fd = open(NPF_DEV_PATH, O_RDONLY);
|
||||
if (npf_fd == -1) {
|
||||
err(EXIT_FAILURE, "cannot open '%s'", NPF_DEV_PATH);
|
||||
}
|
||||
LIST_INIT(&fp_ent_list);
|
||||
fp_ent_hint = NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
npf_prepare_commit(uint32_t id)
|
||||
{
|
||||
fp_ent_t *fpe;
|
||||
|
||||
/* Check if already exists. */
|
||||
fpe = ftp_proxy_lookup(id);
|
||||
if (fpe) {
|
||||
/* Destroy existing rules and reset the values. */
|
||||
npf_rule_destroy(fpe->fpe_rl);
|
||||
npf_rule_destroy(fpe->fpe_nat);
|
||||
npf_rule_destroy(fpe->fpe_rdr);
|
||||
goto reset;
|
||||
}
|
||||
/* Create a new one, if not found. */
|
||||
fpe = malloc(sizeof(fp_ent_t));
|
||||
if (fpe == NULL) {
|
||||
return -1;
|
||||
}
|
||||
LIST_INSERT_HEAD(&fp_ent_list, fpe, fpe_list);
|
||||
fpe->fpe_id = id;
|
||||
reset:
|
||||
fpe->fpe_rl = NULL;
|
||||
fpe->fpe_nat = NULL;
|
||||
fpe->fpe_rdr = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
npf_add_filter(uint32_t id, uint8_t pf_dir, struct sockaddr *src,
|
||||
struct sockaddr *dst, uint16_t dport)
|
||||
{
|
||||
fp_ent_t *fpe;
|
||||
nl_rule_t *rl;
|
||||
int di;
|
||||
|
||||
if (!src || !dst || !dport) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
fpe = ftp_proxy_lookup(id);
|
||||
assert(fpe != NULL);
|
||||
|
||||
di = (pf_dir == PF_OUT) ? NPF_RULE_OUT : NPF_RULE_IN;
|
||||
rl = npf_rule_create(NULL, di | NPF_RULE_PASS | NPF_RULE_FINAL, 0);
|
||||
if (rl == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
ftp_proxy_modify_nc(sa_to_32(src), sa_to_32(dst), htons(dport));
|
||||
errno = npf_rule_setcode(rl, NPF_CODE_NCODE, ncode, sizeof(ncode));
|
||||
if (errno) {
|
||||
npf_rule_destroy(rl);
|
||||
return -1;
|
||||
}
|
||||
assert(fpe->fpe_rl == NULL);
|
||||
fpe->fpe_rl = rl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
npf_add_nat(uint32_t id, struct sockaddr *src, struct sockaddr *dst,
|
||||
uint16_t dport, struct sockaddr *snat, uint16_t plow, uint16_t phigh)
|
||||
{
|
||||
fp_ent_t *fpe;
|
||||
nl_nat_t *nt;
|
||||
npf_addr_t addr;
|
||||
|
||||
if (!src || !dst || !dport || !snat || !plow ||
|
||||
(src->sa_family != snat->sa_family)) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
fpe = ftp_proxy_lookup(id);
|
||||
assert(fpe != NULL);
|
||||
|
||||
memcpy(&addr, &sa_to_32(snat), sizeof(struct in_addr));
|
||||
nt = npf_nat_create(NPF_NATOUT, NPF_NAT_PORTS | NPF_NAT_PORTMAP, 0,
|
||||
&addr, AF_INET, htons(plow));
|
||||
if (nt == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
ftp_proxy_modify_nc(sa_to_32(src), sa_to_32(dst), htons(dport));
|
||||
errno = npf_rule_setcode(nt, NPF_CODE_NCODE, ncode, sizeof(ncode));
|
||||
if (errno) {
|
||||
npf_rule_destroy(nt);
|
||||
return -1;
|
||||
}
|
||||
assert(fpe->fpe_nat == NULL);
|
||||
fpe->fpe_nat = nt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
npf_add_rdr(uint32_t id, struct sockaddr *src, struct sockaddr *dst,
|
||||
uint16_t dport, struct sockaddr *rdr, uint16_t rdr_port)
|
||||
{
|
||||
fp_ent_t *fpe;
|
||||
nl_nat_t *nt;
|
||||
npf_addr_t addr;
|
||||
|
||||
if (!src || !dst || !dport || !rdr || !rdr_port ||
|
||||
(src->sa_family != rdr->sa_family)) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
fpe = ftp_proxy_lookup(id);
|
||||
assert(fpe != NULL);
|
||||
|
||||
memcpy(&addr, &sa_to_32(rdr), sizeof(struct in_addr));
|
||||
nt = npf_nat_create(NPF_NATIN, NPF_NAT_PORTS, 0,
|
||||
&addr, AF_INET, htons(rdr_port));
|
||||
if (nt == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
ftp_proxy_modify_nc(sa_to_32(src), sa_to_32(dst), htons(dport));
|
||||
errno = npf_rule_setcode(nt, NPF_CODE_NCODE, ncode, sizeof(ncode));
|
||||
if (errno) {
|
||||
npf_rule_destroy(nt);
|
||||
return -1;
|
||||
}
|
||||
assert(fpe->fpe_rdr == NULL);
|
||||
fpe->fpe_rdr = nt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
npf_server_lookup(struct sockaddr *c, struct sockaddr *proxy,
|
||||
struct sockaddr *server)
|
||||
{
|
||||
|
||||
memcpy(server, &fp_server_sa, sizeof(struct sockaddr_in));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
npf_do_commit(void)
|
||||
{
|
||||
nl_rule_t *group;
|
||||
fp_ent_t *fpe;
|
||||
pri_t pri;
|
||||
|
||||
group = npf_rule_create(NPF_FP_RULE_TAG, NPF_RULE_PASS | NPF_RULE_IN |
|
||||
NPF_RULE_OUT | NPF_RULE_FINAL, fp_if_idx);
|
||||
if (group == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pri = 1;
|
||||
LIST_FOREACH(fpe, &fp_ent_list, fpe_list) {
|
||||
npf_rule_insert(NULL, group, fpe->fpe_rl, pri++);
|
||||
}
|
||||
npf_update_rule(npf_fd, NPF_FP_RULE_TAG, group);
|
||||
npf_rule_destroy(group);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
npf_do_rollback(void)
|
||||
{
|
||||
/* None. */
|
||||
return 0;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: ad.mips64eb,v 1.36 2011/01/18 20:09:37 pooka Exp $
|
||||
# $NetBSD: ad.mips64eb,v 1.37 2011/02/02 02:20:26 rmind Exp $
|
||||
./libexec/ld.elf_so-64 base-compat-shlib compat,pic
|
||||
./libexec/ld.elf_so-o32 base-sysutil-bin compat,pic
|
||||
./usr/lib/64 base-compat-lib
|
||||
|
@ -151,6 +151,8 @@
|
|||
./usr/lib/64/libmj.so.0.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/64/libnetpgp.so.3 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/64/libnetpgp.so.3.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/64/libnpf.so.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/64/libnpf.so.0.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/64/libobjc.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/64/libobjc.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/64/libopcodes.so.4 base-compat-shlib compat,pic,binutils
|
||||
|
@ -408,6 +410,8 @@
|
|||
./usr/lib/o32/libmj.so.0.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/o32/libnetpgp.so.3 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/o32/libnetpgp.so.3.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/o32/libnpf.so.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/o32/libnpf.so.0.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/o32/libobjc.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/o32/libobjc.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/o32/libopcodes.so.4 base-compat-shlib compat,pic,binutils
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: ad.mips64el,v 1.34 2011/01/18 20:09:37 pooka Exp $
|
||||
# $NetBSD: ad.mips64el,v 1.35 2011/02/02 02:20:26 rmind Exp $
|
||||
./libexec/ld.elf_so-64 base-compat-shlib compat,pic
|
||||
./libexec/ld.elf_so-o32 base-sysutil-bin compat,pic
|
||||
./usr/lib/64 base-compat-lib
|
||||
|
@ -151,6 +151,8 @@
|
|||
./usr/lib/64/libmj.so.0.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/64/libnetpgp.so.3 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/64/libnetpgp.so.3.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/64/libnpf.so.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/64/libnpf.so.0.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/64/libobjc.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/64/libobjc.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/64/libopcodes.so.4 base-compat-shlib compat,pic,binutils
|
||||
|
@ -408,6 +410,8 @@
|
|||
./usr/lib/o32/libmj.so.0.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/o32/libnetpgp.so.3 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/o32/libnetpgp.so.3.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/o32/libnpf.so.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/o32/libnpf.so.0.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/o32/libobjc.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/o32/libobjc.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/o32/libopcodes.so.4 base-compat-shlib compat,pic,binutils
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: md.amd64,v 1.109 2011/01/18 20:09:37 pooka Exp $
|
||||
# $NetBSD: md.amd64,v 1.110 2011/02/02 02:20:26 rmind Exp $
|
||||
./dev/lms0 base-obsolete obsolete
|
||||
./dev/mms0 base-obsolete obsolete
|
||||
./libexec/ld.elf_so-i386 base-sys-shlib compat,pic
|
||||
|
@ -157,6 +157,8 @@
|
|||
./usr/lib/i386/libmj.so.0.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/i386/libnetpgp.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libnetpgp.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libnpf.so.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/i386/libnpf.so.0.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/i386/libobjc.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libobjc.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/i386/libopcodes.so.4 base-compat-shlib compat,pic,binutils
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: md.sparc64,v 1.102 2011/01/18 20:09:38 pooka Exp $
|
||||
# $NetBSD: md.sparc64,v 1.103 2011/02/02 02:20:26 rmind Exp $
|
||||
./libexec/ld.elf_so-sparc base-sysutil-bin compat,pic
|
||||
./sbin/edlabel base-sysutil-root obsolete
|
||||
./usr/bin/fdformat base-util-bin
|
||||
|
@ -154,6 +154,8 @@
|
|||
./usr/lib/sparc/libmj.so.0.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/sparc/libnetpgp.so.3 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/sparc/libnetpgp.so.3.0 base-compat-shlib compat,pic,crypto
|
||||
./usr/lib/sparc/libnpf.so.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/sparc/libnpf.so.0.0 base-compat-shlib compat,pic,npf
|
||||
./usr/lib/sparc/libobjc.so.3 base-compat-shlib compat,pic
|
||||
./usr/lib/sparc/libobjc.so.3.0 base-compat-shlib compat,pic
|
||||
./usr/lib/sparc/libopcodes.so.4 base-compat-shlib compat,pic,binutils
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: shl.mi,v 1.570 2011/01/19 21:07:13 he Exp $
|
||||
# $NetBSD: shl.mi,v 1.571 2011/02/02 02:20:26 rmind Exp $
|
||||
#
|
||||
# Note: Don't delete entries from here - mark them as "obsolete" instead,
|
||||
# unless otherwise stated below.
|
||||
|
@ -317,6 +317,9 @@
|
|||
./usr/lib/libnetpgp.so base-crypto-shlib crypto
|
||||
./usr/lib/libnetpgp.so.3 base-crypto-shlib crypto
|
||||
./usr/lib/libnetpgp.so.3.0 base-crypto-shlib crypto
|
||||
./usr/lib/libnpf.so base-npf-shlib npf
|
||||
./usr/lib/libnpf.so.0 base-npf-shlib npf
|
||||
./usr/lib/libnpf.so.0.0 base-npf-shlib npf
|
||||
./usr/lib/libnvpair.so base-zfs-shlib dynamicroot,zfs
|
||||
./usr/lib/libnvpair.so.0 base-zfs-shlib dynamicroot,zfs
|
||||
./usr/lib/libnvpair.so.0.0 base-zfs-shlib zfs,dynamicroot
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: ad.mips64eb,v 1.19 2011/01/31 18:27:53 christos Exp $
|
||||
# $NetBSD: ad.mips64eb,v 1.20 2011/02/02 02:20:27 rmind Exp $
|
||||
./usr/bin/elf2aout comp-obsolete obsolete
|
||||
./usr/bin/elf2ecoff comp-sysutil-bin
|
||||
./usr/include/mips comp-c-include
|
||||
|
@ -392,6 +392,10 @@
|
|||
./usr/lib/64/libnetpgp.so comp-sys-shlib compat,crypto,pic
|
||||
./usr/lib/64/libnetpgp_p.a comp-c-proflib compat,crypto,profile
|
||||
./usr/lib/64/libnetpgp_pic.a comp-c-piclib compat,crypto,pic
|
||||
./usr/lib/64/libnpf.a comp-c-lib compat,npf
|
||||
./usr/lib/64/libnpf.so comp-sys-shlib compat,npf,pic
|
||||
./usr/lib/64/libnpf_p.a comp-c-proflib compat,npf,profile
|
||||
./usr/lib/64/libnpf_pic.a comp-c-piclib compat,npf,pic
|
||||
./usr/lib/64/libobjc.a comp-c-lib compat
|
||||
./usr/lib/64/libobjc.so base-sys-shlib compat,pic
|
||||
./usr/lib/64/libobjc_p.a comp-c-proflib compat,profile
|
||||
|
@ -899,6 +903,10 @@
|
|||
./usr/lib/o32/libnetpgp.so comp-sys-shlib compat,crypto,pic
|
||||
./usr/lib/o32/libnetpgp_p.a comp-c-proflib compat,crypto,profile
|
||||
./usr/lib/o32/libnetpgp_pic.a comp-c-piclib compat,crypto,pic
|
||||
./usr/lib/o32/libnpf.a comp-c-lib compat,npf
|
||||
./usr/lib/o32/libnpf.so comp-sys-shlib compat,npf,pic
|
||||
./usr/lib/o32/libnpf_p.a comp-c-proflib compat,npf,profile
|
||||
./usr/lib/o32/libnpf_pic.a comp-c-piclib compat,npf,pic
|
||||
./usr/lib/o32/libobjc.a comp-c-lib compat
|
||||
./usr/lib/o32/libobjc.so base-sys-shlib compat,pic
|
||||
./usr/lib/o32/libobjc_p.a comp-c-proflib compat,profile
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: ad.mips64el,v 1.19 2011/01/31 18:27:53 christos Exp $
|
||||
# $NetBSD: ad.mips64el,v 1.20 2011/02/02 02:20:27 rmind Exp $
|
||||
./usr/bin/elf2aout comp-obsolete obsolete
|
||||
./usr/bin/elf2ecoff comp-sysutil-bin
|
||||
./usr/include/mips comp-c-include
|
||||
|
@ -392,6 +392,10 @@
|
|||
./usr/lib/64/libnetpgp.so comp-sys-shlib compat,crypto,pic
|
||||
./usr/lib/64/libnetpgp_p.a comp-c-proflib compat,crypto,profile
|
||||
./usr/lib/64/libnetpgp_pic.a comp-c-piclib compat,crypto,pic
|
||||
./usr/lib/64/libnpf.a comp-c-lib compat,npf
|
||||
./usr/lib/64/libnpf.so comp-sys-shlib compat,npf,pic
|
||||
./usr/lib/64/libnpf_p.a comp-c-proflib compat,npf,profile
|
||||
./usr/lib/64/libnpf_pic.a comp-c-piclib compat,npf,pic
|
||||
./usr/lib/64/libobjc.a comp-c-lib compat
|
||||
./usr/lib/64/libobjc.so base-sys-shlib compat,pic
|
||||
./usr/lib/64/libobjc_p.a comp-c-proflib compat,profile
|
||||
|
@ -899,6 +903,10 @@
|
|||
./usr/lib/o32/libnetpgp.so comp-sys-shlib compat,crypto,pic
|
||||
./usr/lib/o32/libnetpgp_p.a comp-c-proflib compat,crypto,profile
|
||||
./usr/lib/o32/libnetpgp_pic.a comp-c-piclib compat,crypto,pic
|
||||
./usr/lib/o32/libnpf.a comp-c-lib compat,npf
|
||||
./usr/lib/o32/libnpf.so comp-sys-shlib compat,npf,pic
|
||||
./usr/lib/o32/libnpf_p.a comp-c-proflib compat,npf,profile
|
||||
./usr/lib/o32/libnpf_pic.a comp-c-piclib compat,npf,pic
|
||||
./usr/lib/o32/libobjc.a comp-c-lib compat
|
||||
./usr/lib/o32/libobjc.so base-sys-shlib compat,pic
|
||||
./usr/lib/o32/libobjc_p.a comp-c-proflib compat,profile
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: md.amd64,v 1.93 2011/01/20 14:54:24 njoly Exp $
|
||||
# $NetBSD: md.amd64,v 1.94 2011/02/02 02:20:27 rmind Exp $
|
||||
./usr/include/amd64 comp-c-include
|
||||
./usr/include/amd64/ansi.h comp-c-include
|
||||
./usr/include/amd64/aout_machdep.h comp-c-include
|
||||
|
@ -656,6 +656,11 @@
|
|||
./usr/lib/i386/libnetpgp_g.a comp-c-proflib compat,debuglib
|
||||
./usr/lib/i386/libnetpgp_p.a comp-c-proflib compat,profile
|
||||
./usr/lib/i386/libnetpgp_pic.a comp-c-piclib compat,pic
|
||||
./usr/lib/i386/libnpf.a comp-c-lib compat,npf
|
||||
./usr/lib/i386/libnpf.so comp-sys-shlib compat,npf,pic
|
||||
./usr/lib/i386/libnpf_g.a comp-c-proflib compat,npf,debuglib
|
||||
./usr/lib/i386/libnpf_p.a comp-c-proflib compat,npf,profile
|
||||
./usr/lib/i386/libnpf_pic.a comp-c-piclib compat,npf,pic
|
||||
./usr/lib/i386/libobjc.a comp-c-lib compat
|
||||
./usr/lib/i386/libobjc.so comp-sys-shlib compat,pic
|
||||
./usr/lib/i386/libobjc_g.a comp-c-proflib compat,debuglib
|
||||
|
@ -952,6 +957,7 @@
|
|||
./usr/libdata/debug/usr/lib/i386/libmenu.so.6.0.debug comp-compat-shlib compat,pic,debug
|
||||
./usr/libdata/debug/usr/lib/i386/libmj.so.0.0.debug comp-compat-shlib compat,pic,debug
|
||||
./usr/libdata/debug/usr/lib/i386/libnetpgp.so.3.0.debug comp-compat-shlib compat,pic,debug
|
||||
./usr/libdata/debug/usr/lib/i386/libnpf.so.0.0.debug comp-compat-shlib compat,pic,npf,debug
|
||||
./usr/libdata/debug/usr/lib/i386/libobjc.so.3.0.debug comp-compat-shlib compat,pic,debug
|
||||
./usr/libdata/debug/usr/lib/i386/libopcodes.so.4.0.debug comp-compat-shlib compat,pic,binutils,debug
|
||||
./usr/libdata/debug/usr/lib/i386/libossaudio.so.1.0.debug comp-compat-shlib compat,pic,debug
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: md.sparc64,v 1.82 2011/01/31 18:49:43 matt Exp $
|
||||
# $NetBSD: md.sparc64,v 1.83 2011/02/02 02:20:27 rmind Exp $
|
||||
./usr/include/ieeefp.h comp-c-include
|
||||
./usr/include/sparc comp-c-include
|
||||
./usr/include/sparc/_G_config.h comp-obsolete obsolete
|
||||
|
@ -466,6 +466,10 @@
|
|||
./usr/lib/sparc/libnetpgp.so comp-sys-shlib compat,pic,crypto
|
||||
./usr/lib/sparc/libnetpgp_p.a comp-c-proflib compat,profile,crypto
|
||||
./usr/lib/sparc/libnetpgp_pic.a comp-c-piclib compat,pic,crypto
|
||||
./usr/lib/sparc/libnpf.a comp-c-lib compat,npf
|
||||
./usr/lib/sparc/libnpf.so comp-sys-shlib compat,pic,npf
|
||||
./usr/lib/sparc/libnpf_p.a comp-c-proflib compat,profile,npf
|
||||
./usr/lib/sparc/libnpf_pic.a comp-c-piclib compat,pic,npf
|
||||
./usr/lib/sparc/libobjc.a comp-c-lib compat
|
||||
./usr/lib/sparc/libobjc.so base-sys-shlib compat,pic
|
||||
./usr/lib/sparc/libobjc_p.a comp-c-proflib compat,profile
|
||||
|
@ -716,6 +720,7 @@
|
|||
./usr/libdata/debug/usr/lib/sparc/libmenu.so.6.0.debug comp-compat-shlib compat,pic,debug
|
||||
./usr/libdata/debug/usr/lib/sparc/libmj.so.0.0.debug comp-compat-shlib compat,pic,debug
|
||||
./usr/libdata/debug/usr/lib/sparc/libnetpgp.so.3.0.debug comp-compat-shlib compat,pic,debug
|
||||
./usr/libdata/debug/usr/lib/sparc/libnpf.so.0.0.debug comp-compat-shlib compat,pic,debug,npf
|
||||
./usr/libdata/debug/usr/lib/sparc/libobjc.so.3.0.debug comp-compat-shlib compat,pic,debug
|
||||
./usr/libdata/debug/usr/lib/sparc/libopcodes.so.4.0.debug comp-compat-shlib compat,pic,binutils,debug
|
||||
./usr/libdata/debug/usr/lib/sparc/libossaudio.so.1.0.debug comp-compat-shlib compat,pic,debug
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.1578 2011/01/28 18:52:48 pooka Exp $
|
||||
# $NetBSD: mi,v 1.1579 2011/02/02 02:20:27 rmind Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
|
@ -1703,6 +1703,7 @@
|
|||
./usr/include/nfs/xdr_subs.h comp-c-include
|
||||
./usr/include/nl_types.h comp-c-include
|
||||
./usr/include/nlist.h comp-c-include
|
||||
./usr/include/npf.h comp-npf-include npf
|
||||
./usr/include/nsswitch.h comp-c-include
|
||||
./usr/include/ntfs/ntfs.h comp-c-include
|
||||
./usr/include/ntfs/ntfs_compr.h comp-obsolete obsolete
|
||||
|
@ -2560,6 +2561,9 @@
|
|||
./usr/lib/libnetpgp.a comp-c-lib crypto
|
||||
./usr/lib/libnetpgp_g.a -unknown- debuglib
|
||||
./usr/lib/libnetpgp_p.a comp-c-proflib profile,crypto
|
||||
./usr/lib/libnpf.a comp-npf-lib npf
|
||||
./usr/lib/libnpf_g.a -unknown- debuglib
|
||||
./usr/lib/libnpf_p.a comp-npf-proflib profile,npf
|
||||
./usr/lib/libntp.a comp-obsolete obsolete
|
||||
./usr/lib/libntp_p.a comp-obsolete obsolete
|
||||
./usr/lib/libntp_pic.a comp-obsolete obsolete
|
||||
|
@ -3913,6 +3917,7 @@
|
|||
./usr/libdata/lint/llib-lmilter.ln comp-obsolete obsolete
|
||||
./usr/libdata/lint/llib-lmj.ln comp-c-lintlib lint,crypto
|
||||
./usr/libdata/lint/llib-lnetpgp.ln comp-c-lintlib lint,crypto
|
||||
./usr/libdata/lint/llib-lnpf.ln comp-npf-lintlib lint,npf
|
||||
./usr/libdata/lint/llib-lntp.ln comp-obsolete obsolete
|
||||
./usr/libdata/lint/llib-lopenpgpsdk.ln comp-obsolete obsolete
|
||||
./usr/libdata/lint/llib-lossaudio.ln comp-c-lintlib lint
|
||||
|
@ -7442,6 +7447,7 @@
|
|||
./usr/share/man/cat3/noqiflush.0 comp-c-catman .cat
|
||||
./usr/share/man/cat3/noraw.0 comp-c-catman .cat
|
||||
./usr/share/man/cat3/notimeout.0 comp-c-catman .cat
|
||||
./usr/share/man/cat3/npf.0 comp-npf-catman .cat
|
||||
./usr/share/man/cat3/nrand48.0 comp-c-catman .cat
|
||||
./usr/share/man/cat3/ns.0 comp-obsolete obsolete
|
||||
./usr/share/man/cat3/ns_addr.0 comp-obsolete obsolete
|
||||
|
@ -13455,6 +13461,7 @@
|
|||
./usr/share/man/html3/noqiflush.html comp-c-htmlman html
|
||||
./usr/share/man/html3/noraw.html comp-c-htmlman html
|
||||
./usr/share/man/html3/notimeout.html comp-c-htmlman html
|
||||
./usr/share/man/html3/npf.html comp-npf-htmlman html
|
||||
./usr/share/man/html3/nrand48.html comp-c-htmlman html
|
||||
./usr/share/man/html3/nsdispatch.html comp-c-htmlman html
|
||||
./usr/share/man/html3/ntoa.html comp-c-htmlman html
|
||||
|
@ -19454,6 +19461,7 @@
|
|||
./usr/share/man/man3/noqiflush.3 comp-c-man .man
|
||||
./usr/share/man/man3/noraw.3 comp-c-man .man
|
||||
./usr/share/man/man3/notimeout.3 comp-c-man .man
|
||||
./usr/share/man/man3/npf.3 comp-npf-man .man
|
||||
./usr/share/man/man3/nrand48.3 comp-c-man .man
|
||||
./usr/share/man/man3/ns.3 comp-obsolete obsolete
|
||||
./usr/share/man/man3/ns_addr.3 comp-obsolete obsolete
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: shl.mi,v 1.154 2011/01/24 10:15:39 skrll Exp $
|
||||
# $NetBSD: shl.mi,v 1.155 2011/02/02 02:20:27 rmind Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
|
@ -73,6 +73,7 @@
|
|||
./usr/lib/libmenu_pic.a comp-c-piclib
|
||||
./usr/lib/libmj_pic.a comp-c-piclib
|
||||
./usr/lib/libnetpgp_pic.a comp-c-piclib crypto
|
||||
./usr/lib/libnpf_pic.a comp-npf-piclib npf
|
||||
./usr/lib/libnvpair_pic.a comp-zfs-piclib zfs
|
||||
./usr/lib/libobjc_pic.a comp-objc-piclib
|
||||
./usr/lib/libopcodes.so.4 comp-c-shlib binutils
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.218 2011/01/13 10:55:19 kefren Exp $
|
||||
# $NetBSD: mi,v 1.219 2011/02/02 02:20:28 rmind Exp $
|
||||
#
|
||||
# Note: end-user configuration files that are moved to another location
|
||||
# should not be marked "obsolete"; they should just be removed from
|
||||
|
@ -236,6 +236,7 @@
|
|||
./etc/rc.d/newsyslog etc-sys-rc
|
||||
./etc/rc.d/nfsd etc-nfsserver-rc
|
||||
./etc/rc.d/nfslocking etc-nfsserver-rc
|
||||
./etc/rc.d/npf etc-npf-rc
|
||||
./etc/rc.d/ntpd etc-ntp-rc
|
||||
./etc/rc.d/ntpdate etc-ntp-rc
|
||||
./etc/rc.d/perusertmp etc-sys-rc
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: rc.conf,v 1.110 2011/01/13 10:55:20 kefren Exp $
|
||||
# $NetBSD: rc.conf,v 1.111 2011/02/02 02:20:28 rmind Exp $
|
||||
#
|
||||
# /etc/defaults/rc.conf --
|
||||
# default configuration of /etc/rc.conf
|
||||
|
@ -161,6 +161,7 @@ securelevel="" # securelevel to set to
|
|||
# Networking startup.
|
||||
#
|
||||
mdnsd=NO
|
||||
npf=NO
|
||||
ipfilter=NO ipfilter_flags="" # uses /etc/ipf.conf
|
||||
ipnat=NO # uses /etc/ipnat.conf
|
||||
ipfs=NO ipfs_flags="" # save/load ipnat and ipf states
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: special,v 1.134 2010/12/17 09:54:28 jruoho Exp $
|
||||
# $NetBSD: special,v 1.135 2011/02/02 02:20:28 rmind Exp $
|
||||
# @(#)special 8.2 (Berkeley) 1/23/94
|
||||
#
|
||||
# This file may be overwritten on upgrades.
|
||||
|
@ -240,6 +240,7 @@
|
|||
./etc/rc.d/newsyslog type=file mode=0555
|
||||
./etc/rc.d/nfsd type=file mode=0555
|
||||
./etc/rc.d/nfslocking type=file mode=0555
|
||||
./etc/rc.d/npf type=file mode=0555
|
||||
./etc/rc.d/ntpd type=file mode=0555
|
||||
./etc/rc.d/ntpdate type=file mode=0555
|
||||
./etc/rc.d/perusertmp type=file mode=0555
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.81 2011/01/13 10:55:20 kefren Exp $
|
||||
# $NetBSD: Makefile,v 1.82 2011/02/02 02:20:28 rmind Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
|
@ -28,7 +28,7 @@ CONFIGFILES=\
|
|||
ldconfig ldpd local lpd lvm \
|
||||
mdnsd mixerctl mopd motd mountall mountcritlocal \
|
||||
mountcritremote mountd moused mrouted \
|
||||
named ndbootd network newsyslog nfsd nfslocking ntpd ntpdate \
|
||||
named ndbootd network newsyslog nfsd nfslocking npf ntpd ntpdate \
|
||||
perusertmp pf pf_boot pflogd postfix powerd ppp pwcheck \
|
||||
quota \
|
||||
racoon rpcbind raidframe raidframeparity rarpd rbootd rndctl \
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: npf,v 1.1 2011/02/02 02:20:28 rmind Exp $
|
||||
#
|
||||
# Public Domain.
|
||||
#
|
||||
|
||||
# PROVIDE: npf
|
||||
# REQUIRE: root bootconf mountcritlocal tty network
|
||||
# BEFORE: NETWORKING
|
||||
|
||||
$_rc_subr_loaded . /etc/rc.subr
|
||||
|
||||
name="npf"
|
||||
rcvar=$name
|
||||
|
||||
config="/etc/npf.conf"
|
||||
|
||||
start_cmd="npf_start"
|
||||
stop_cmd="npf_stop"
|
||||
|
||||
reload_cmd="npf_reload"
|
||||
status_cmd="npf_status"
|
||||
extra_commands="reload status"
|
||||
|
||||
npf_cfg_check()
|
||||
{
|
||||
if [ ! -f ${config} ]; then
|
||||
warn "${config} is not readable; failed."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
npf_start()
|
||||
{
|
||||
echo "Enabling NPF."
|
||||
npf_cfg_check
|
||||
/usr/sbin/npfctl reload
|
||||
/usr/sbin/npfctl start
|
||||
}
|
||||
|
||||
npf_stop()
|
||||
{
|
||||
echo "Disabling NPF."
|
||||
/usr/sbin/npfctl stop
|
||||
/usr/sbin/npfctl flush
|
||||
}
|
||||
|
||||
npf_reload()
|
||||
{
|
||||
echo "Reloading NPF ruleset."
|
||||
npf_cfg_check
|
||||
/usr/sbin/npfctl reload
|
||||
}
|
||||
|
||||
npf_status()
|
||||
{
|
||||
}
|
||||
|
||||
load_rc_config $name
|
||||
run_rc_command "$1"
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.160 2011/01/18 20:09:37 pooka Exp $
|
||||
# $NetBSD: Makefile,v 1.161 2011/02/02 02:20:24 rmind Exp $
|
||||
# from: @(#)Makefile 5.25.1.1 (Berkeley) 5/7/91
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
@ -88,6 +88,10 @@ SUBDIR+= libedit # depends on libterminfo
|
|||
SUBDIR+= librefuse # depends on libpuffs
|
||||
SUBDIR+= librumpuser # depends on libpthread
|
||||
|
||||
.if (${MKNPF} != "no")
|
||||
SUBDIR+= libnpf # depends on libprop
|
||||
.endif
|
||||
|
||||
.if (${MKCRYPTO} != "no")
|
||||
SUBDIR+= ../crypto/external/bsd/openssl/lib # depends on libcrypt
|
||||
.endif
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# $NetBSD: Makefile,v 1.1 2011/02/02 02:20:25 rmind Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
LIB= npf
|
||||
MAN= npf.3
|
||||
|
||||
SRCS= npf.c
|
||||
|
||||
INCS= npf.h
|
||||
INCSDIR= /usr/include
|
||||
|
||||
LIBDPLIBS+= prop ${.CURDIR}/../libprop
|
||||
LDADD+= -lprop
|
||||
DPADD+= ${LIBPROP}
|
||||
|
||||
WARNS?= 4
|
||||
NOLINT= # defined (note: deliberately)
|
||||
|
||||
.include <bsd.lib.mk>
|
|
@ -0,0 +1,290 @@
|
|||
.\" $NetBSD: npf.3,v 1.1 2011/02/02 02:20:25 rmind Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This material is based upon work partially supported by The
|
||||
.\" NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
.\" CONTRACT, STRICT LIABILITY, OR TORT (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 February 2, 2011
|
||||
.Dt NPF 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm npf
|
||||
.Nd NPF packet filter library
|
||||
.Sh LIBRARY
|
||||
.Lb libnpf
|
||||
.Sh SYNOPSIS
|
||||
.In npf.h
|
||||
.\" ---
|
||||
.Ft nl_config_t *
|
||||
.Fn npf_config_create "void"
|
||||
.Ft int
|
||||
.Fn npf_config_submit "nl_config_t *ncf" "int fd"
|
||||
.Ft void
|
||||
.Fn npf_config_destroy "nl_config_t *ncf"
|
||||
.\" ---
|
||||
.Ft nl_rule_t *
|
||||
.Fn npf_rule_create "char *name" "uint32_t attr" "u_int if_idx"
|
||||
.Ft int
|
||||
.Fn npf_rule_setcode "nl_rule_t *rl" "int type" "const void *code" "size_t sz"
|
||||
.Ft bool
|
||||
.Fn npf_rule_exists_p "nl_config_t *ncf" "const char *name"
|
||||
.Ft int
|
||||
.Fn npf_rule_insert "nl_config_t *ncf" " nl_rule_t *parent" \
|
||||
"nl_rule_t *rl" "pri_t pri"
|
||||
.Ft int
|
||||
.Fn npf_rule_setproc "nl_config_t *ncf" "nl_rule_t *rl" "const char *name"
|
||||
.Ft void
|
||||
.Fn npf_rule_destroy "nl_rule_t *rl"
|
||||
.\" ---
|
||||
.Ft nl_rproc_t *
|
||||
.Fn npf_rproc_create "char *name"
|
||||
.Ft bool
|
||||
.Fn npf_rproc_exists_p "nl_config_t *ncf" "const char *name"
|
||||
.Ft int
|
||||
.Fn npf_rproc_insert "nl_config_t *ncf" "nl_rproc_t *rp"
|
||||
.\" ---
|
||||
.Ft nl_nat_t *
|
||||
.Fn npf_nat_create "int type" "int flags" "u_int if_idx" \
|
||||
"npf_addr_t *addr" "int af" "in_port_t port"
|
||||
.Ft int
|
||||
.Fn npf_nat_insert "nl_config_t *ncf" "nl_nat_t *nt" "pri_t pri"
|
||||
.\" ---
|
||||
.Ft nl_table_t *
|
||||
.Fn npf_table_create "int index" "int type"
|
||||
.Ft int
|
||||
.Fn npf_table_add_entry "nl_table_t *tl" "in_addr_t addr" "in_addr_t mask"
|
||||
.Fa bool
|
||||
.Fn npf_table_exists_p "nl_config_t *ncf" "u_int tid"
|
||||
.Ft int
|
||||
.Fn npf_table_insert "nl_config_t *ncf" "nl_table_t *tl"
|
||||
.Ft void
|
||||
.Fn npf_table_destroy "nl_table_t *tl"
|
||||
.\" ---
|
||||
.Ft int
|
||||
.Fn npf_update_rule "int fd" "char *rname" "nl_rule_t *rl"
|
||||
.Ft int
|
||||
.Fn npf_sessions_send "int fd" "const char *fpath"
|
||||
.Ft int
|
||||
.Fn npf_sessions_recv "int fd" "const char *fpath"
|
||||
.\" -----
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
library provides an interface to create an NPF configuration having rules,
|
||||
tables, procedures, or translation policies.
|
||||
The configuration can be submitted to the kernel.
|
||||
.\" -----
|
||||
.Sh CONFIGURATION
|
||||
.Bl -tag -width 4n
|
||||
.It Fn npf_config_create
|
||||
Create a configuration.
|
||||
.It Fn npf_config_submit
|
||||
Submit configuration to the kernel.
|
||||
.It Fn npf_config_destroy
|
||||
Destroy the configuration.
|
||||
.El
|
||||
.\" ---
|
||||
.Sh RULE INTERFACE
|
||||
.Bl -tag -width 4n
|
||||
.It Fn npf_rule_create
|
||||
Create a rule with a given name, attribute and priorty. Name can be NULL,
|
||||
in which case rule has no unique identifier. Otherwise, rules shall not
|
||||
have duplicate names. The following attributes, which can be ORed, are
|
||||
available:
|
||||
.Bl -tag -width indent
|
||||
.It Dv NPF_RULE_PASS
|
||||
Decision of this rule is "pass". If this attribute is not
|
||||
specified, then packet "block" (drop) is the default.
|
||||
.It Dv NPF_RULE_DEFAULT
|
||||
This a default rule in the ruleset. There can only be a
|
||||
single rule having this attribute set in the ruleset.
|
||||
.It Dv NPF_RULE_FINAL
|
||||
Indicates that on rule match, further processing of the
|
||||
ruleset should be stopped and this rule applied instantly.
|
||||
.It Dv NPF_RULE_KEEPSTATE
|
||||
Create a state (session) on match, track the connection and
|
||||
therefore pass the backwards stream without inspection.
|
||||
.It Dv NPF_RULE_RETRST
|
||||
Return TCP RST packet in a case of packet block.
|
||||
.It Dv NPF_RULE_RETICMP
|
||||
Return ICMP destination unreachable in a case of packet block.
|
||||
.It Dv NPF_RULE_IN
|
||||
Rule may match only if incoming packet.
|
||||
.It Dv NPF_RULE_OUT
|
||||
Rule may match only if outgoing packet.
|
||||
.El
|
||||
.Pp
|
||||
Interface is specified by
|
||||
.Fa if_idx ,
|
||||
which is a numeral representation of an
|
||||
interface, given by
|
||||
.Xr if_nametoindex 3 .
|
||||
Zero indicates any interface.
|
||||
.\" ---
|
||||
.It Fn npf_rule_setcode
|
||||
Assign compiled code for the rule specified by
|
||||
.Fa rl ,
|
||||
used for filter criteria.
|
||||
Pointer to the binary code is specified by
|
||||
.Fa code ,
|
||||
and size of the memory area by
|
||||
.Fa sz .
|
||||
Type of the code is specified by
|
||||
.Fa type .
|
||||
Currently, only n-code is supported and
|
||||
.Dv NPF_CODE_NCODE
|
||||
should be passed.
|
||||
.\" ---
|
||||
.It Fn npf_rule_insert
|
||||
Insert the rule into the set of parent rule specified by
|
||||
.Fa parent .
|
||||
If value of
|
||||
.Fa parent
|
||||
is NULL,
|
||||
then insert into the main ruleset.
|
||||
.Pp
|
||||
Priority is the order of the rule in the ruleset. Lower value means first
|
||||
to process, higher value - last to process. If multiple rules have the same
|
||||
priority - order is unspecified. A special constant
|
||||
.Dv NPF_PRI_NEXT
|
||||
may be passed to use the value of last used priority incremented by 1.
|
||||
.It npf_rule_setproc
|
||||
Set procedure for the specified rule.
|
||||
.It Fn npf_rule_destroy
|
||||
Destroy the given rule.
|
||||
.El
|
||||
.\" -----
|
||||
.Sh RULE PROCEDURE INTERFACE
|
||||
.Bl -tag -width 4n
|
||||
.It Fn npf_rproc_create
|
||||
Create a rule procedure with a given
|
||||
.Fa name .
|
||||
Name must be unique for each procedure.
|
||||
.It Fn npf_rproc_insert
|
||||
Insert rule procedure into the specified configuration.
|
||||
.El
|
||||
.\" -----
|
||||
.Sh TRANSLATION INTERFACE
|
||||
.Bl -tag -width 4n
|
||||
.It Fn npf_nat_create
|
||||
Create a NAT translation policy of a specified type.
|
||||
There are two types:
|
||||
.Bl -tag -width indent
|
||||
.It Dv NPF_NATIN
|
||||
Inbound NAT policy.
|
||||
.It Dv NPF_NATOUT
|
||||
Outbound NAT policy.
|
||||
.El
|
||||
.Pp
|
||||
A bi-directional NAT is obtained by combining two policies.
|
||||
The following flags are supported:
|
||||
.Bl -tag -width indent
|
||||
.It Dv NPF_NAT_PORTS
|
||||
Indicates to perform port translation.
|
||||
Otherwise, port translation is not performed and
|
||||
.Fa port
|
||||
is ignored.
|
||||
.It Dv NPF_NAT_PORTMAP
|
||||
Effective only if
|
||||
.Dv NPF_NAT_PORTS
|
||||
flag is set.
|
||||
Indicates to create a port map and select a random port for translation.
|
||||
Otherwise, port is translated to the value specified by
|
||||
.Fa port
|
||||
is used.
|
||||
.El
|
||||
.Pp
|
||||
Translation address is specified by
|
||||
.Fa addr ,
|
||||
and its family by
|
||||
.Fa fa.
|
||||
Family must be either
|
||||
.Dv AF_INET
|
||||
for IPv4 or
|
||||
.Dv AF_INET6
|
||||
for IPv6 address.
|
||||
.It Fn npf_nat_insert
|
||||
Insert NAT policy, its rule, into the specified configuration.
|
||||
.El
|
||||
.\" -----
|
||||
.Sh TABLE INTERFACE
|
||||
.Bl -tag -width 4n
|
||||
.It Fn npf_table_create
|
||||
Create NPF table of specified type.
|
||||
The following types are supported:
|
||||
.Bl -tag -width indent
|
||||
.It Dv NPF_TABLE_HASH
|
||||
Indicates to use hash table for storage.
|
||||
.It Dv NPF_TABLE_RBTREE
|
||||
Indicates to use red-black tree for storage.
|
||||
Table is identified by
|
||||
.Fa index ,
|
||||
which should be in the range between 1 and
|
||||
.Dv NPF_MAX_TABLE_ID .
|
||||
.El
|
||||
.It Fn npf_table_add_entry
|
||||
Add an entry of IPv4 address and mask, specified by
|
||||
.Fa addr
|
||||
and
|
||||
.Fa mask ,
|
||||
to the table specified by
|
||||
.Fa tl .
|
||||
.It Fn npf_table_exists_p
|
||||
Determine whether table with ID
|
||||
.Fa tid
|
||||
exists in the configuration
|
||||
.Fa ncf .
|
||||
Return
|
||||
.Dv true
|
||||
if exists, and
|
||||
.Dv false
|
||||
otherwise.
|
||||
.It Fn npf_table_insert
|
||||
Insert table into set of configuration.
|
||||
Routine performs a check for duplicate table ID.
|
||||
.It Fn npf_table_destroy
|
||||
Destroy the specified table.
|
||||
.El
|
||||
.\" -----
|
||||
.Sh TABLE INTERFACE
|
||||
.Bl -tag -width 4n
|
||||
.It Fn npf_update_rule
|
||||
.It Fn npf_sessions_send
|
||||
Read the file specified by
|
||||
.Fa fpath ,
|
||||
and send sessions saved in it to the kernel.
|
||||
.It Fn npf_sessions_recv
|
||||
Receive currently loaded session from the kernel, and save them to a file
|
||||
specified by
|
||||
.Fa fpath .
|
||||
.El
|
||||
.\" -----
|
||||
.Sh SEE ALSO
|
||||
.Xr npfctl 8 ,
|
||||
.Xr npf_ncode 9
|
||||
.Sh HISTORY
|
||||
NPF library first appeared in
|
||||
.Nx 6.0 .
|
|
@ -0,0 +1,544 @@
|
|||
/* $NetBSD: npf.c,v 1.1 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This material is based upon work partially supported by The
|
||||
* NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.1 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <prop/proplib.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
|
||||
#define _NPF_PRIVATE
|
||||
#include "npf.h"
|
||||
|
||||
struct nl_config {
|
||||
/* Rules, translations, tables, procedures. */
|
||||
prop_array_t ncf_rules_list;
|
||||
prop_array_t ncf_rproc_list;
|
||||
prop_array_t ncf_table_list;
|
||||
prop_array_t ncf_nat_list;
|
||||
/* Priority counters. */
|
||||
pri_t ncf_rule_pri;
|
||||
pri_t ncf_nat_pri;
|
||||
};
|
||||
|
||||
struct nl_rule {
|
||||
prop_dictionary_t nrl_dict;
|
||||
};
|
||||
|
||||
struct nl_rproc {
|
||||
prop_dictionary_t nrp_dict;
|
||||
};
|
||||
|
||||
struct nl_table {
|
||||
prop_dictionary_t ntl_dict;
|
||||
};
|
||||
|
||||
/*
|
||||
* CONFIGURATION INTERFACE.
|
||||
*/
|
||||
|
||||
nl_config_t *
|
||||
npf_config_create(void)
|
||||
{
|
||||
nl_config_t *ncf;
|
||||
|
||||
ncf = malloc(sizeof(nl_config_t));
|
||||
if (ncf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ncf->ncf_rules_list = prop_array_create();
|
||||
ncf->ncf_rproc_list = prop_array_create();
|
||||
ncf->ncf_table_list = prop_array_create();
|
||||
ncf->ncf_nat_list = prop_array_create();
|
||||
|
||||
ncf->ncf_rule_pri = 1;
|
||||
ncf->ncf_nat_pri = 1;
|
||||
|
||||
return ncf;
|
||||
}
|
||||
|
||||
int
|
||||
npf_config_submit(nl_config_t *ncf, int fd)
|
||||
{
|
||||
prop_dictionary_t npf_dict;
|
||||
int error = 0;
|
||||
|
||||
npf_dict = prop_dictionary_create();
|
||||
if (npf_dict == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
prop_dictionary_set(npf_dict, "rules", ncf->ncf_rules_list);
|
||||
prop_dictionary_set(npf_dict, "rprocs", ncf->ncf_rproc_list);
|
||||
prop_dictionary_set(npf_dict, "tables", ncf->ncf_table_list);
|
||||
prop_dictionary_set(npf_dict, "translation", ncf->ncf_nat_list);
|
||||
|
||||
#ifndef _NPF_TESTING
|
||||
error = prop_dictionary_send_ioctl(npf_dict, fd, IOC_NPF_RELOAD);
|
||||
#else
|
||||
if (!prop_dictionary_externalize_to_file(npf_dict, "./npf.plist")) {
|
||||
error = errno;
|
||||
}
|
||||
#endif
|
||||
prop_object_release(npf_dict);
|
||||
return error;
|
||||
}
|
||||
|
||||
void
|
||||
npf_config_destroy(nl_config_t *ncf)
|
||||
{
|
||||
|
||||
prop_object_release(ncf->ncf_rules_list);
|
||||
prop_object_release(ncf->ncf_rproc_list);
|
||||
prop_object_release(ncf->ncf_table_list);
|
||||
prop_object_release(ncf->ncf_nat_list);
|
||||
free(ncf);
|
||||
}
|
||||
|
||||
static bool
|
||||
_npf_prop_array_lookup(prop_array_t array, const char *key, const char *name)
|
||||
{
|
||||
prop_dictionary_t dict;
|
||||
prop_object_iterator_t it;
|
||||
|
||||
it = prop_array_iterator(array);
|
||||
while ((dict = prop_object_iterator_next(it)) != NULL) {
|
||||
const char *lname;
|
||||
prop_dictionary_get_cstring_nocopy(dict, key, &lname);
|
||||
if (strcmp(name, lname) == 0)
|
||||
break;
|
||||
}
|
||||
prop_object_iterator_release(it);
|
||||
return dict ? true : false;
|
||||
}
|
||||
|
||||
/*
|
||||
* RULE INTERFACE.
|
||||
*/
|
||||
|
||||
nl_rule_t *
|
||||
npf_rule_create(const char *name, uint32_t attr, u_int if_idx)
|
||||
{
|
||||
prop_dictionary_t rldict;
|
||||
nl_rule_t *rl;
|
||||
|
||||
rl = malloc(sizeof(nl_rule_t));
|
||||
if (rl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
rldict = prop_dictionary_create();
|
||||
if (rldict == NULL) {
|
||||
free(rl);
|
||||
return NULL;
|
||||
}
|
||||
if (name) {
|
||||
prop_dictionary_set_cstring(rldict, "name", name);
|
||||
}
|
||||
prop_dictionary_set_uint32(rldict, "attributes", attr);
|
||||
|
||||
if (if_idx) {
|
||||
prop_dictionary_set_uint32(rldict, "interface", if_idx);
|
||||
}
|
||||
rl->nrl_dict = rldict;
|
||||
return rl;
|
||||
}
|
||||
|
||||
int
|
||||
npf_rule_setcode(nl_rule_t *rl, int type, const void *code, size_t sz)
|
||||
{
|
||||
prop_dictionary_t rldict = rl->nrl_dict;
|
||||
prop_data_t cdata;
|
||||
|
||||
if (type != NPF_CODE_NCODE) {
|
||||
return ENOTSUP;
|
||||
}
|
||||
cdata = prop_data_create_data(code, sz);
|
||||
if (cdata == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
prop_dictionary_set(rldict, "ncode", cdata);
|
||||
prop_object_release(cdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
npf_rule_setproc(nl_config_t *ncf, nl_rule_t *rl, const char *name)
|
||||
{
|
||||
prop_dictionary_t rldict = rl->nrl_dict;
|
||||
|
||||
if (!npf_rproc_exists_p(ncf, name)) {
|
||||
return ENOENT;
|
||||
}
|
||||
prop_dictionary_set_cstring(rldict, "rproc", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
npf_rule_exists_p(nl_config_t *ncf, const char *name)
|
||||
{
|
||||
|
||||
return _npf_prop_array_lookup(ncf->ncf_rules_list, "name", name);
|
||||
}
|
||||
|
||||
int
|
||||
npf_rule_insert(nl_config_t *ncf, nl_rule_t *parent, nl_rule_t *rl, pri_t pri)
|
||||
{
|
||||
prop_dictionary_t rldict = rl->nrl_dict;
|
||||
prop_array_t rlset;
|
||||
|
||||
if (pri == NPF_PRI_NEXT) {
|
||||
pri = ncf->ncf_rule_pri++;
|
||||
} else if (ncf) {
|
||||
ncf->ncf_rule_pri = pri + 1;
|
||||
}
|
||||
prop_dictionary_set_int32(rldict, "priority", pri);
|
||||
|
||||
if (parent) {
|
||||
prop_dictionary_t pdict = parent->nrl_dict;
|
||||
rlset = prop_dictionary_get(pdict, "subrules");
|
||||
if (rlset == NULL) {
|
||||
rlset = prop_array_create();
|
||||
prop_dictionary_set(pdict, "subrules", rlset);
|
||||
prop_object_release(rlset);
|
||||
}
|
||||
} else {
|
||||
rlset = ncf->ncf_rules_list;
|
||||
}
|
||||
prop_array_add(rlset, rldict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
npf_rule_destroy(nl_rule_t *rl)
|
||||
{
|
||||
|
||||
prop_object_release(rl->nrl_dict);
|
||||
free(rl);
|
||||
}
|
||||
|
||||
/*
|
||||
* RULE PROCEDURE INTERFACE.
|
||||
*/
|
||||
|
||||
nl_rproc_t *
|
||||
npf_rproc_create(const char *name)
|
||||
{
|
||||
prop_dictionary_t rpdict;
|
||||
nl_rproc_t *nrp;
|
||||
|
||||
nrp = malloc(sizeof(nl_rproc_t));
|
||||
if (nrp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
rpdict = prop_dictionary_create();
|
||||
if (rpdict == NULL) {
|
||||
free(nrp);
|
||||
return NULL;
|
||||
}
|
||||
prop_dictionary_set_cstring(rpdict, "name", name);
|
||||
nrp->nrp_dict = rpdict;
|
||||
return nrp;
|
||||
}
|
||||
|
||||
bool
|
||||
npf_rproc_exists_p(nl_config_t *ncf, const char *name)
|
||||
{
|
||||
|
||||
return _npf_prop_array_lookup(ncf->ncf_rproc_list, "name", name);
|
||||
}
|
||||
|
||||
int
|
||||
_npf_rproc_setnorm(nl_rproc_t *rp, bool rnd, bool no_df, int minttl, int maxmss)
|
||||
{
|
||||
prop_dictionary_t rpdict = rp->nrp_dict;
|
||||
uint32_t attr;
|
||||
|
||||
prop_dictionary_set_bool(rpdict, "randomize-id", rnd);
|
||||
prop_dictionary_set_bool(rpdict, "no-df", no_df);
|
||||
prop_dictionary_set_uint32(rpdict, "min-ttl", minttl);
|
||||
prop_dictionary_set_uint32(rpdict, "max-mss", maxmss);
|
||||
|
||||
prop_dictionary_get_uint32(rpdict, "flags", &attr);
|
||||
prop_dictionary_set_uint32(rpdict, "flags", attr | NPF_RPROC_NORMALIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_npf_rproc_setlog(nl_rproc_t *rp, u_int if_idx)
|
||||
{
|
||||
prop_dictionary_t rpdict = rp->nrp_dict;
|
||||
uint32_t attr;
|
||||
|
||||
prop_dictionary_set_uint32(rpdict, "log-interface", if_idx);
|
||||
|
||||
prop_dictionary_get_uint32(rpdict, "flags", &attr);
|
||||
prop_dictionary_set_uint32(rpdict, "flags", attr | NPF_RPROC_LOG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
npf_rproc_insert(nl_config_t *ncf, nl_rproc_t *rp)
|
||||
{
|
||||
prop_dictionary_t rpdict = rp->nrp_dict;
|
||||
const char *name;
|
||||
|
||||
if (!prop_dictionary_get_cstring_nocopy(rpdict, "name", &name)) {
|
||||
return EINVAL;
|
||||
}
|
||||
if (npf_rproc_exists_p(ncf, name)) {
|
||||
return EEXIST;
|
||||
}
|
||||
prop_array_add(ncf->ncf_rproc_list, rpdict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TRANSLATION INTERFACE.
|
||||
*/
|
||||
|
||||
nl_nat_t *
|
||||
npf_nat_create(int type, int flags, u_int if_idx,
|
||||
npf_addr_t *addr, int af, in_port_t port)
|
||||
{
|
||||
nl_rule_t *rl;
|
||||
prop_dictionary_t rldict;
|
||||
prop_data_t addrdat;
|
||||
uint32_t attr;
|
||||
size_t sz;
|
||||
|
||||
if (af == AF_INET) {
|
||||
sz = sizeof(struct in_addr);
|
||||
} else if (af == AF_INET6) {
|
||||
sz = sizeof(struct in6_addr);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
attr = NPF_RULE_PASS | NPF_RULE_FINAL |
|
||||
(type == NPF_NATOUT) ? NPF_RULE_OUT : NPF_RULE_IN;
|
||||
|
||||
/* Create a rule for NAT policy. Next, will add translation data. */
|
||||
rl = npf_rule_create(NULL, attr, if_idx);
|
||||
if (rl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
rldict = rl->nrl_dict;
|
||||
|
||||
/* Translation type and flags. */
|
||||
prop_dictionary_set_int32(rldict, "type", type);
|
||||
prop_dictionary_set_uint32(rldict, "flags", flags);
|
||||
|
||||
/* Translation IP. */
|
||||
addrdat = prop_data_create_data(addr, sz);
|
||||
if (addrdat == NULL) {
|
||||
npf_rule_destroy(rl);
|
||||
return NULL;
|
||||
}
|
||||
prop_dictionary_set(rldict, "translation-ip", addrdat);
|
||||
prop_object_release(addrdat);
|
||||
|
||||
/* Translation port (for redirect case). */
|
||||
prop_dictionary_set_uint16(rldict, "translation-port", port);
|
||||
|
||||
return (nl_nat_t *)rl;
|
||||
}
|
||||
|
||||
int
|
||||
npf_nat_insert(nl_config_t *ncf, nl_nat_t *nt, pri_t pri)
|
||||
{
|
||||
prop_dictionary_t rldict = nt->nrl_dict;
|
||||
|
||||
if (pri == NPF_PRI_NEXT) {
|
||||
pri = ncf->ncf_nat_pri++;
|
||||
} else {
|
||||
ncf->ncf_nat_pri = pri + 1;
|
||||
}
|
||||
prop_dictionary_set_int32(rldict, "priority", pri);
|
||||
prop_array_add(ncf->ncf_nat_list, rldict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TABLE INTERFACE.
|
||||
*/
|
||||
|
||||
nl_table_t *
|
||||
npf_table_create(int id, int type)
|
||||
{
|
||||
prop_dictionary_t tldict;
|
||||
prop_array_t tblents;
|
||||
nl_table_t *tl;
|
||||
|
||||
tl = malloc(sizeof(nl_table_t));
|
||||
if (tl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
tldict = prop_dictionary_create();
|
||||
if (tldict == NULL) {
|
||||
free(tl);
|
||||
return NULL;
|
||||
}
|
||||
prop_dictionary_set_uint32(tldict, "id", id);
|
||||
prop_dictionary_set_int32(tldict, "type", type);
|
||||
|
||||
tblents = prop_array_create();
|
||||
if (tblents == NULL) {
|
||||
prop_object_release(tldict);
|
||||
free(tl);
|
||||
return NULL;
|
||||
}
|
||||
prop_dictionary_set(tldict, "entries", tblents);
|
||||
prop_object_release(tblents);
|
||||
|
||||
tl->ntl_dict = tldict;
|
||||
return tl;
|
||||
}
|
||||
|
||||
int
|
||||
npf_table_add_entry(nl_table_t *tl, in_addr_t addr, in_addr_t mask)
|
||||
{
|
||||
prop_dictionary_t tldict = tl->ntl_dict, entdict;
|
||||
prop_array_t tblents;
|
||||
|
||||
/* Create the table entry. */
|
||||
entdict = prop_dictionary_create();
|
||||
if (entdict) {
|
||||
return ENOMEM;
|
||||
}
|
||||
prop_dictionary_set_uint32(entdict, "addr", addr);
|
||||
prop_dictionary_set_uint32(entdict, "mask", mask);
|
||||
|
||||
/* Insert the entry. */
|
||||
tblents = prop_dictionary_get(tldict, "entries");
|
||||
prop_array_add(tblents, entdict);
|
||||
prop_object_release(entdict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
npf_table_exists_p(nl_config_t *ncf, u_int tid)
|
||||
{
|
||||
prop_dictionary_t tldict;
|
||||
prop_object_iterator_t it;
|
||||
|
||||
it = prop_array_iterator(ncf->ncf_table_list);
|
||||
while ((tldict = prop_object_iterator_next(it)) != NULL) {
|
||||
u_int i;
|
||||
if (prop_dictionary_get_uint32(tldict, "id", &i) && tid == i)
|
||||
break;
|
||||
}
|
||||
prop_object_iterator_release(it);
|
||||
return tldict ? true : false;
|
||||
}
|
||||
|
||||
int
|
||||
npf_table_insert(nl_config_t *ncf, nl_table_t *tl)
|
||||
{
|
||||
prop_dictionary_t tldict = tl->ntl_dict;
|
||||
u_int tid;
|
||||
|
||||
if (!prop_dictionary_get_uint32(tldict, "id", &tid)) {
|
||||
return EINVAL;
|
||||
}
|
||||
if (npf_table_exists_p(ncf, tid)) {
|
||||
return EEXIST;
|
||||
}
|
||||
prop_array_add(ncf->ncf_table_list, tldict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
npf_table_destroy(nl_table_t *tl)
|
||||
{
|
||||
|
||||
prop_object_release(tl->ntl_dict);
|
||||
free(tl);
|
||||
}
|
||||
|
||||
/*
|
||||
* MISC.
|
||||
*/
|
||||
|
||||
int
|
||||
npf_update_rule(int fd, char *rname, nl_rule_t *rl)
|
||||
{
|
||||
prop_dictionary_t rldict = rl->nrl_dict;
|
||||
int error;
|
||||
|
||||
error = prop_dictionary_send_ioctl(rldict, fd, IOC_NPF_UPDATE_RULE);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
npf_sessions_recv(int fd, const char *fpath)
|
||||
{
|
||||
prop_dictionary_t sdict;
|
||||
int error;
|
||||
|
||||
error = prop_dictionary_recv_ioctl(fd, IOC_NPF_SESSIONS_SAVE, &sdict);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
if (!prop_dictionary_externalize_to_file(sdict, fpath)) {
|
||||
error = errno;
|
||||
}
|
||||
prop_object_release(sdict);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
npf_sessions_send(int fd, const char *fpath)
|
||||
{
|
||||
prop_dictionary_t sdict;
|
||||
int error;
|
||||
|
||||
if (fpath) {
|
||||
sdict = prop_dictionary_internalize_from_file(fpath);
|
||||
if (sdict == NULL) {
|
||||
return errno;
|
||||
}
|
||||
} else {
|
||||
/* Empty: will flush the sessions. */
|
||||
prop_array_t selist = prop_array_create();
|
||||
sdict = prop_dictionary_create();
|
||||
prop_dictionary_set(sdict, "session-list", selist);
|
||||
prop_object_release(selist);
|
||||
}
|
||||
error = prop_dictionary_send_ioctl(sdict, fd, IOC_NPF_SESSIONS_LOAD);
|
||||
prop_object_release(sdict);
|
||||
return error;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/* $NetBSD: npf.h,v 1.1 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This material is based upon work partially supported by The
|
||||
* NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _NPF_LIB_H_
|
||||
#define _NPF_LIB_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <net/npf.h>
|
||||
|
||||
#ifdef _NPF_TESTING
|
||||
#include "testing.h"
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct nl_config;
|
||||
struct nl_rule;
|
||||
struct nl_rproc;
|
||||
struct nl_table;
|
||||
|
||||
typedef struct nl_config nl_config_t;
|
||||
typedef struct nl_rule nl_rule_t;
|
||||
typedef struct nl_rproc nl_rproc_t;
|
||||
typedef struct nl_table nl_table_t;
|
||||
|
||||
typedef struct nl_rule nl_nat_t;
|
||||
|
||||
#define NPF_CODE_NCODE 1
|
||||
#define NPF_CODE_BPF 2
|
||||
|
||||
#define NPF_PRI_NEXT (-1)
|
||||
|
||||
#define NPF_MAX_TABLE_ID (16)
|
||||
|
||||
nl_config_t * npf_config_create(void);
|
||||
int npf_config_submit(nl_config_t *, int);
|
||||
void npf_config_destroy(nl_config_t *);
|
||||
|
||||
nl_rule_t * npf_rule_create(const char *, uint32_t, u_int);
|
||||
int npf_rule_setcode(nl_rule_t *, int, const void *, size_t);
|
||||
int npf_rule_setproc(nl_config_t *, nl_rule_t *, const char *);
|
||||
bool npf_rule_exists_p(nl_config_t *, const char *);
|
||||
int npf_rule_insert(nl_config_t *, nl_rule_t *, nl_rule_t *, pri_t);
|
||||
void npf_rule_destroy(nl_rule_t *);
|
||||
|
||||
nl_rproc_t * npf_rproc_create(const char *);
|
||||
bool npf_rproc_exists_p(nl_config_t *, const char *);
|
||||
int npf_rproc_insert(nl_config_t *, nl_rproc_t *);
|
||||
|
||||
#ifdef _NPF_PRIVATE
|
||||
int _npf_rproc_setnorm(nl_rproc_t *, bool, bool, int, int);
|
||||
int _npf_rproc_setlog(nl_rproc_t *, u_int);
|
||||
#endif
|
||||
|
||||
nl_nat_t * npf_nat_create(int, int, u_int, npf_addr_t *, int, in_port_t);
|
||||
int npf_nat_insert(nl_config_t *, nl_nat_t *, pri_t);
|
||||
|
||||
nl_table_t * npf_table_create(int, int);
|
||||
int npf_table_add_entry(nl_table_t *, in_addr_t, in_addr_t);
|
||||
bool npf_table_exists_p(nl_config_t *, u_int);
|
||||
int npf_table_insert(nl_config_t *, nl_table_t *);
|
||||
void npf_table_destroy(nl_table_t *);
|
||||
|
||||
int npf_update_rule(int, char *, nl_rule_t *);
|
||||
int npf_sessions_send(int, const char *);
|
||||
int npf_sessions_recv(int, const char *);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _NPF_LIB_H_ */
|
|
@ -0,0 +1,5 @@
|
|||
# $NetBSD: shlib_version,v 1.1 2011/02/02 02:20:25 rmind Exp $
|
||||
# Remember to update distrib/sets/lists/base/shl.* when changing
|
||||
#
|
||||
major=0
|
||||
minor=0
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf.c,v 1.3 2011/01/18 20:33:45 rmind Exp $ */
|
||||
/* $NetBSD: npf.c,v 1.4 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.3 2011/01/18 20:33:45 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf.c,v 1.4 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -221,6 +221,9 @@ npf_dev_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
|
|||
case IOC_NPF_SESSIONS_LOAD:
|
||||
error = npfctl_sessions_load(cmd, data);
|
||||
break;
|
||||
case IOC_NPF_UPDATE_RULE:
|
||||
error = npfctl_update_rule(cmd, data);
|
||||
break;
|
||||
default:
|
||||
error = ENOTTY;
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf.h,v 1.6 2011/01/18 20:33:45 rmind Exp $ */
|
||||
/* $NetBSD: npf.h,v 1.7 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -33,8 +33,8 @@
|
|||
* Public NPF interfaces.
|
||||
*/
|
||||
|
||||
#ifndef _NPF_H_
|
||||
#define _NPF_H_
|
||||
#ifndef _NPF_NET_H_
|
||||
#define _NPF_NET_H_
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
@ -42,6 +42,9 @@
|
|||
#include <sys/ioctl.h>
|
||||
#include <prop/proplib.h>
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifdef _NPF_TESTING
|
||||
#include "testing.h"
|
||||
#endif
|
||||
|
@ -49,43 +52,32 @@
|
|||
#define NPF_VERSION 1
|
||||
|
||||
/*
|
||||
* Public declarations.
|
||||
* Public declarations and definitions.
|
||||
*/
|
||||
|
||||
struct npf_ruleset;
|
||||
struct npf_rule;
|
||||
struct npf_hook;
|
||||
|
||||
typedef struct npf_rproc npf_rproc_t;
|
||||
typedef struct npf_ruleset npf_ruleset_t;
|
||||
typedef struct npf_rule npf_rule_t;
|
||||
typedef struct npf_hook npf_hook_t;
|
||||
|
||||
/*
|
||||
* Public definitions.
|
||||
*/
|
||||
|
||||
typedef void nbuf_t;
|
||||
/* Storage of address (both for IPv4 and IPv6). */
|
||||
typedef struct in6_addr npf_addr_t;
|
||||
|
||||
#if defined(_KERNEL) || defined(_NPF_TESTING)
|
||||
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
/* Network buffer. */
|
||||
typedef void nbuf_t;
|
||||
|
||||
struct npf_rproc;
|
||||
struct npf_hook;
|
||||
|
||||
typedef struct npf_rproc npf_rproc_t;
|
||||
typedef struct npf_hook npf_hook_t;
|
||||
|
||||
/*
|
||||
* Packet information cache.
|
||||
*/
|
||||
#include <netinet/ip.h>
|
||||
#include <netinet/ip6.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
|
||||
/*
|
||||
* Storage of address, both IPv4 and IPv6.
|
||||
*/
|
||||
typedef struct in6_addr npf_addr_t;
|
||||
|
||||
/*
|
||||
* Packet information cache.
|
||||
*/
|
||||
|
||||
#define NPC_IP4 0x01 /* Indicates fetched IPv4 header. */
|
||||
#define NPC_IP6 0x02 /* Indicates IPv6 header. */
|
||||
#define NPC_IPFRAG 0x04 /* IPv4 fragment. */
|
||||
|
@ -146,15 +138,11 @@ int nbuf_store_datum(nbuf_t *, void *, size_t, void *);
|
|||
int nbuf_add_tag(nbuf_t *, uint32_t, uint32_t);
|
||||
int nbuf_find_tag(nbuf_t *, uint32_t, void **);
|
||||
|
||||
/* Ruleset interface. */
|
||||
npf_rule_t * npf_rule_alloc(prop_dictionary_t, npf_rproc_t *, void *, size_t);
|
||||
void npf_rule_free(npf_rule_t *);
|
||||
void npf_activate_rule(npf_rule_t *);
|
||||
void npf_deactivate_rule(npf_rule_t *);
|
||||
|
||||
#if 0
|
||||
npf_hook_t * npf_hook_register(npf_rule_t *,
|
||||
void (*)(npf_cache_t *, nbuf_t *, void *), void *);
|
||||
void npf_hook_unregister(npf_rule_t *, npf_hook_t *);
|
||||
#endif
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
|
@ -250,5 +238,6 @@ typedef enum {
|
|||
#define IOC_NPF_STATS _IOW('N', 104, void *)
|
||||
#define IOC_NPF_SESSIONS_SAVE _IOR('N', 105, struct plistref)
|
||||
#define IOC_NPF_SESSIONS_LOAD _IOW('N', 106, struct plistref)
|
||||
#define IOC_NPF_UPDATE_RULE _IOW('N', 107, struct plistref)
|
||||
|
||||
#endif /* _NPF_H_ */
|
||||
#endif /* _NPF_NET_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_ctl.c,v 1.5 2011/01/18 20:33:45 rmind Exp $ */
|
||||
/* $NetBSD: npf_ctl.c,v 1.6 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.5 2011/01/18 20:33:45 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_ctl.c,v 1.6 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/conf.h>
|
||||
|
@ -68,12 +68,11 @@ npfctl_switch(void *data)
|
|||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
static int __noinline
|
||||
npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables)
|
||||
{
|
||||
prop_object_iterator_t it;
|
||||
prop_dictionary_t tbldict;
|
||||
prop_object_t obj;
|
||||
int error = 0;
|
||||
|
||||
/* Tables - array. */
|
||||
|
@ -96,10 +95,9 @@ npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables)
|
|||
}
|
||||
|
||||
/* Table ID and type. */
|
||||
obj = prop_dictionary_get(tbldict, "id");
|
||||
tid = (u_int)prop_number_integer_value(obj);
|
||||
obj = prop_dictionary_get(tbldict, "type");
|
||||
type = (int)prop_number_integer_value(obj);
|
||||
prop_dictionary_get_uint32(tbldict, "id", &tid);
|
||||
prop_dictionary_get_int32(tbldict, "type", &type);
|
||||
|
||||
/* Validate them. */
|
||||
error = npf_table_check(tblset, tid, type);
|
||||
if (error)
|
||||
|
@ -124,13 +122,9 @@ npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables)
|
|||
while ((ent = prop_object_iterator_next(eit)) != NULL) {
|
||||
in_addr_t addr, mask; /* XXX: IPv6 */
|
||||
|
||||
/* Address. */
|
||||
obj = prop_dictionary_get(ent, "addr");
|
||||
addr = (in_addr_t)prop_number_integer_value(obj);
|
||||
/* Mask. */
|
||||
obj = prop_dictionary_get(ent, "mask");
|
||||
mask = (in_addr_t)prop_number_integer_value(obj);
|
||||
/* Add a table entry. */
|
||||
/* Get address and mask. Add a table entry. */
|
||||
prop_dictionary_get_uint32(ent, "addr", &addr);
|
||||
prop_dictionary_get_uint32(ent, "mask", &mask);
|
||||
error = npf_table_add_v4cidr(tblset, tid, addr, mask);
|
||||
if (error)
|
||||
break;
|
||||
|
@ -147,41 +141,36 @@ npf_mk_tables(npf_tableset_t *tblset, prop_array_t tables)
|
|||
}
|
||||
|
||||
static npf_rproc_t *
|
||||
npf_mk_rproc(prop_array_t rprocs, uint64_t rproc_id)
|
||||
npf_mk_rproc(prop_array_t rprocs, const char *rpname)
|
||||
{
|
||||
prop_object_iterator_t it;
|
||||
prop_dictionary_t rpdict;
|
||||
prop_object_t obj;
|
||||
npf_rproc_t *rp;
|
||||
uint64_t id;
|
||||
|
||||
it = prop_array_iterator(rprocs);
|
||||
while ((rpdict = prop_object_iterator_next(it)) != NULL) {
|
||||
obj = prop_dictionary_get(rpdict, "id");
|
||||
id = prop_number_unsigned_integer_value(obj);
|
||||
if (id == rproc_id)
|
||||
const char *iname;
|
||||
prop_dictionary_get_cstring_nocopy(rpdict, "name", &iname);
|
||||
if (strcmp(rpname, iname) == 0)
|
||||
break;
|
||||
}
|
||||
prop_object_iterator_release(it);
|
||||
if (rpdict == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
CTASSERT(sizeof(uintptr_t) <= sizeof(uint64_t));
|
||||
obj = prop_dictionary_get(rpdict, "rproc-ptr");
|
||||
if (obj == NULL) {
|
||||
if (!prop_dictionary_get_uint64(rpdict, "rproc-ptr", (uint64_t *)&rp)) {
|
||||
rp = npf_rproc_create(rpdict);
|
||||
prop_dictionary_set(rpdict, "rproc-ptr",
|
||||
prop_number_create_unsigned_integer((uintptr_t)rp));
|
||||
} else {
|
||||
rp = (void *)(uintptr_t)prop_number_unsigned_integer_value(obj);
|
||||
prop_dictionary_set_uint64(rpdict, "rproc-ptr",
|
||||
(uint64_t)(uintptr_t)rp);
|
||||
}
|
||||
return rp;
|
||||
}
|
||||
|
||||
static int
|
||||
npf_mk_singlerule(prop_dictionary_t rldict, npf_ruleset_t *rlset,
|
||||
prop_array_t rprocs, npf_rule_t **parent)
|
||||
static int __noinline
|
||||
npf_mk_singlerule(prop_dictionary_t rldict, prop_array_t rps, npf_rule_t **rl)
|
||||
{
|
||||
npf_rule_t *rl;
|
||||
const char *rnm;
|
||||
npf_rproc_t *rp;
|
||||
prop_object_t obj;
|
||||
size_t nc_size;
|
||||
|
@ -223,10 +212,8 @@ npf_mk_singlerule(prop_dictionary_t rldict, npf_ruleset_t *rlset,
|
|||
}
|
||||
|
||||
/* Check for rule procedure. */
|
||||
obj = prop_dictionary_get(rldict, "rproc-id");
|
||||
if (obj && rprocs) {
|
||||
uint64_t rproc_id = prop_number_unsigned_integer_value(obj);
|
||||
rp = npf_mk_rproc(rprocs, rproc_id);
|
||||
if (rps && prop_dictionary_get_cstring_nocopy(rldict, "rproc", &rnm)) {
|
||||
rp = npf_mk_rproc(rps, rnm);
|
||||
if (rp == NULL) {
|
||||
if (nc) {
|
||||
npf_ncode_free(nc, nc_size); /* XXX */
|
||||
|
@ -237,16 +224,35 @@ npf_mk_singlerule(prop_dictionary_t rldict, npf_ruleset_t *rlset,
|
|||
rp = NULL;
|
||||
}
|
||||
|
||||
/* Allocate and setup NPF rule. */
|
||||
rl = npf_rule_alloc(rldict, rp, nc, nc_size);
|
||||
npf_ruleset_insert(rlset, rl);
|
||||
if (parent) {
|
||||
*parent = rl;
|
||||
}
|
||||
/* Finally, allocate and return the rule. */
|
||||
*rl = npf_rule_alloc(rldict, rp, nc, nc_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
static int __noinline
|
||||
npf_mk_subrules(npf_ruleset_t *rlset, prop_array_t rules, prop_array_t rprocs)
|
||||
{
|
||||
prop_object_iterator_t it;
|
||||
prop_dictionary_t rldict;
|
||||
int error = 0;
|
||||
|
||||
if (prop_object_type(rules) != PROP_TYPE_ARRAY) {
|
||||
return EINVAL;
|
||||
}
|
||||
it = prop_array_iterator(rules);
|
||||
while ((rldict = prop_object_iterator_next(it)) != NULL) {
|
||||
npf_rule_t *rl;
|
||||
error = npf_mk_singlerule(rldict, rprocs, &rl);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
npf_ruleset_insert(rlset, rl);
|
||||
}
|
||||
prop_object_iterator_release(it);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int __noinline
|
||||
npf_mk_rules(npf_ruleset_t *rlset, prop_array_t rules, prop_array_t rprocs)
|
||||
{
|
||||
prop_object_iterator_t it;
|
||||
|
@ -260,44 +266,35 @@ npf_mk_rules(npf_ruleset_t *rlset, prop_array_t rules, prop_array_t rprocs)
|
|||
|
||||
it = prop_array_iterator(rprocs);
|
||||
while ((rpdict = prop_object_iterator_next(it)) != NULL) {
|
||||
if (prop_dictionary_get(rpdict, "rproc-ptr"))
|
||||
if (prop_dictionary_get(rpdict, "rproc-ptr")) {
|
||||
prop_object_iterator_release(it);
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
prop_object_iterator_release(it);
|
||||
|
||||
error = 0;
|
||||
it = prop_array_iterator(rules);
|
||||
while ((rldict = prop_object_iterator_next(it)) != NULL) {
|
||||
prop_object_iterator_t sit;
|
||||
prop_array_t subrules;
|
||||
prop_dictionary_t srldict;
|
||||
npf_rule_t *myrl;
|
||||
npf_ruleset_t *rlsetsub;
|
||||
npf_rule_t *rl;
|
||||
|
||||
/* Generate a single rule. */
|
||||
error = npf_mk_singlerule(rldict, rlset, rprocs, &myrl);
|
||||
if (error)
|
||||
error = npf_mk_singlerule(rldict, rprocs, &rl);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
npf_ruleset_insert(rlset, rl);
|
||||
|
||||
/* Check for subrules. */
|
||||
/* Check for sub-rules and generate, if any. */
|
||||
subrules = prop_dictionary_get(rldict, "subrules");
|
||||
if (subrules == NULL) {
|
||||
/* No subrules, next.. */
|
||||
continue;
|
||||
}
|
||||
/* Generate subrules, if any. */
|
||||
if (prop_object_type(subrules) != PROP_TYPE_ARRAY) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
sit = prop_array_iterator(subrules);
|
||||
while ((srldict = prop_object_iterator_next(sit)) != NULL) {
|
||||
/* For subrule, pass ruleset pointer of parent. */
|
||||
error = npf_mk_singlerule(srldict,
|
||||
npf_rule_subset(myrl), rprocs, NULL);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
prop_object_iterator_release(sit);
|
||||
rlsetsub = npf_rule_subset(rl);
|
||||
error = npf_mk_subrules(rlsetsub, subrules, rprocs);
|
||||
if (error)
|
||||
break;
|
||||
}
|
||||
|
@ -308,7 +305,7 @@ npf_mk_rules(npf_ruleset_t *rlset, prop_array_t rules, prop_array_t rprocs)
|
|||
return error;
|
||||
}
|
||||
|
||||
static int
|
||||
static int __noinline
|
||||
npf_mk_natlist(npf_ruleset_t *nset, prop_array_t natlist)
|
||||
{
|
||||
prop_object_iterator_t it;
|
||||
|
@ -335,9 +332,17 @@ npf_mk_natlist(npf_ruleset_t *nset, prop_array_t natlist)
|
|||
* NAT policies are standard rules, plus additional
|
||||
* information for translation. Make a rule.
|
||||
*/
|
||||
error = npf_mk_singlerule(natdict, nset, NULL, &rl);
|
||||
if (error)
|
||||
error = npf_mk_singlerule(natdict, NULL, &rl);
|
||||
if (error) {
|
||||
break;
|
||||
}
|
||||
npf_ruleset_insert(nset, rl);
|
||||
|
||||
/* If rule is named, it is a group with NAT policies. */
|
||||
if (prop_dictionary_get(natdict, "name") &&
|
||||
prop_dictionary_get(natdict, "subrules")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Allocate a new NAT policy and assign to the rule. */
|
||||
np = npf_nat_newpolicy(natdict, nset);
|
||||
|
@ -414,7 +419,6 @@ npfctl_reload(u_long cmd, void *data)
|
|||
rlset = NULL;
|
||||
nset = NULL;
|
||||
fail:
|
||||
prop_object_release(dict);
|
||||
/*
|
||||
* Note: destroy rulesets first, to drop references to the tableset.
|
||||
*/
|
||||
|
@ -428,6 +432,53 @@ fail:
|
|||
if (tblset) {
|
||||
npf_tableset_destroy(tblset);
|
||||
}
|
||||
prop_object_release(dict);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* npfctl_update_rule: reload a specific rule identified by the name.
|
||||
*/
|
||||
int
|
||||
npfctl_update_rule(u_long cmd, void *data)
|
||||
{
|
||||
const struct plistref *pref = data;
|
||||
prop_dictionary_t dict;
|
||||
prop_array_t subrules;
|
||||
prop_object_t obj;
|
||||
npf_ruleset_t *rlset;
|
||||
const char *name;
|
||||
int error;
|
||||
|
||||
#ifdef _KERNEL
|
||||
/* Retrieve and construct the rule. */
|
||||
error = prop_dictionary_copyin_ioctl(pref, cmd, &dict);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
#else
|
||||
dict = prop_dictionary_internalize_from_file(data);
|
||||
if (dict == NULL)
|
||||
return EINVAL;
|
||||
#endif
|
||||
/* Create the ruleset and construct sub-rules. */
|
||||
rlset = npf_ruleset_create();
|
||||
subrules = prop_dictionary_get(dict, "subrules");
|
||||
error = npf_mk_subrules(rlset, subrules, NULL);
|
||||
if (error) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Lookup the rule by name, and replace its subset (sub-rules). */
|
||||
obj = prop_dictionary_get(dict, "name");
|
||||
name = prop_string_cstring_nocopy(obj);
|
||||
if (npf_ruleset_replace(name, rlset) == NULL) {
|
||||
/* Not found. */
|
||||
error = ENOENT;
|
||||
out: /* Error path. */
|
||||
npf_ruleset_destroy(rlset);
|
||||
}
|
||||
prop_object_release(dict);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -546,6 +597,7 @@ npfctl_table(void *data)
|
|||
npf_ioctl_table_t *nct = data;
|
||||
int error;
|
||||
|
||||
npf_core_enter(); /* XXXSMP */
|
||||
switch (nct->nct_action) {
|
||||
case NPF_IOCTL_TBLENT_ADD:
|
||||
error = npf_table_add_v4cidr(NULL, nct->nct_tid,
|
||||
|
@ -562,5 +614,6 @@ npfctl_table(void *data)
|
|||
error = EINVAL;
|
||||
}
|
||||
}
|
||||
npf_core_exit(); /* XXXSMP */
|
||||
return error;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_handler.c,v 1.6 2011/01/18 20:33:45 rmind Exp $ */
|
||||
/* $NetBSD: npf_handler.c,v 1.7 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.6 2011/01/18 20:33:45 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_handler.c,v 1.7 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -83,6 +83,7 @@ npf_packet_handler(void *arg, struct mbuf **mp, ifnet_t *ifp, int di)
|
|||
nbuf_t *nbuf = *mp;
|
||||
npf_cache_t npc;
|
||||
npf_session_t *se;
|
||||
npf_ruleset_t *rlset;
|
||||
npf_rule_t *rl;
|
||||
npf_rproc_t *rp;
|
||||
int retfl, error;
|
||||
|
@ -125,8 +126,10 @@ npf_packet_handler(void *arg, struct mbuf **mp, ifnet_t *ifp, int di)
|
|||
goto pass;
|
||||
}
|
||||
|
||||
/* Inspect the ruleset using this packet, acquire the lock. */
|
||||
rl = npf_ruleset_inspect(&npc, nbuf, ifp, di, NPF_LAYER_3);
|
||||
/* Acquire the lock, inspect the ruleset using this packet. */
|
||||
npf_core_enter();
|
||||
rlset = npf_core_ruleset();
|
||||
rl = npf_ruleset_inspect(&npc, nbuf, rlset, ifp, di, NPF_LAYER_3);
|
||||
if (rl == NULL) {
|
||||
if (default_pass) {
|
||||
npf_stats_inc(NPF_STAT_PASS_DEFAULT);
|
||||
|
@ -169,7 +172,7 @@ block:
|
|||
* Perform rule procedure, if any.
|
||||
*/
|
||||
if (rp) {
|
||||
npf_rproc_run(&npc, nbuf, rp);
|
||||
npf_rproc_run(&npc, nbuf, rp, error);
|
||||
}
|
||||
out:
|
||||
/* Release the reference on session, or rule procedure. */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_impl.h,v 1.6 2011/01/18 20:33:45 rmind Exp $ */
|
||||
/* $NetBSD: npf_impl.h,v 1.7 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -37,6 +37,10 @@
|
|||
#ifndef _NPF_IMPL_H_
|
||||
#define _NPF_IMPL_H_
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_NPF_TESTING)
|
||||
#error "Kernel-level header only"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/hash.h>
|
||||
|
@ -59,14 +63,15 @@
|
|||
|
||||
/*
|
||||
* STRUCTURE DECLARATIONS.
|
||||
*
|
||||
* Note: ruleset interface declarations are public.
|
||||
*/
|
||||
|
||||
struct npf_ruleset;
|
||||
struct npf_rule;
|
||||
struct npf_nat;
|
||||
struct npf_rproc;
|
||||
struct npf_session;
|
||||
|
||||
typedef struct npf_ruleset npf_ruleset_t;
|
||||
typedef struct npf_rule npf_rule_t;
|
||||
typedef struct npf_nat npf_nat_t;
|
||||
typedef struct npf_alg npf_alg_t;
|
||||
typedef struct npf_natpolicy npf_natpolicy_t;
|
||||
|
@ -127,6 +132,7 @@ int npfctl_switch(void *);
|
|||
int npfctl_reload(u_long, void *);
|
||||
int npfctl_sessions_save(u_long, void *);
|
||||
int npfctl_sessions_load(u_long, void *);
|
||||
int npfctl_update_rule(u_long, void *);
|
||||
int npfctl_table(void *);
|
||||
|
||||
void npf_stats_inc(npf_stats_t);
|
||||
|
@ -204,13 +210,15 @@ void npf_ruleset_insert(npf_ruleset_t *, npf_rule_t *);
|
|||
void npf_ruleset_natreload(npf_ruleset_t *, npf_ruleset_t *);
|
||||
npf_rule_t * npf_ruleset_matchnat(npf_ruleset_t *, npf_natpolicy_t *);
|
||||
npf_rule_t * npf_ruleset_sharepm(npf_ruleset_t *, npf_natpolicy_t *);
|
||||
npf_rule_t * npf_ruleset_replace(const char *, npf_ruleset_t *);
|
||||
|
||||
npf_rule_t * npf_ruleset_match(npf_ruleset_t *, npf_cache_t *, nbuf_t *,
|
||||
ifnet_t *, const int, const int);
|
||||
npf_rule_t * npf_ruleset_inspect(npf_cache_t *, nbuf_t *,
|
||||
npf_rule_t * npf_ruleset_inspect(npf_cache_t *, nbuf_t *, npf_ruleset_t *,
|
||||
ifnet_t *, const int, const int);
|
||||
int npf_rule_apply(npf_cache_t *, nbuf_t *, npf_rule_t *, int *);
|
||||
|
||||
/* Rule interface. */
|
||||
npf_rule_t * npf_rule_alloc(prop_dictionary_t, npf_rproc_t *, void *, size_t);
|
||||
void npf_rule_free(npf_rule_t *);
|
||||
npf_ruleset_t * npf_rule_subset(npf_rule_t *);
|
||||
npf_natpolicy_t *npf_rule_getnat(const npf_rule_t *);
|
||||
void npf_rule_setnat(npf_rule_t *, npf_natpolicy_t *);
|
||||
|
@ -218,7 +226,7 @@ void npf_rule_setnat(npf_rule_t *, npf_natpolicy_t *);
|
|||
npf_rproc_t * npf_rproc_create(prop_dictionary_t);
|
||||
npf_rproc_t * npf_rproc_return(npf_rule_t *);
|
||||
void npf_rproc_release(npf_rproc_t *);
|
||||
void npf_rproc_run(npf_cache_t *, nbuf_t *, npf_rproc_t *);
|
||||
void npf_rproc_run(npf_cache_t *, nbuf_t *, npf_rproc_t *, int);
|
||||
|
||||
/* Session handling interface. */
|
||||
void npf_session_sysinit(void);
|
||||
|
@ -282,4 +290,4 @@ void npf_sessions_dump(void);
|
|||
void npf_state_dump(npf_state_t *);
|
||||
void npf_nat_dump(npf_nat_t *);
|
||||
|
||||
#endif
|
||||
#endif /* _NPF_IMPL_H_ */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_nat.c,v 1.5 2011/01/18 20:33:46 rmind Exp $ */
|
||||
/* $NetBSD: npf_nat.c,v 1.6 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -76,7 +76,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.5 2011/01/18 20:33:46 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_nat.c,v 1.6 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -117,7 +117,7 @@ struct npf_natpolicy {
|
|||
kcondvar_t n_cv;
|
||||
npf_portmap_t * n_portmap;
|
||||
int n_type;
|
||||
int n_flags;
|
||||
u_int n_flags;
|
||||
size_t n_addr_sz;
|
||||
npf_addr_t n_taddr;
|
||||
in_port_t n_tport;
|
||||
|
@ -174,7 +174,6 @@ npf_nat_sysfini(void)
|
|||
npf_natpolicy_t *
|
||||
npf_nat_newpolicy(prop_dictionary_t natdict, npf_ruleset_t *nrlset)
|
||||
{
|
||||
const npf_addr_t *taddr;
|
||||
npf_natpolicy_t *np;
|
||||
prop_object_t obj;
|
||||
npf_portmap_t *pm;
|
||||
|
@ -184,26 +183,19 @@ npf_nat_newpolicy(prop_dictionary_t natdict, npf_ruleset_t *nrlset)
|
|||
cv_init(&np->n_cv, "npfnatcv");
|
||||
LIST_INIT(&np->n_nat_list);
|
||||
|
||||
/* Translation type. */
|
||||
obj = prop_dictionary_get(natdict, "type");
|
||||
np->n_type = prop_number_integer_value(obj);
|
||||
|
||||
/* Translation type. */
|
||||
obj = prop_dictionary_get(natdict, "flags");
|
||||
np->n_flags = prop_number_integer_value(obj);
|
||||
/* Translation type and flags. */
|
||||
prop_dictionary_get_int32(natdict, "type", &np->n_type);
|
||||
prop_dictionary_get_uint32(natdict, "flags", &np->n_flags);
|
||||
KASSERT(np->n_type == NPF_NATIN || np->n_type == NPF_NATOUT);
|
||||
|
||||
/* Translation IP. */
|
||||
obj = prop_dictionary_get(natdict, "translation-ip");
|
||||
np->n_addr_sz = prop_data_size(obj);
|
||||
KASSERT(np->n_addr_sz > 0 && np->n_addr_sz <= sizeof(npf_addr_t));
|
||||
taddr = (const npf_addr_t *)prop_data_data_nocopy(obj);
|
||||
memcpy(&np->n_taddr, taddr, np->n_addr_sz);
|
||||
memcpy(&np->n_taddr, prop_data_data_nocopy(obj), np->n_addr_sz);
|
||||
|
||||
/* Translation port (for redirect case). */
|
||||
obj = prop_dictionary_get(natdict, "translation-port");
|
||||
np->n_tport = (in_port_t)prop_number_integer_value(obj);
|
||||
|
||||
KASSERT(np->n_type == NPF_NATIN || np->n_type == NPF_NATOUT);
|
||||
prop_dictionary_get_uint16(natdict, "translation-port", &np->n_tport);
|
||||
|
||||
/* Determine if port map is needed. */
|
||||
np->n_portmap = NULL;
|
||||
|
@ -401,11 +393,21 @@ static npf_natpolicy_t *
|
|||
npf_nat_inspect(npf_cache_t *npc, nbuf_t *nbuf, ifnet_t *ifp, const int di)
|
||||
{
|
||||
npf_ruleset_t *rlset;
|
||||
npf_natpolicy_t *np;
|
||||
npf_rule_t *rl;
|
||||
|
||||
npf_core_enter();
|
||||
rlset = npf_core_natset();
|
||||
rl = npf_ruleset_match(rlset, npc, nbuf, ifp, di, NPF_LAYER_3);
|
||||
return rl ? npf_rule_getnat(rl) : NULL;
|
||||
rl = npf_ruleset_inspect(npc, nbuf, rlset, ifp, di, NPF_LAYER_3);
|
||||
if (rl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
np = npf_rule_getnat(rl);
|
||||
if (np == NULL) {
|
||||
npf_core_exit();
|
||||
return NULL;
|
||||
}
|
||||
return np;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -580,12 +582,13 @@ npf_do_nat(npf_cache_t *npc, npf_session_t *se, nbuf_t *nbuf,
|
|||
goto translate;
|
||||
}
|
||||
|
||||
/* Inspect the packet for a NAT policy, if there is no session. */
|
||||
npf_core_enter();
|
||||
/*
|
||||
* Inspect the packet for a NAT policy, if there is no session.
|
||||
* Note: acquires the lock (releases, if not found).
|
||||
*/
|
||||
np = npf_nat_inspect(npc, nbuf, ifp, di);
|
||||
if (np == NULL) {
|
||||
/* If packet does not match - done. */
|
||||
npf_core_exit();
|
||||
return 0;
|
||||
}
|
||||
forw = true;
|
||||
|
@ -728,13 +731,13 @@ npf_nat_save(prop_dictionary_t sedict, prop_array_t natlist, npf_nat_t *nt)
|
|||
/* Set NAT entry data. */
|
||||
nd = prop_data_create_data(nt, sizeof(npf_nat_t));
|
||||
prop_dictionary_set(sedict, "nat-data", nd);
|
||||
prop_object_release(nd);
|
||||
|
||||
/* Find or create a NAT policy. */
|
||||
it = prop_array_iterator(natlist);
|
||||
while ((npdict = prop_object_iterator_next(it)) != NULL) {
|
||||
CTASSERT(sizeof(uintptr_t) <= sizeof(uint64_t));
|
||||
itnp = (uintptr_t)prop_number_unsigned_integer_value(
|
||||
prop_dictionary_get(npdict, "id-ptr"));
|
||||
prop_dictionary_get_uint64(npdict, "id-ptr", (uint64_t *)&itnp);
|
||||
if (itnp == (uintptr_t)np) {
|
||||
break;
|
||||
}
|
||||
|
@ -743,16 +746,16 @@ npf_nat_save(prop_dictionary_t sedict, prop_array_t natlist, npf_nat_t *nt)
|
|||
/* Create NAT policy dictionary and copy the data. */
|
||||
npdict = prop_dictionary_create();
|
||||
npd = prop_data_create_data(np, sizeof(npf_natpolicy_t));
|
||||
|
||||
/* Set the data, insert into the array. */
|
||||
CTASSERT(sizeof(uintptr_t) <= sizeof(uint64_t));
|
||||
prop_dictionary_set(npdict, "id-ptr",
|
||||
prop_number_create_unsigned_integer((uintptr_t)np));
|
||||
prop_dictionary_set(npdict, "nat-policy-data", npd);
|
||||
prop_object_release(npd);
|
||||
|
||||
CTASSERT(sizeof(uintptr_t) <= sizeof(uint64_t));
|
||||
prop_dictionary_set_uint64(npdict, "id-ptr", (uintptr_t)np);
|
||||
prop_array_add(natlist, npdict);
|
||||
prop_object_release(npdict);
|
||||
}
|
||||
prop_dictionary_set(sedict, "nat-policy",
|
||||
prop_dictionary_copy(npdict));
|
||||
prop_dictionary_set(sedict, "nat-policy", npdict);
|
||||
prop_object_release(npdict);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_ruleset.c,v 1.6 2011/01/18 20:33:46 rmind Exp $ */
|
||||
/* $NetBSD: npf_ruleset.c,v 1.7 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -34,7 +34,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.6 2011/01/18 20:33:46 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_ruleset.c,v 1.7 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -64,8 +64,12 @@ struct npf_hook {
|
|||
LIST_ENTRY(npf_hook) hk_entry;
|
||||
};
|
||||
|
||||
#define NPF_RNAME_LEN 16
|
||||
|
||||
/* Rule procedure structure. */
|
||||
struct npf_rproc {
|
||||
/* Name. */
|
||||
char rp_name[NPF_RNAME_LEN];
|
||||
/* Reference count. */
|
||||
u_int rp_refcnt;
|
||||
uint32_t rp_flags;
|
||||
|
@ -80,12 +84,14 @@ struct npf_rproc {
|
|||
|
||||
/* Rule structure. */
|
||||
struct npf_rule {
|
||||
/* Rule name (optional) and list entry. */
|
||||
char r_name[NPF_RNAME_LEN];
|
||||
TAILQ_ENTRY(npf_rule) r_entry;
|
||||
/* Optional: sub-ruleset, NAT policy. */
|
||||
npf_ruleset_t r_subset;
|
||||
npf_natpolicy_t * r_natp;
|
||||
/* Rule priority: (highest) 0, 1, 2 ... n (lowest). */
|
||||
u_int r_priority;
|
||||
pri_t r_priority;
|
||||
/* N-code to process. */
|
||||
void * r_ncode;
|
||||
size_t r_nc_size;
|
||||
|
@ -220,34 +226,26 @@ npf_rproc_t *
|
|||
npf_rproc_create(prop_dictionary_t rpdict)
|
||||
{
|
||||
npf_rproc_t *rp;
|
||||
prop_object_t obj;
|
||||
const char *rname;
|
||||
|
||||
rp = kmem_alloc(sizeof(npf_rproc_t), KM_SLEEP);
|
||||
rp = kmem_zalloc(sizeof(npf_rproc_t), KM_SLEEP);
|
||||
rp->rp_refcnt = 1;
|
||||
|
||||
/* Flags. */
|
||||
obj = prop_dictionary_get(rpdict, "flags");
|
||||
rp->rp_flags = prop_number_integer_value(obj);
|
||||
/* Name and flags. */
|
||||
prop_dictionary_get_cstring_nocopy(rpdict, "name", &rname);
|
||||
strlcpy(rp->rp_name, rname, NPF_RNAME_LEN);
|
||||
prop_dictionary_get_uint32(rpdict, "flags", &rp->rp_flags);
|
||||
|
||||
/* Logging interface ID (integer). */
|
||||
obj = prop_dictionary_get(rpdict, "log-interface");
|
||||
rp->rp_log_ifid = prop_number_integer_value(obj);
|
||||
prop_dictionary_get_uint32(rpdict, "log-interface", &rp->rp_log_ifid);
|
||||
|
||||
/* Randomize IP ID (bool). */
|
||||
obj = prop_dictionary_get(rpdict, "randomize-id");
|
||||
rp->rp_rnd_ipid = prop_bool_true(obj);
|
||||
/* IP ID randomization and IP_DF flag cleansing. */
|
||||
prop_dictionary_get_bool(rpdict, "randomize-id", &rp->rp_rnd_ipid);
|
||||
prop_dictionary_get_bool(rpdict, "no-df", &rp->rp_no_df);
|
||||
|
||||
/* IP_DF flag cleansing (bool). */
|
||||
obj = prop_dictionary_get(rpdict, "no-df");
|
||||
rp->rp_no_df = prop_bool_true(obj);
|
||||
|
||||
/* Minimum IP TTL (integer). */
|
||||
obj = prop_dictionary_get(rpdict, "min-ttl");
|
||||
rp->rp_minttl = prop_number_integer_value(obj);
|
||||
|
||||
/* Maximum TCP MSS (integer). */
|
||||
obj = prop_dictionary_get(rpdict, "max-mss");
|
||||
rp->rp_maxmss = prop_number_integer_value(obj);
|
||||
/* Minimum IP TTL and maximum TCP MSS. */
|
||||
prop_dictionary_get_uint32(rpdict, "min-ttl", &rp->rp_minttl);
|
||||
prop_dictionary_get_uint32(rpdict, "max-mss", &rp->rp_maxmss);
|
||||
|
||||
return rp;
|
||||
}
|
||||
|
@ -276,14 +274,14 @@ npf_rproc_release(npf_rproc_t *rp)
|
|||
}
|
||||
|
||||
void
|
||||
npf_rproc_run(npf_cache_t *npc, nbuf_t *nbuf, npf_rproc_t *rp)
|
||||
npf_rproc_run(npf_cache_t *npc, nbuf_t *nbuf, npf_rproc_t *rp, int error)
|
||||
{
|
||||
const uint32_t flags = rp->rp_flags;
|
||||
|
||||
KASSERT(rp->rp_refcnt > 0);
|
||||
|
||||
/* Normalize the packet, if required. */
|
||||
if (flags & NPF_RPROC_NORMALIZE) {
|
||||
if ((flags & NPF_RPROC_NORMALIZE) != 0 && !error) {
|
||||
(void)npf_normalize(npc, nbuf,
|
||||
rp->rp_rnd_ipid, rp->rp_no_df,
|
||||
rp->rp_minttl, rp->rp_maxmss);
|
||||
|
@ -291,7 +289,7 @@ npf_rproc_run(npf_cache_t *npc, nbuf_t *nbuf, npf_rproc_t *rp)
|
|||
}
|
||||
|
||||
/* Log packet, if required. */
|
||||
if (flags & NPF_RPROC_LOG) {
|
||||
if ((flags & NPF_RPROC_LOG) != 0) {
|
||||
npf_log_packet(npc, nbuf, rp->rp_log_ifid);
|
||||
npf_stats_inc(NPF_STAT_RPROC_LOG);
|
||||
}
|
||||
|
@ -307,7 +305,7 @@ npf_rule_alloc(prop_dictionary_t rldict, npf_rproc_t *rp,
|
|||
void *nc, size_t nc_size)
|
||||
{
|
||||
npf_rule_t *rl;
|
||||
prop_object_t obj;
|
||||
const char *rname;
|
||||
int errat;
|
||||
|
||||
/* Allocate a rule structure. */
|
||||
|
@ -323,17 +321,17 @@ npf_rule_alloc(prop_dictionary_t rldict, npf_rproc_t *rp,
|
|||
rl->r_ncode = nc;
|
||||
rl->r_nc_size = nc_size;
|
||||
|
||||
/* Attributes (integer). */
|
||||
obj = prop_dictionary_get(rldict, "attributes");
|
||||
rl->r_attr = prop_number_integer_value(obj);
|
||||
/* Name (string, optional) */
|
||||
if (prop_dictionary_get_cstring_nocopy(rldict, "name", &rname)) {
|
||||
strlcpy(rl->r_name, rname, NPF_RNAME_LEN);
|
||||
} else {
|
||||
rl->r_name[0] = '\0';
|
||||
}
|
||||
|
||||
/* Priority (integer). */
|
||||
obj = prop_dictionary_get(rldict, "priority");
|
||||
rl->r_priority = prop_number_integer_value(obj);
|
||||
|
||||
/* Interface ID (integer). */
|
||||
obj = prop_dictionary_get(rldict, "interface");
|
||||
rl->r_ifid = prop_number_integer_value(obj);
|
||||
/* Attributes, priority and interface ID. */
|
||||
prop_dictionary_get_uint32(rldict, "attributes", &rl->r_attr);
|
||||
prop_dictionary_get_int32(rldict, "priority", &rl->r_priority);
|
||||
prop_dictionary_get_uint32(rldict, "interface", &rl->r_ifid);
|
||||
|
||||
/* Rule procedure. */
|
||||
if (rp) {
|
||||
|
@ -398,6 +396,7 @@ npf_rule_setnat(npf_rule_t *rl, npf_natpolicy_t *np)
|
|||
rl->r_natp = np;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* npf_hook_register: register action hook in the rule.
|
||||
*/
|
||||
|
@ -432,21 +431,49 @@ npf_hook_unregister(npf_rule_t *rl, npf_hook_t *hk)
|
|||
mutex_exit(&rl->r_hooks_lock);
|
||||
kmem_free(hk, sizeof(npf_hook_t));
|
||||
}
|
||||
#endif
|
||||
|
||||
npf_rule_t *
|
||||
npf_ruleset_replace(const char *name, npf_ruleset_t *rlset)
|
||||
{
|
||||
npf_ruleset_t orlset;
|
||||
npf_rule_t *rl;
|
||||
|
||||
npf_core_enter(); /* XXX */
|
||||
rlset = npf_core_ruleset();
|
||||
TAILQ_FOREACH(rl, &rlset->rs_queue, r_entry) {
|
||||
if (rl->r_name[0] == '\0')
|
||||
continue;
|
||||
if (strncmp(rl->r_name, name, NPF_RNAME_LEN))
|
||||
continue;
|
||||
memcpy(&orlset, &rl->r_subset, sizeof(npf_ruleset_t));
|
||||
break;
|
||||
}
|
||||
npf_core_exit();
|
||||
return rl;
|
||||
}
|
||||
|
||||
/*
|
||||
* npf_ruleset_match: inspect the packet against the given ruleset.
|
||||
* npf_ruleset_inspect: inspect the packet against the given ruleset.
|
||||
*
|
||||
* Loop for each rule in the set and run n-code processor of each rule
|
||||
* against the packet (nbuf chain).
|
||||
* Loop through the rules in the set and run n-code processor of each rule
|
||||
* against the packet (nbuf chain). If sub-ruleset is found, inspect it.
|
||||
*
|
||||
* => If not found, core ruleset lock is released.
|
||||
* => Caller should protect the nbuf chain.
|
||||
*/
|
||||
npf_rule_t *
|
||||
npf_ruleset_match(npf_ruleset_t *rlset, npf_cache_t *npc, nbuf_t *nbuf,
|
||||
npf_ruleset_inspect(npf_cache_t *npc, nbuf_t *nbuf, npf_ruleset_t *mainrlset,
|
||||
ifnet_t *ifp, const int di, const int layer)
|
||||
{
|
||||
const int di_mask = (di & PFIL_IN) ? NPF_RULE_IN : NPF_RULE_OUT;
|
||||
npf_ruleset_t *rlset = mainrlset;
|
||||
npf_rule_t *final_rl = NULL, *rl;
|
||||
bool defed = false;
|
||||
|
||||
KASSERT(npf_core_locked());
|
||||
KASSERT(((di & PFIL_IN) != 0) ^ ((di & PFIL_OUT) != 0));
|
||||
|
||||
again:
|
||||
TAILQ_FOREACH(rl, &rlset->rs_queue, r_entry) {
|
||||
KASSERT(!final_rl || rl->r_priority >= final_rl->r_priority);
|
||||
|
||||
|
@ -456,9 +483,6 @@ npf_ruleset_match(npf_ruleset_t *rlset, npf_cache_t *npc, nbuf_t *nbuf,
|
|||
}
|
||||
/* Match the direction. */
|
||||
if ((rl->r_attr & NPF_RULE_DIMASK) != NPF_RULE_DIMASK) {
|
||||
const int di_mask =
|
||||
(di & PFIL_IN) ? NPF_RULE_IN : NPF_RULE_OUT;
|
||||
|
||||
if ((rl->r_attr & di_mask) == 0)
|
||||
continue;
|
||||
}
|
||||
|
@ -473,45 +497,22 @@ npf_ruleset_match(npf_ruleset_t *rlset, npf_cache_t *npc, nbuf_t *nbuf,
|
|||
break;
|
||||
}
|
||||
}
|
||||
return final_rl;
|
||||
}
|
||||
|
||||
/*
|
||||
* npf_ruleset_inspect: inspection of the main ruleset for filtering.
|
||||
* If sub-ruleset is found, inspect it.
|
||||
*
|
||||
* => If found, ruleset is kept read-locked.
|
||||
* => Caller should protect the nbuf chain.
|
||||
*/
|
||||
npf_rule_t *
|
||||
npf_ruleset_inspect(npf_cache_t *npc, nbuf_t *nbuf,
|
||||
ifnet_t *ifp, const int di, const int layer)
|
||||
{
|
||||
npf_ruleset_t *rlset;
|
||||
npf_rule_t *rl;
|
||||
bool defed;
|
||||
|
||||
defed = false;
|
||||
npf_core_enter();
|
||||
rlset = npf_core_ruleset();
|
||||
reinspect:
|
||||
rl = npf_ruleset_match(rlset, npc, nbuf, ifp, di, layer);
|
||||
|
||||
/* If no final rule, then - default. */
|
||||
if (rl == NULL && !defed) {
|
||||
npf_ruleset_t *mainrlset = npf_core_ruleset();
|
||||
rl = mainrlset->rs_default;
|
||||
if (final_rl == NULL && !defed) {
|
||||
final_rl = mainrlset->rs_default;
|
||||
defed = true;
|
||||
}
|
||||
/* Inspect the sub-ruleset, if any. */
|
||||
if (rl && !TAILQ_EMPTY(&rl->r_subset.rs_queue)) {
|
||||
rlset = &rl->r_subset;
|
||||
goto reinspect;
|
||||
if (final_rl && !TAILQ_EMPTY(&final_rl->r_subset.rs_queue)) {
|
||||
rlset = &final_rl->r_subset;
|
||||
final_rl = NULL;
|
||||
goto again;
|
||||
}
|
||||
if (rl == NULL) {
|
||||
if (final_rl == NULL) {
|
||||
npf_core_exit();
|
||||
}
|
||||
return rl;
|
||||
return final_rl;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_session.c,v 1.7 2011/01/18 20:33:46 rmind Exp $ */
|
||||
/* $NetBSD: npf_session.c,v 1.8 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -74,7 +74,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.7 2011/01/18 20:33:46 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_session.c,v 1.8 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -952,9 +952,12 @@ npf_session_save(prop_array_t selist, prop_array_t nplist)
|
|||
sedict = prop_dictionary_create();
|
||||
sd = prop_data_create_data(se, sizeof(npf_session_t));
|
||||
prop_dictionary_set(sedict, "data", sd);
|
||||
prop_object_release(sd);
|
||||
|
||||
CTASSERT(sizeof(uintptr_t) <= sizeof(uint64_t));
|
||||
prop_dictionary_set(sedict, "id-ptr",
|
||||
prop_number_create_unsigned_integer((uintptr_t)se));
|
||||
prop_dictionary_set_uint64(
|
||||
sedict, "id-ptr", (uintptr_t)se);
|
||||
|
||||
if (se->s_nat) {
|
||||
/* Save NAT entry and policy, if any. */
|
||||
error = npf_nat_save(sedict, nplist, se->s_nat);
|
||||
|
@ -964,6 +967,7 @@ npf_session_save(prop_array_t selist, prop_array_t nplist)
|
|||
}
|
||||
}
|
||||
prop_array_add(selist, sedict);
|
||||
prop_object_release(sedict);
|
||||
}
|
||||
rw_exit(&sh->sh_lock);
|
||||
if (error) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_tableset.c,v 1.4 2010/12/18 01:07:25 rmind Exp $ */
|
||||
/* $NetBSD: npf_tableset.c,v 1.5 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2010 The NetBSD Foundation, Inc.
|
||||
|
@ -39,7 +39,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.4 2010/12/18 01:07:25 rmind Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: npf_tableset.c,v 1.5 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -78,7 +78,7 @@ struct npf_table {
|
|||
/* Table ID. */
|
||||
u_int t_id;
|
||||
/* The storage type can be: 1. Hash 2. RB-tree. */
|
||||
u_int t_type;
|
||||
int t_type;
|
||||
struct npf_hashl * t_hashl;
|
||||
u_long t_hashmask;
|
||||
rb_tree_t t_rbtree;
|
||||
|
@ -310,19 +310,11 @@ npf_table_get(npf_tableset_t *tset, u_int tid)
|
|||
if ((u_int)tid >= NPF_TABLE_SLOTS) {
|
||||
return NULL;
|
||||
}
|
||||
if (tset == NULL) {
|
||||
npf_core_enter();
|
||||
rtset = npf_core_tableset();
|
||||
} else {
|
||||
rtset = tset;
|
||||
}
|
||||
rtset = tset ? tset : npf_core_tableset();
|
||||
t = rtset[tid];
|
||||
if (t != NULL) {
|
||||
rw_enter(&t->t_lock, RW_READER);
|
||||
}
|
||||
if (tset == NULL) {
|
||||
npf_core_exit();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -479,11 +471,9 @@ int
|
|||
npf_table_match_v4addr(u_int tid, in_addr_t ip4addr)
|
||||
{
|
||||
struct npf_hashl *htbl;
|
||||
npf_tblent_t *e;
|
||||
npf_tblent_t *e = NULL;
|
||||
npf_table_t *t;
|
||||
|
||||
e = NULL;
|
||||
|
||||
/* Locks the table. */
|
||||
t = npf_table_get(NULL, tid);
|
||||
if (__predict_false(t == NULL)) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
# $NetBSD: Makefile,v 1.2 2010/08/24 23:55:04 rmind Exp $
|
||||
# $NetBSD: Makefile,v 1.3 2011/02/02 02:20:25 rmind Exp $
|
||||
|
||||
PROG= npfctl
|
||||
MAN= npfctl.8 npf.conf.5
|
||||
|
||||
SRCS= npfctl.c npf_parser.c npf_data.c npf_ncgen.c
|
||||
|
||||
LDADD+= -lprop
|
||||
DPADD+= ${LIBPROP}
|
||||
LDADD+= -lnpf
|
||||
DPADD+= ${LIBNPF}
|
||||
|
||||
WARNS?= 4
|
||||
NOLINT= # defined (note: deliberately)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $NetBSD: npf.conf.5,v 1.3 2011/01/18 20:33:45 rmind Exp $
|
||||
.\" $NetBSD: npf.conf.5,v 1.4 2011/02/02 02:20:25 rmind Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
|
@ -27,7 +27,7 @@
|
|||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd January 18, 2011
|
||||
.Dd February 2, 2011
|
||||
.Dt NPF.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -56,8 +56,8 @@ The default group must always be defined.
|
|||
Rules, which are the main part of NPF configuration, describe the criteria
|
||||
used to inspect and make decisions about packets.
|
||||
Currently, NPF supports filtering on the following criteria: interface,
|
||||
traffic direction, protocol, IPv4 address or network, and TCP/UDP port
|
||||
or range.
|
||||
traffic direction, protocol, IPv4 address or network, TCP/UDP port
|
||||
or range, TCP flags, and ICMP type/code.
|
||||
Supported actions are blocking or passing the packet.
|
||||
.Pp
|
||||
Each rule has a priority, which is set according to its order in the ruleset.
|
||||
|
@ -70,8 +70,47 @@ marked as final.
|
|||
If there is no matching rule in the custom group, then rules in the default
|
||||
group will be inspected.
|
||||
.Pp
|
||||
Stateful filtering is supported using the "keep state" keyword.
|
||||
In such cases, state (a session) is created and any further packets
|
||||
of the connection are tracked.
|
||||
Packets in backwards stream, after having been confirmed to belong to
|
||||
the same connection, are passed without ruleset inspection.
|
||||
Rules may have associated rule procedures (described in a later section),
|
||||
which are applied for all packets of a connection.
|
||||
.Pp
|
||||
Definitions (prefixed with "$") and tables (specified by an ID within
|
||||
"\*[Lt]\*[Gt]" marks) can be used in the filter options of rules.
|
||||
.Sh RULE PROCEDURES AND NORMALIZATION
|
||||
Rule procedures are provided to perform packet transformations and various
|
||||
additional procedures on the packets.
|
||||
It should be noted that rule procedures are applied for the connections,
|
||||
that is, both for packets which match the rule and for further packets
|
||||
of the connection, which are passed without ruleset inspection.
|
||||
Currently, two facilities are supported:
|
||||
traffic normalization and packet logging.
|
||||
Packet normalization has the following functionality:
|
||||
IP ID randomization, IP_DF flag cleansing, TCP minimum TTL enforcement,
|
||||
and maximum MSS enforcement ("MSS clamping").
|
||||
If a matching rule is going to drop the packet, normalization functions
|
||||
are not performed.
|
||||
Packet logging is performed both in packet passing and blocking cases.
|
||||
.Sh NAT
|
||||
Rules for address translation can be added.
|
||||
Translation is performed on the specified interface, assigning the specified
|
||||
address of said interface.
|
||||
There are three types of translation:
|
||||
Network Address Port Translation (NAPT) - a regular NAT,
|
||||
also known as "outbound NAT";
|
||||
Port forwarding (redirection) - also known as "inbound NAT";
|
||||
Bi-directional NAT - a combination of inbound and outbound NAT.
|
||||
.Pp
|
||||
Minimal filtering criteria on local network and destination are provided.
|
||||
Note that address translation implies routing, therefore IP forwarding
|
||||
is required to be enabled:
|
||||
net.inet.ip.forwarding = 1.
|
||||
See
|
||||
.Xr sysctl 7
|
||||
for more details.
|
||||
.Sh TABLES
|
||||
Certain configurations might use very large sets of IP addresses or change
|
||||
sets frequently.
|
||||
|
@ -85,11 +124,6 @@ Tables can be managed dynamically or loaded from a separate file, which
|
|||
is useful for large static tables.
|
||||
There are two types of storage: "tree" (red-black tree is used) and
|
||||
"hash".
|
||||
.Sh NAT
|
||||
Special rules for Network Address Translation (NAT) can be added.
|
||||
Translation is performed on specified interface, assigning a specified
|
||||
address of said interface.
|
||||
Minimal filtering criteria on local network and destination are provided.
|
||||
.\" -----
|
||||
.Sh GRAMMAR
|
||||
.Bd -literal
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_data.c,v 1.6 2011/01/18 20:33:45 rmind Exp $ */
|
||||
/* $NetBSD: npf_data.c,v 1.7 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -27,13 +27,11 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* NPF proplib(9) dictionary producer.
|
||||
*
|
||||
* XXX: Needs some clean-up.
|
||||
* npfctl(8) helper routines.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: npf_data.c,v 1.6 2011/01/18 20:33:45 rmind Exp $");
|
||||
__RCSID("$NetBSD: npf_data.c,v 1.7 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
@ -42,7 +40,6 @@ __RCSID("$NetBSD: npf_data.c,v 1.6 2011/01/18 20:33:45 rmind Exp $");
|
|||
#include <netinet/tcp.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <prop/proplib.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -56,110 +53,27 @@ __RCSID("$NetBSD: npf_data.c,v 1.6 2011/01/18 20:33:45 rmind Exp $");
|
|||
#include "npfctl.h"
|
||||
|
||||
static struct ifaddrs * ifs_list = NULL;
|
||||
|
||||
static prop_dictionary_t npf_dict, settings_dict;
|
||||
static prop_array_t nat_arr, tables_arr, rproc_arr, rules_arr;
|
||||
|
||||
static pri_t gr_prio_counter = 1;
|
||||
static pri_t rl_prio_counter = 1;
|
||||
static pri_t nat_prio_counter = 1;
|
||||
static u_int rproc_id_counter = 1;
|
||||
nl_config_t * npf_conf = NULL;
|
||||
|
||||
void
|
||||
npfctl_init_data(void)
|
||||
{
|
||||
|
||||
if (getifaddrs(&ifs_list) == -1)
|
||||
npf_conf = npf_config_create();
|
||||
if (npf_conf == NULL) {
|
||||
errx(EXIT_FAILURE, "npf_config_create");
|
||||
}
|
||||
if (getifaddrs(&ifs_list) == -1) {
|
||||
err(EXIT_FAILURE, "getifaddrs");
|
||||
|
||||
npf_dict = prop_dictionary_create();
|
||||
|
||||
nat_arr = prop_array_create();
|
||||
prop_dictionary_set(npf_dict, "translation", nat_arr);
|
||||
|
||||
settings_dict = prop_dictionary_create();
|
||||
prop_dictionary_set(npf_dict, "settings", settings_dict);
|
||||
|
||||
tables_arr = prop_array_create();
|
||||
prop_dictionary_set(npf_dict, "tables", tables_arr);
|
||||
|
||||
rproc_arr = prop_array_create();
|
||||
prop_dictionary_set(npf_dict, "rprocs", rproc_arr);
|
||||
|
||||
rules_arr = prop_array_create();
|
||||
prop_dictionary_set(npf_dict, "rules", rules_arr);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
npfctl_ioctl_send(int fd)
|
||||
{
|
||||
int ret = 0, errval;
|
||||
|
||||
#ifdef _NPF_TESTING
|
||||
prop_dictionary_externalize_to_file(npf_dict, "./npf.plist");
|
||||
#else
|
||||
errval = prop_dictionary_send_ioctl(npf_dict, fd, IOC_NPF_RELOAD);
|
||||
if (errval) {
|
||||
errx(EXIT_FAILURE, "npfctl_ioctl_send: %s\n", strerror(errval));
|
||||
}
|
||||
#endif
|
||||
prop_object_release(npf_dict);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
npfctl_ioctl_flushse(int fd)
|
||||
{
|
||||
prop_dictionary_t sesdict;
|
||||
prop_array_t selist;
|
||||
int errval;
|
||||
|
||||
sesdict = prop_dictionary_create();
|
||||
selist = prop_array_create();
|
||||
prop_dictionary_set(sesdict, "session-list", selist);
|
||||
errval = prop_dictionary_send_ioctl(sesdict, fd, IOC_NPF_SESSIONS_LOAD);
|
||||
if (errval) {
|
||||
errx(EXIT_FAILURE, "npfctl_ioctl_flushse: %s\n",
|
||||
strerror(errval));
|
||||
}
|
||||
prop_object_release(sesdict);
|
||||
return errval;
|
||||
}
|
||||
|
||||
int
|
||||
npfctl_ioctl_sendse(int fd)
|
||||
{
|
||||
prop_dictionary_t sesdict;
|
||||
int error;
|
||||
|
||||
sesdict = prop_dictionary_internalize_from_file(NPF_SESSDB_PATH);
|
||||
if (sesdict == NULL) {
|
||||
errx(EXIT_FAILURE, "npfctl: no sessions saved "
|
||||
"('%s' does not exist)", NPF_SESSDB_PATH);
|
||||
}
|
||||
error = prop_dictionary_send_ioctl(sesdict, fd, IOC_NPF_SESSIONS_LOAD);
|
||||
prop_object_release(sesdict);
|
||||
if (error) {
|
||||
err(EXIT_FAILURE, "npfctl_ioctl_sendse");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
npfctl_ioctl_recvse(int fd)
|
||||
{
|
||||
prop_dictionary_t sesdict;
|
||||
int error;
|
||||
|
||||
error = prop_dictionary_recv_ioctl(fd, IOC_NPF_SESSIONS_SAVE, &sesdict);
|
||||
if (error) {
|
||||
err(EXIT_FAILURE, "prop_array_recv_ioctl");
|
||||
}
|
||||
if (!prop_dictionary_externalize_to_file(sesdict, NPF_SESSDB_PATH)) {
|
||||
errx(EXIT_FAILURE, "could not save to '%s'", NPF_SESSDB_PATH);
|
||||
}
|
||||
prop_object_release(sesdict);
|
||||
return 0;
|
||||
int error = npf_config_submit(npf_conf, fd);
|
||||
npf_config_destroy(npf_conf);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -211,7 +125,7 @@ npfctl_parse_v4mask(char *ostr, in_addr_t *addr, in_addr_t *mask)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
bool
|
||||
npfctl_parse_port(char *ostr, bool *range, in_port_t *fport, in_port_t *tport)
|
||||
{
|
||||
char *str = xstrdup(ostr), *sep;
|
||||
|
@ -239,7 +153,7 @@ npfctl_parse_port(char *ostr, bool *range, in_port_t *fport, in_port_t *tport)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
npfctl_parse_cidr(char *str, in_addr_t *addr, in_addr_t *mask)
|
||||
{
|
||||
|
||||
|
@ -299,55 +213,14 @@ npfctl_parse_tcpfl(char *s, uint8_t *tfl, uint8_t *tfl_mask)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* NPF table creation and construction routines.
|
||||
*/
|
||||
|
||||
prop_dictionary_t
|
||||
npfctl_lookup_table(char *tidstr)
|
||||
{
|
||||
prop_dictionary_t tl;
|
||||
prop_object_iterator_t it;
|
||||
prop_object_t obj;
|
||||
u_int tid;
|
||||
|
||||
tid = atoi(tidstr);
|
||||
it = prop_array_iterator(tables_arr);
|
||||
while ((tl = prop_object_iterator_next(it)) != NULL) {
|
||||
obj = prop_dictionary_get(tl, "id");
|
||||
if (tid == prop_number_integer_value(obj))
|
||||
break;
|
||||
}
|
||||
return tl;
|
||||
}
|
||||
|
||||
prop_dictionary_t
|
||||
npfctl_construct_table(int id, int type)
|
||||
{
|
||||
prop_dictionary_t tl;
|
||||
|
||||
tl = prop_dictionary_create();
|
||||
/* TODO: 1. check ID range 2. check if not a duplicate */
|
||||
prop_dictionary_set(tl, "id", prop_number_create_integer(id));
|
||||
prop_dictionary_set(tl, "type", prop_number_create_integer(type));
|
||||
prop_dictionary_set(tl, "entries", prop_array_create());
|
||||
prop_array_add(tables_arr, tl);
|
||||
return tl;
|
||||
}
|
||||
|
||||
void
|
||||
npfctl_fill_table(prop_dictionary_t tl, char *fname)
|
||||
npfctl_fill_table(nl_table_t *tl, char *fname)
|
||||
{
|
||||
prop_dictionary_t entdict;
|
||||
prop_array_t tblents;
|
||||
char *buf;
|
||||
FILE *fp;
|
||||
size_t n;
|
||||
int l;
|
||||
|
||||
tblents = prop_dictionary_get(tl, "entries");
|
||||
assert(tblents != NULL);
|
||||
|
||||
fp = fopen(fname, "r");
|
||||
if (fp == NULL) {
|
||||
err(EXIT_FAILURE, "open '%s'", fname);
|
||||
|
@ -361,16 +234,12 @@ npfctl_fill_table(prop_dictionary_t tl, char *fname)
|
|||
continue;
|
||||
|
||||
/* IPv4 CIDR: a.b.c.d/mask */
|
||||
if (!npfctl_parse_v4mask(buf, &addr, &mask))
|
||||
if (!npfctl_parse_v4mask(buf, &addr, &mask)) {
|
||||
errx(EXIT_FAILURE, "invalid table entry at line %d", l);
|
||||
}
|
||||
|
||||
/* Create and add table entry. */
|
||||
entdict = prop_dictionary_create();
|
||||
prop_dictionary_set(entdict, "addr",
|
||||
prop_number_create_integer(addr));
|
||||
prop_dictionary_set(entdict, "mask",
|
||||
prop_number_create_integer(mask));
|
||||
prop_array_add(tblents, entdict);
|
||||
npf_table_add_entry(tl, addr, mask);
|
||||
l++;
|
||||
}
|
||||
if (buf != NULL) {
|
||||
|
@ -379,54 +248,7 @@ npfctl_fill_table(prop_dictionary_t tl, char *fname)
|
|||
}
|
||||
|
||||
/*
|
||||
* npfctl_mk_rule: create a rule (or group) dictionary.
|
||||
*
|
||||
* Note: group is a rule containing subrules. It has no n-code, however.
|
||||
*/
|
||||
prop_dictionary_t
|
||||
npfctl_mk_rule(bool group, prop_dictionary_t parent)
|
||||
{
|
||||
prop_dictionary_t rl;
|
||||
prop_array_t subrl, rlset;
|
||||
pri_t pri;
|
||||
|
||||
rl = prop_dictionary_create();
|
||||
if (group) {
|
||||
subrl = prop_array_create();
|
||||
prop_dictionary_set(rl, "subrules", subrl);
|
||||
/* Give new priority, reset rule priority counter. */
|
||||
pri = gr_prio_counter++;
|
||||
rl_prio_counter = 1;
|
||||
} else {
|
||||
pri = rl_prio_counter++;
|
||||
}
|
||||
prop_dictionary_set(rl, "priority", prop_number_create_integer(pri));
|
||||
|
||||
if (parent) {
|
||||
rlset = prop_dictionary_get(parent, "subrules");
|
||||
assert(rlset != NULL);
|
||||
} else {
|
||||
rlset = rules_arr;
|
||||
}
|
||||
prop_array_add(rlset, rl);
|
||||
return rl;
|
||||
}
|
||||
|
||||
void
|
||||
npfctl_rule_setattr(prop_dictionary_t rl, int attr, u_int iface)
|
||||
{
|
||||
prop_number_t attrnum, ifnum;
|
||||
|
||||
attrnum = prop_number_create_integer(attr);
|
||||
prop_dictionary_set(rl, "attributes", attrnum);
|
||||
if (iface) {
|
||||
ifnum = prop_number_create_integer(iface);
|
||||
prop_dictionary_set(rl, "interface", ifnum);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Main rule generation routines.
|
||||
* N-code generation helpers.
|
||||
*/
|
||||
|
||||
static void
|
||||
|
@ -497,15 +319,13 @@ npfctl_rulenc_block(void **nc, int nblocks[], var_t *cidr, var_t *ports,
|
|||
}
|
||||
|
||||
void
|
||||
npfctl_rule_protodata(prop_dictionary_t rl, char *proto, char *tcp_flags,
|
||||
int icmp_type, int icmp_code,
|
||||
var_t *from, var_t *fports, var_t *to, var_t *tports)
|
||||
npfctl_rule_ncode(nl_rule_t *rl, char *proto, char *tcpfl, int icmp_type,
|
||||
int icmp_code, var_t *from, var_t *fports, var_t *to, var_t *tports)
|
||||
{
|
||||
prop_data_t ncdata;
|
||||
int nblocks[3] = { 0, 0, 0 };
|
||||
bool icmp, tcpudp, both;
|
||||
int foff, nblocks[3] = { 0, 0, 0 };
|
||||
void *ncptr, *nc;
|
||||
size_t sz;
|
||||
size_t sz, foff;
|
||||
|
||||
/*
|
||||
* Default: both TCP and UDP.
|
||||
|
@ -537,11 +357,11 @@ npfctl_rule_protodata(prop_dictionary_t rl, char *proto, char *tcp_flags,
|
|||
}
|
||||
skip_proto:
|
||||
if (icmp || icmp_type != -1) {
|
||||
assert(tcp_flags == NULL);
|
||||
assert(tcpfl == NULL);
|
||||
icmp = true;
|
||||
nblocks[2] += 1;
|
||||
}
|
||||
if (tcpudp && tcp_flags) {
|
||||
if (tcpudp && tcpfl) {
|
||||
assert(icmp_type == -1 && icmp_code == -1);
|
||||
nblocks[2] += 1;
|
||||
}
|
||||
|
@ -574,8 +394,7 @@ skip_proto:
|
|||
sz = npfctl_calc_ncsize(nblocks);
|
||||
ncptr = malloc(sz);
|
||||
if (ncptr == NULL) {
|
||||
perror("malloc");
|
||||
exit(EXIT_FAILURE);
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
}
|
||||
nc = ncptr;
|
||||
|
||||
|
@ -599,7 +418,7 @@ skip_proto:
|
|||
foff = npfctl_failure_offset(nblocks);
|
||||
npfctl_gennc_icmp(&nc, foff, icmp_type, icmp_code);
|
||||
|
||||
} else if (tcpudp && tcp_flags) {
|
||||
} else if (tcpudp && tcpfl) {
|
||||
/*
|
||||
* TCP case, flags.
|
||||
*/
|
||||
|
@ -607,8 +426,8 @@ skip_proto:
|
|||
|
||||
nblocks[2]--;
|
||||
foff = npfctl_failure_offset(nblocks);
|
||||
if (!npfctl_parse_tcpfl(tcp_flags, &tfl, &tfl_mask)) {
|
||||
errx(EXIT_FAILURE, "invalid TCP flags '%s'", tcp_flags);
|
||||
if (!npfctl_parse_tcpfl(tcpfl, &tfl, &tfl_mask)) {
|
||||
errx(EXIT_FAILURE, "invalid TCP flags '%s'", tcpfl);
|
||||
}
|
||||
npfctl_gennc_tcpfl(&nc, foff, tfl, tfl_mask);
|
||||
}
|
||||
|
@ -630,107 +449,8 @@ skip_proto:
|
|||
#endif
|
||||
|
||||
/* Create a final memory block of data, ready to send. */
|
||||
ncdata = prop_data_create_data(ncptr, sz);
|
||||
if (ncdata == NULL) {
|
||||
perror("prop_data_create_data");
|
||||
exit(EXIT_FAILURE);
|
||||
if (npf_rule_setcode(rl, NPF_CODE_NCODE, ncptr, sz) == -1) {
|
||||
errx(EXIT_FAILURE, "npf_rule_setcode");
|
||||
}
|
||||
prop_dictionary_set(rl, "ncode", ncdata);
|
||||
free(ncptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rule procedure construction routines.
|
||||
*/
|
||||
|
||||
prop_dictionary_t
|
||||
npfctl_mk_rproc(void)
|
||||
{
|
||||
prop_dictionary_t rp;
|
||||
|
||||
rp = prop_dictionary_create();
|
||||
prop_dictionary_set(rp, "id",
|
||||
prop_number_create_unsigned_integer(rproc_id_counter++));
|
||||
prop_array_add(rproc_arr, rp);
|
||||
return rp;
|
||||
}
|
||||
|
||||
bool
|
||||
npfctl_find_rproc(prop_dictionary_t rl, char *name)
|
||||
{
|
||||
prop_dictionary_t rp;
|
||||
prop_object_iterator_t it;
|
||||
prop_object_t obj;
|
||||
|
||||
it = prop_array_iterator(rproc_arr);
|
||||
while ((rp = prop_object_iterator_next(it)) != NULL) {
|
||||
obj = prop_dictionary_get(rp, "name");
|
||||
if (strcmp(prop_string_cstring(obj), name) == 0)
|
||||
break;
|
||||
}
|
||||
if (rp == NULL) {
|
||||
return false;
|
||||
}
|
||||
prop_dictionary_set(rl, "rproc-id", prop_dictionary_get(rp, "id"));
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAT policy construction routines.
|
||||
*/
|
||||
|
||||
prop_dictionary_t
|
||||
npfctl_mk_nat(void)
|
||||
{
|
||||
prop_dictionary_t rl;
|
||||
pri_t pri;
|
||||
|
||||
/* NAT policy is rule with extra info. */
|
||||
rl = prop_dictionary_create();
|
||||
pri = nat_prio_counter++;
|
||||
prop_dictionary_set(rl, "priority", prop_number_create_integer(pri));
|
||||
prop_array_add(nat_arr, rl);
|
||||
return rl;
|
||||
}
|
||||
|
||||
void
|
||||
npfctl_nat_setup(prop_dictionary_t rl, int type, int flags,
|
||||
u_int iface, char *taddr, char *rport)
|
||||
{
|
||||
int attr = NPF_RULE_PASS | NPF_RULE_FINAL;
|
||||
in_addr_t addr, _dummy;
|
||||
prop_data_t addrdat;
|
||||
|
||||
/* Translation type and flags. */
|
||||
prop_dictionary_set(rl, "type",
|
||||
prop_number_create_integer(type));
|
||||
prop_dictionary_set(rl, "flags",
|
||||
prop_number_create_integer(flags));
|
||||
|
||||
/* Interface and attributes. */
|
||||
attr |= (type == NPF_NATOUT) ? NPF_RULE_OUT : NPF_RULE_IN;
|
||||
npfctl_rule_setattr(rl, attr, iface);
|
||||
|
||||
/* Translation IP. */
|
||||
npfctl_parse_cidr(taddr, &addr, &_dummy);
|
||||
addrdat = prop_data_create_data(&addr, sizeof(in_addr_t));
|
||||
if (addrdat == NULL) {
|
||||
err(EXIT_FAILURE, "prop_data_create_data");
|
||||
}
|
||||
prop_dictionary_set(rl, "translation-ip", addrdat);
|
||||
|
||||
/* Translation port (for redirect case). */
|
||||
if (rport) {
|
||||
in_port_t port;
|
||||
bool range;
|
||||
|
||||
if (!npfctl_parse_port(rport, &range, &port, &port)) {
|
||||
errx(EXIT_FAILURE, "invalid service '%s'", rport);
|
||||
}
|
||||
if (range) {
|
||||
errx(EXIT_FAILURE, "range is not supported for 'rdr'");
|
||||
}
|
||||
prop_dictionary_set(rl, "translation-port",
|
||||
prop_number_create_integer(port));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npf_parser.c,v 1.5 2011/01/18 20:33:45 rmind Exp $ */
|
||||
/* $NetBSD: npf_parser.c,v 1.6 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: npf_parser.c,v 1.5 2011/01/18 20:33:45 rmind Exp $");
|
||||
__RCSID("$NetBSD: npf_parser.c,v 1.6 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -92,7 +92,7 @@ npfctl_parsevalue(char *buf)
|
|||
/* Definition - lookup. */
|
||||
vr = npfctl_lookup_varlist(++p);
|
||||
if (vr == NULL) {
|
||||
errx(EXIT_FAILURE, "invalid variable '%s'", p);
|
||||
errx(EXIT_FAILURE, "variable '%s' is not defined", p);
|
||||
}
|
||||
break;
|
||||
case '{':
|
||||
|
@ -123,8 +123,8 @@ npfctl_parsevalue(char *buf)
|
|||
return NULL;
|
||||
}
|
||||
*tend = '\0';
|
||||
if (npfctl_lookup_table(p) == NULL) {
|
||||
errx(EXIT_FAILURE, "invalid table '%s'", p);
|
||||
if (!npf_table_exists_p(npf_conf, (u_int)atoi(p))) {
|
||||
errx(EXIT_FAILURE, "table '%s' is not defined", p);
|
||||
}
|
||||
vr = zalloc(sizeof(var_t));
|
||||
vr->v_type = VAR_TABLE;
|
||||
|
@ -149,7 +149,7 @@ npfctl_val_single(var_t *v, char *p)
|
|||
element_t *el;
|
||||
|
||||
if (v->v_type != VAR_SINGLE) {
|
||||
errx(EXIT_FAILURE, "invalid value '%s'", p);
|
||||
errx(EXIT_FAILURE, "multiple elements in variable '%s'", p);
|
||||
}
|
||||
el = v->v_elements;
|
||||
return el->e_data;
|
||||
|
@ -168,7 +168,7 @@ npfctl_val_interface(var_t *v, char *p, bool reqaddr)
|
|||
}
|
||||
|
||||
static int
|
||||
npfctl_parsenorm(char *buf, prop_dictionary_t rp)
|
||||
npfctl_parsenorm(char *buf, nl_rproc_t *rp)
|
||||
{
|
||||
char *p = buf, *sptr;
|
||||
int minttl = 0, maxmss = 0;
|
||||
|
@ -194,15 +194,11 @@ npfctl_parsenorm(char *buf, prop_dictionary_t rp)
|
|||
}
|
||||
} while ((p = strtok_r(NULL, ", \t", &sptr)) != 0);
|
||||
|
||||
prop_dictionary_set(rp, "randomize-id", prop_bool_create(rnd));
|
||||
prop_dictionary_set(rp, "min-ttl", prop_number_create_integer(minttl));
|
||||
prop_dictionary_set(rp, "max-mss", prop_number_create_integer(maxmss));
|
||||
prop_dictionary_set(rp, "no-df", prop_bool_create(no_df));
|
||||
return 0;
|
||||
return _npf_rproc_setnorm(rp, rnd, no_df, minttl, maxmss);
|
||||
}
|
||||
|
||||
static int
|
||||
npfctl_parserproc(char *buf, prop_dictionary_t rp)
|
||||
npfctl_parserproc(char *buf, nl_rproc_t **rp)
|
||||
{
|
||||
char *p = buf, *end;
|
||||
|
||||
|
@ -213,21 +209,20 @@ npfctl_parserproc(char *buf, prop_dictionary_t rp)
|
|||
if ((end = strchr(++p, '"')) == NULL)
|
||||
return -1;
|
||||
*end = '\0';
|
||||
prop_dictionary_set(rp, "name", prop_string_create_cstring(p));
|
||||
return 0;
|
||||
|
||||
*rp = npf_rproc_create(p);
|
||||
if (*rp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
return npf_rproc_insert(npf_conf, *rp) ? -1 : 0;
|
||||
}
|
||||
|
||||
static int
|
||||
npfctl_parserproc_lines(char *buf, prop_dictionary_t rp)
|
||||
npfctl_parserproc_lines(char *buf, nl_rproc_t *rp)
|
||||
{
|
||||
char *p = buf, *sptr;
|
||||
prop_object_t obj;
|
||||
uint32_t attr;
|
||||
|
||||
DPRINTF(("rproc\t|%s|\n", p));
|
||||
obj = prop_dictionary_get(rp, "flags");
|
||||
attr = obj ? prop_number_integer_value(obj) : 0;
|
||||
|
||||
PARSE_FIRST_TOKEN();
|
||||
|
||||
/* log <interface> */
|
||||
|
@ -239,9 +234,7 @@ npfctl_parserproc_lines(char *buf, prop_dictionary_t rp)
|
|||
if ((ifvar = npfctl_parsevalue(p)) == NULL)
|
||||
return PARSE_ERR();
|
||||
if_idx = npfctl_val_interface(ifvar, p, false);
|
||||
prop_dictionary_set(rp, "log-interface",
|
||||
prop_number_create_integer(if_idx));
|
||||
attr |= NPF_RPROC_LOG;
|
||||
(void)_npf_rproc_setlog(rp, if_idx);
|
||||
|
||||
} else if (strcmp(p, "normalize") == 0) {
|
||||
/* normalize ( .. ) */
|
||||
|
@ -252,10 +245,8 @@ npfctl_parserproc_lines(char *buf, prop_dictionary_t rp)
|
|||
if (npfctl_parsenorm(p, rp)) {
|
||||
return PARSE_ERR();
|
||||
}
|
||||
attr |= NPF_RPROC_NORMALIZE;
|
||||
PARSE_NEXT_TOKEN_NOCHECK();
|
||||
}
|
||||
prop_dictionary_set(rp, "flags", prop_number_create_integer(attr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -269,15 +260,15 @@ npfctl_parserproc_lines(char *buf, prop_dictionary_t rp)
|
|||
* [ keep state ] [ apply "<rproc>" ]
|
||||
*/
|
||||
static int
|
||||
npfctl_parserule(char *buf, prop_dictionary_t rl)
|
||||
npfctl_parserule(char *buf, nl_rule_t *parent)
|
||||
{
|
||||
var_t *from_cidr = NULL, *fports = NULL;
|
||||
var_t *to_cidr = NULL, *tports = NULL;
|
||||
char *p, *sptr, *proto = NULL, *tcp_flags = NULL;
|
||||
var_t *from_v = NULL, *fports = NULL, *to_v = NULL, *tports = NULL;
|
||||
char *p, *sptr, *proto = NULL, *tcp_flags = NULL, *rproc = NULL;
|
||||
int icmp_type = -1, icmp_code = -1;
|
||||
bool icmp = false, tcp = false;
|
||||
u_int iface = 0;
|
||||
u_int if_idx = 0;
|
||||
int ret, attr = 0;
|
||||
nl_rule_t *rl;
|
||||
|
||||
DPRINTF(("rule\t|%s|\n", buf));
|
||||
|
||||
|
@ -329,7 +320,7 @@ npfctl_parserule(char *buf, prop_dictionary_t rl)
|
|||
PARSE_NEXT_TOKEN();
|
||||
if ((ifvar = npfctl_parsevalue(p)) == NULL)
|
||||
return PARSE_ERR();
|
||||
iface = npfctl_val_interface(ifvar, p, true);
|
||||
if_idx = npfctl_val_interface(ifvar, p, true);
|
||||
PARSE_NEXT_TOKEN();
|
||||
}
|
||||
|
||||
|
@ -370,7 +361,7 @@ npfctl_parserule(char *buf, prop_dictionary_t rl)
|
|||
/* from <addr> port <port | range> */
|
||||
if (strcmp(p, "from") == 0) {
|
||||
PARSE_NEXT_TOKEN();
|
||||
from_cidr = npfctl_parsevalue(p);
|
||||
from_v = npfctl_parsevalue(p);
|
||||
|
||||
PARSE_NEXT_TOKEN_NOCHECK();
|
||||
if (p && strcmp(p, "port") == 0) {
|
||||
|
@ -384,7 +375,7 @@ npfctl_parserule(char *buf, prop_dictionary_t rl)
|
|||
/* to <addr> port <port | range> */
|
||||
if (p && strcmp(p, "to") == 0) {
|
||||
PARSE_NEXT_TOKEN();
|
||||
to_cidr = npfctl_parsevalue(p);
|
||||
to_v = npfctl_parsevalue(p);
|
||||
|
||||
PARSE_NEXT_TOKEN_NOCHECK();
|
||||
if (p && strcmp(p, "port") == 0) {
|
||||
|
@ -446,9 +437,10 @@ last:
|
|||
if ((end = strchr(++p, '"')) == NULL)
|
||||
return PARSE_ERR();
|
||||
*end = '\0';
|
||||
if (!npfctl_find_rproc(rl, p)) {
|
||||
errx(EXIT_FAILURE, "invalid procedure '%s'", p);
|
||||
if (!npf_rproc_exists_p(npf_conf, p)) {
|
||||
errx(EXIT_FAILURE, "procedure '%s' is not defined", p);
|
||||
}
|
||||
rproc = p;
|
||||
PARSE_NEXT_TOKEN_NOCHECK();
|
||||
}
|
||||
|
||||
|
@ -460,9 +452,13 @@ last:
|
|||
/*
|
||||
* Set the rule attributes and interface. Generate all protocol data.
|
||||
*/
|
||||
npfctl_rule_setattr(rl, attr, iface);
|
||||
npfctl_rule_protodata(rl, proto, tcp_flags, icmp_type, icmp_code,
|
||||
from_cidr, fports, to_cidr, tports);
|
||||
rl = npf_rule_create(NULL, attr, if_idx);
|
||||
npfctl_rule_ncode(rl, proto, tcp_flags, icmp_type, icmp_code,
|
||||
from_v, fports, to_v, tports);
|
||||
if (rproc && npf_rule_setproc(npf_conf, rl, rproc) != 0) {
|
||||
errx(EXIT_FAILURE, "procedure '%s' is not defined", rproc);
|
||||
}
|
||||
npf_rule_insert(npf_conf, parent, rl, NPF_PRI_NEXT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -476,10 +472,10 @@ last:
|
|||
#define GROUP_ATTRS (NPF_RULE_PASS | NPF_RULE_FINAL)
|
||||
|
||||
static int
|
||||
npfctl_parsegroup(char *buf, prop_dictionary_t rl)
|
||||
npfctl_parsegroup(char *buf, nl_rule_t **rl)
|
||||
{
|
||||
char *p = buf, *end, *sptr;
|
||||
u_int iface = 0;
|
||||
char *p = buf, *end, *sptr, *rname = NULL;
|
||||
u_int if_idx = 0;
|
||||
int attr_dir;
|
||||
|
||||
DPRINTF(("group\t|%s|\n", buf));
|
||||
|
@ -502,8 +498,7 @@ npfctl_parsegroup(char *buf, prop_dictionary_t rl)
|
|||
*/
|
||||
if (strcmp(p, "default") == 0) {
|
||||
attr_dir = NPF_RULE_DEFAULT | (NPF_RULE_IN | NPF_RULE_OUT);
|
||||
npfctl_rule_setattr(rl, GROUP_ATTRS | attr_dir, 0);
|
||||
return 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
PARSE_FIRST_TOKEN();
|
||||
|
@ -513,10 +508,10 @@ npfctl_parsegroup(char *buf, prop_dictionary_t rl)
|
|||
PARSE_NEXT_TOKEN()
|
||||
if (*p != '"')
|
||||
return -1;
|
||||
if ((end = strchr(++p, '"')) == NULL)
|
||||
rname = ++p;
|
||||
if ((p = strchr(rname, '"')) == NULL)
|
||||
return -1;
|
||||
*end = '\0';
|
||||
/* TODO: p == name */
|
||||
*p = '\0';
|
||||
PARSE_NEXT_TOKEN_NOCHECK();
|
||||
}
|
||||
|
||||
|
@ -526,7 +521,7 @@ npfctl_parsegroup(char *buf, prop_dictionary_t rl)
|
|||
PARSE_NEXT_TOKEN();
|
||||
if ((ifvar = npfctl_parsevalue(p)) == NULL)
|
||||
return -1;
|
||||
iface = npfctl_val_interface(ifvar, p, true);
|
||||
if_idx = npfctl_val_interface(ifvar, p, true);
|
||||
PARSE_NEXT_TOKEN_NOCHECK();
|
||||
}
|
||||
|
||||
|
@ -541,8 +536,12 @@ npfctl_parsegroup(char *buf, prop_dictionary_t rl)
|
|||
} else {
|
||||
attr_dir = NPF_RULE_IN | NPF_RULE_OUT;
|
||||
}
|
||||
|
||||
npfctl_rule_setattr(rl, GROUP_ATTRS | attr_dir, iface);
|
||||
done:
|
||||
*rl = npf_rule_create(rname, GROUP_ATTRS | attr_dir, if_idx);
|
||||
if (*rl == NULL) {
|
||||
return -1;
|
||||
}
|
||||
npf_rule_insert(npf_conf, NULL, *rl, NPF_PRI_NEXT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -554,9 +553,9 @@ npfctl_parsegroup(char *buf, prop_dictionary_t rl)
|
|||
static int
|
||||
npfctl_parsetable(char *buf)
|
||||
{
|
||||
prop_dictionary_t tl;
|
||||
char *p, *sptr, *fname;
|
||||
unsigned int id, type;
|
||||
nl_table_t *tl;
|
||||
|
||||
DPRINTF(("table\t|%s|\n", buf));
|
||||
|
||||
|
@ -583,7 +582,7 @@ npfctl_parsetable(char *buf)
|
|||
} else if (strcmp(p, "tree")) {
|
||||
type = NPF_TABLE_RBTREE;
|
||||
} else {
|
||||
errx(EXIT_FAILURE, "invalid table type '%s'\n", p);
|
||||
errx(EXIT_FAILURE, "invalid table type '%s'", p);
|
||||
}
|
||||
if ((p = strchr(++p, '"')) == NULL) {
|
||||
return PARSE_ERR();
|
||||
|
@ -593,7 +592,10 @@ npfctl_parsetable(char *buf)
|
|||
/*
|
||||
* Setup the table.
|
||||
*/
|
||||
tl = npfctl_construct_table(id, type);
|
||||
tl = npf_table_create(id, type);
|
||||
if (npf_table_insert(npf_conf, tl)) {
|
||||
errx(EXIT_FAILURE, "table '%d' is already defined\n", id);
|
||||
}
|
||||
PARSE_NEXT_TOKEN();
|
||||
|
||||
/* Dynamic. */
|
||||
|
@ -621,17 +623,19 @@ npfctl_parsetable(char *buf)
|
|||
*
|
||||
* [bi]nat <if> from <net> to <net/addr> -> <ip>
|
||||
* rdr <if> from <net> to <addr> -> <ip>
|
||||
* nat <if> dynamic "<name>"
|
||||
*/
|
||||
static int
|
||||
npfctl_parse_nat(char *buf)
|
||||
{
|
||||
prop_dictionary_t nat, bn;
|
||||
var_t *ifvar, *from_cidr, *to_cidr, *ip;
|
||||
var_t *tports = NULL, *rports = NULL;
|
||||
element_t *cidr;
|
||||
char *p, *sptr;
|
||||
var_t *ifvar, *from_v, *to_v, *raddr_v;
|
||||
var_t *tports = NULL, *rport_v = NULL;
|
||||
char *p, *sptr, *raddr_s, *rport_s;
|
||||
in_addr_t raddr4, _dummy;
|
||||
npf_addr_t raddr;
|
||||
bool binat, rdr;
|
||||
u_int iface;
|
||||
nl_nat_t *nat;
|
||||
u_int if_idx;
|
||||
|
||||
DPRINTF(("[bi]nat/rdr\t|%s|\n", buf));
|
||||
binat = (strncmp(buf, "binat", 5) == 0);
|
||||
|
@ -646,15 +650,35 @@ npfctl_parse_nat(char *buf)
|
|||
if ((ifvar = npfctl_parsevalue(p)) == NULL) {
|
||||
return PARSE_ERR();
|
||||
}
|
||||
iface = npfctl_val_interface(ifvar, p, true);
|
||||
if_idx = npfctl_val_interface(ifvar, p, true);
|
||||
PARSE_NEXT_TOKEN();
|
||||
|
||||
/* dynamic <name> */
|
||||
if (!binat && !rdr && strcmp(p, "dynamic") == 0) {
|
||||
char *nname;
|
||||
|
||||
/* Parse name. */
|
||||
PARSE_NEXT_TOKEN()
|
||||
if (*p != '"')
|
||||
return PARSE_ERR();
|
||||
nname = ++p;
|
||||
if ((p = strchr(nname, '"')) == NULL)
|
||||
return PARSE_ERR();
|
||||
*p = '\0';
|
||||
|
||||
/* Create a rule and insert into the NAT list. */
|
||||
nat = npf_rule_create(nname, NPF_RULE_PASS | NPF_RULE_FINAL |
|
||||
NPF_RULE_OUT | NPF_RULE_IN, if_idx);
|
||||
(void)npf_nat_insert(npf_conf, nat, NPF_PRI_NEXT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* from <addr> */
|
||||
if (strcmp(p, "from") != 0) {
|
||||
return PARSE_ERR();
|
||||
}
|
||||
PARSE_NEXT_TOKEN();
|
||||
from_cidr = npfctl_parsevalue(p);
|
||||
from_v = npfctl_parsevalue(p);
|
||||
PARSE_NEXT_TOKEN();
|
||||
|
||||
/* to <addr> */
|
||||
|
@ -662,7 +686,7 @@ npfctl_parse_nat(char *buf)
|
|||
return PARSE_ERR();
|
||||
}
|
||||
PARSE_NEXT_TOKEN();
|
||||
to_cidr = npfctl_parsevalue(p);
|
||||
to_v = npfctl_parsevalue(p);
|
||||
PARSE_NEXT_TOKEN();
|
||||
|
||||
if (rdr && strcmp(p, "port") == 0) {
|
||||
|
@ -676,8 +700,10 @@ npfctl_parse_nat(char *buf)
|
|||
return PARSE_ERR();
|
||||
}
|
||||
PARSE_NEXT_TOKEN();
|
||||
ip = npfctl_parsevalue(p);
|
||||
cidr = ip->v_elements;
|
||||
raddr_v = npfctl_parsevalue(p);
|
||||
raddr_s = npfctl_val_single(raddr_v, p);
|
||||
npfctl_parse_cidr(raddr_s, &raddr4, &_dummy);
|
||||
memcpy(&raddr, &raddr4, sizeof(struct in_addr)); /* XXX IPv6 */
|
||||
|
||||
if (rdr) {
|
||||
PARSE_NEXT_TOKEN();
|
||||
|
@ -685,7 +711,8 @@ npfctl_parse_nat(char *buf)
|
|||
return PARSE_ERR();
|
||||
}
|
||||
PARSE_NEXT_TOKEN();
|
||||
rports = npfctl_parsevalue(p);
|
||||
rport_v = npfctl_parsevalue(p);
|
||||
rport_s = npfctl_val_single(rport_v, p);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -695,22 +722,25 @@ npfctl_parse_nat(char *buf)
|
|||
*
|
||||
* XXX mess
|
||||
*/
|
||||
nat = npfctl_mk_nat();
|
||||
|
||||
if (!rdr) {
|
||||
npfctl_rule_protodata(nat, NULL, NULL, -1, -1, from_cidr,
|
||||
NULL, to_cidr, NULL);
|
||||
npfctl_nat_setup(nat, NPF_NATOUT,
|
||||
nat = npf_nat_create(NPF_NATOUT,
|
||||
binat ? 0 : (NPF_NAT_PORTS | NPF_NAT_PORTMAP),
|
||||
iface, cidr->e_data, NULL);
|
||||
if_idx, &raddr, AF_INET, 0);
|
||||
} else {
|
||||
element_t *rp = rports->v_elements;
|
||||
in_port_t rport;
|
||||
bool range;
|
||||
|
||||
npfctl_rule_protodata(nat, NULL, NULL, -1, -1, from_cidr,
|
||||
NULL, to_cidr, tports);
|
||||
npfctl_nat_setup(nat, NPF_NATIN, NPF_NAT_PORTS,
|
||||
iface, cidr->e_data, rp->e_data);
|
||||
if (!npfctl_parse_port(rport_s, &range, &rport, &rport)) {
|
||||
errx(EXIT_FAILURE, "invalid service '%s'", rport_s);
|
||||
}
|
||||
if (range) {
|
||||
errx(EXIT_FAILURE, "range is not supported for 'rdr'");
|
||||
}
|
||||
nat = npf_nat_create(NPF_NATIN, NPF_NAT_PORTS,
|
||||
if_idx, &raddr, AF_INET, rport);
|
||||
}
|
||||
npfctl_rule_ncode(nat, NULL, NULL, -1, -1, from_v, NULL, to_v, tports);
|
||||
(void)npf_nat_insert(npf_conf, nat, NPF_PRI_NEXT);
|
||||
|
||||
/*
|
||||
* For bi-directional NAT case, create and setup additional
|
||||
|
@ -720,13 +750,17 @@ npfctl_parse_nat(char *buf)
|
|||
* XXX mess
|
||||
*/
|
||||
if (binat) {
|
||||
element_t *taddr = from_cidr->v_elements;
|
||||
char *taddr_s = npfctl_val_single(from_v, NULL);
|
||||
in_addr_t taddr4;
|
||||
npf_addr_t taddr;
|
||||
nl_nat_t *bn;
|
||||
|
||||
bn = npfctl_mk_nat();
|
||||
npfctl_rule_protodata(bn, NULL, NULL, -1, -1,
|
||||
to_cidr, NULL, ip, NULL);
|
||||
npfctl_nat_setup(bn, NPF_NATIN, 0, iface,
|
||||
taddr->e_data, NULL);
|
||||
npfctl_parse_cidr(taddr_s, &taddr4, &_dummy);
|
||||
memcpy(&taddr, &taddr4, sizeof(struct in_addr)); /* XXX IPv6 */
|
||||
bn = npf_nat_create(NPF_NATIN, 0, if_idx, &taddr, AF_INET, 0);
|
||||
npfctl_rule_ncode(bn, NULL, NULL, -1, -1,
|
||||
to_v, NULL, raddr_v, NULL);
|
||||
(void)npf_nat_insert(npf_conf, bn, NPF_PRI_NEXT);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -784,8 +818,8 @@ npfctl_parsevar(char *buf)
|
|||
int
|
||||
npf_parseline(char *buf)
|
||||
{
|
||||
static prop_dictionary_t curgr = NULL;
|
||||
static prop_dictionary_t currp = NULL;
|
||||
static nl_rule_t *curgr = NULL;
|
||||
static nl_rproc_t *currp = NULL;
|
||||
char *p = buf;
|
||||
int ret;
|
||||
|
||||
|
@ -797,16 +831,13 @@ npf_parseline(char *buf)
|
|||
|
||||
/* At first, check if inside the group or rproc. */
|
||||
if (curgr) {
|
||||
prop_dictionary_t rl;
|
||||
|
||||
/* End of the group. */
|
||||
if (*p == '}') {
|
||||
curgr = NULL;
|
||||
return 0;
|
||||
}
|
||||
/* Rule. */
|
||||
rl = npfctl_mk_rule(false, curgr);
|
||||
ret = npfctl_parserule(p, rl);
|
||||
ret = npfctl_parserule(p, curgr);
|
||||
|
||||
} else if (currp) {
|
||||
/* End of the procedure. */
|
||||
|
@ -819,13 +850,11 @@ npf_parseline(char *buf)
|
|||
|
||||
} else if (strncmp(p, "group", 5) == 0) {
|
||||
/* Group. */
|
||||
curgr = npfctl_mk_rule(true, NULL);
|
||||
ret = npfctl_parsegroup(p, curgr);
|
||||
ret = npfctl_parsegroup(p, &curgr);
|
||||
|
||||
} else if (strncmp(p, "procedure", 9) == 0) {
|
||||
/* Rule procedure. */
|
||||
currp = npfctl_mk_rproc();
|
||||
ret = npfctl_parserproc(p, currp);
|
||||
ret = npfctl_parserproc(p, &currp);
|
||||
|
||||
} else if (strncmp(p, "table", 5) == 0) {
|
||||
/* Table. */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npfctl.c,v 1.4 2011/01/18 20:33:45 rmind Exp $ */
|
||||
/* $NetBSD: npfctl.c,v 1.5 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -30,7 +30,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: npfctl.c,v 1.4 2011/01/18 20:33:45 rmind Exp $");
|
||||
__RCSID("$NetBSD: npfctl.c,v 1.5 2011/02/02 02:20:25 rmind Exp $");
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
|
@ -232,7 +232,7 @@ npfctl(int action, int argc, char **argv)
|
|||
if (ret) {
|
||||
break;
|
||||
}
|
||||
ret = npfctl_ioctl_flushse(fd);
|
||||
ret = npf_sessions_send(fd, NULL);
|
||||
break;
|
||||
case NPFCTL_TABLE:
|
||||
if (argc < 5) {
|
||||
|
@ -262,10 +262,18 @@ npfctl(int action, int argc, char **argv)
|
|||
ret = npfctl_print_stats(fd);
|
||||
break;
|
||||
case NPFCTL_SESSIONS_SAVE:
|
||||
ret = npfctl_ioctl_recvse(fd);
|
||||
ret = npf_sessions_recv(fd, NPF_SESSDB_PATH);
|
||||
if (ret) {
|
||||
errx(EXIT_FAILURE, "could not save sessions to '%s'",
|
||||
NPF_SESSDB_PATH);
|
||||
}
|
||||
break;
|
||||
case NPFCTL_SESSIONS_LOAD:
|
||||
ret = npfctl_ioctl_sendse(fd);
|
||||
ret = npf_sessions_send(fd, NPF_SESSDB_PATH);
|
||||
if (ret) {
|
||||
errx(EXIT_FAILURE, "no sessions loaded from '%s'",
|
||||
NPF_SESSDB_PATH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ret == -1) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: npfctl.h,v 1.5 2011/01/18 20:33:45 rmind Exp $ */
|
||||
/* $NetBSD: npfctl.h,v 1.6 2011/02/02 02:20:25 rmind Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2009-2011 The NetBSD Foundation, Inc.
|
||||
|
@ -33,13 +33,11 @@
|
|||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef _NPF_TESTING
|
||||
#include <net/npf.h>
|
||||
#include <net/npf_ncode.h>
|
||||
#else
|
||||
#include "npf.h"
|
||||
#include "npf_ncode.h"
|
||||
#endif
|
||||
#include <net/npf.h>
|
||||
|
||||
#define _NPF_PRIVATE
|
||||
#include <npf.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DPRINTF(x) printf x
|
||||
|
@ -68,34 +66,23 @@ typedef struct {
|
|||
void * v_next;
|
||||
} var_t;
|
||||
|
||||
extern nl_config_t * npf_conf;
|
||||
|
||||
void * zalloc(size_t);
|
||||
char * xstrdup(const char *);
|
||||
|
||||
void npfctl_init_data(void);
|
||||
int npfctl_ioctl_send(int);
|
||||
int npfctl_ioctl_recvse(int);
|
||||
int npfctl_ioctl_sendse(int);
|
||||
int npfctl_ioctl_flushse(int);
|
||||
|
||||
struct ifaddrs *npfctl_getif(char *, unsigned int *, bool);
|
||||
bool npfctl_parse_v4mask(char *, in_addr_t *, in_addr_t *);
|
||||
void npfctl_parse_cidr(char *, in_addr_t *, in_addr_t *);
|
||||
bool npfctl_parse_port(char *, bool *, in_port_t *, in_port_t *);
|
||||
|
||||
prop_dictionary_t npfctl_mk_rule(bool, prop_dictionary_t);
|
||||
void npfctl_rule_setattr(prop_dictionary_t, int, u_int);
|
||||
void npfctl_rule_protodata(prop_dictionary_t, char *, char *,
|
||||
void npfctl_fill_table(nl_table_t *, char *);
|
||||
|
||||
void npfctl_rule_ncode(nl_rule_t *, char *, char *,
|
||||
int, int, var_t *, var_t *, var_t *, var_t *);
|
||||
void npfctl_rule_icmpdata(prop_dictionary_t, var_t *, var_t *);
|
||||
|
||||
prop_dictionary_t npfctl_lookup_table(char *);
|
||||
prop_dictionary_t npfctl_construct_table(int, int);
|
||||
void npfctl_fill_table(prop_dictionary_t, char *);
|
||||
|
||||
prop_dictionary_t npfctl_mk_rproc(void);
|
||||
bool npfctl_find_rproc(prop_dictionary_t, char *);
|
||||
|
||||
prop_dictionary_t npfctl_mk_nat(void);
|
||||
void npfctl_nat_setup(prop_dictionary_t, int, int,
|
||||
u_int, char *, char *);
|
||||
|
||||
size_t npfctl_calc_ncsize(int []);
|
||||
size_t npfctl_failure_offset(int []);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.4 2009/04/22 15:23:06 lukem Exp $
|
||||
# $NetBSD: Makefile,v 1.5 2011/02/02 02:20:26 rmind Exp $
|
||||
# $OpenBSD: Makefile,v 1.3 2006/11/26 11:31:13 deraadt Exp $
|
||||
|
||||
PROG= ftp-proxy
|
||||
|
@ -13,6 +13,13 @@ CPPFLAGS+=-I${NETBSDSRCDIR}/sys
|
|||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
# NPF support
|
||||
.if (${MKNPF} != "no")
|
||||
SRCS+= npf.c
|
||||
CPPFLAGS+= -DWITH_NPF
|
||||
LDADD+= -lnpf
|
||||
.endif
|
||||
|
||||
# IP Filter support
|
||||
.if (${MKIPFILTER} != "no")
|
||||
SRCS+= ipf.c
|
||||
|
|
Loading…
Reference in New Issue