summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2008-09-09 13:56:40 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2008-09-09 13:56:40 +0000
commiteafa0437596580a038262a0363fdd2115f6f1726 (patch)
tree508e9ede5b29e41966fa0aa869df62cbd54600a3 /sbin
parent456e9ebf40a66cc20f4da77dbd097479607938d9 (diff)
welcome pflow(4), a netflow v5 compatible flow export interface.
flows export data gathered from pf states. initial implementation by Joerg Goltermann <jg@osn.de>, guidance and many changes by me. 'put it in' theo
Diffstat (limited to 'sbin')
-rw-r--r--sbin/ifconfig/ifconfig.c136
-rw-r--r--sbin/pfctl/parse.y25
-rw-r--r--sbin/pfctl/pf_print_state.c4
-rw-r--r--sbin/pfctl/pfctl_parser.c8
4 files changed, 167 insertions, 6 deletions
diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c
index 03b40456482..72103b1c197 100644
--- a/sbin/ifconfig/ifconfig.c
+++ b/sbin/ifconfig/ifconfig.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ifconfig.c,v 1.203 2008/09/07 02:22:34 deraadt Exp $ */
+/* $OpenBSD: ifconfig.c,v 1.204 2008/09/09 13:56:38 henning Exp $ */
/* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */
/*
@@ -79,6 +79,7 @@
#include <net80211/ieee80211_ioctl.h>
#include <net/pfvar.h>
#include <net/if_pfsync.h>
+#include <net/if_pflow.h>
#include <net/if_pppoe.h>
#include <net/if_trunk.h>
#include <net/if_sppp.h>
@@ -233,6 +234,14 @@ void trunk_status(void);
int main(int, char *[]);
int prefix(void *val, int);
+#ifndef SMALL
+void pflow_status(void);
+void setpflow_sender(const char *, int);
+void unsetpflow_sender(const char *, int);
+void setpflow_receiver(const char *, int);
+void unsetpflow_receiver(const char *, int);
+#endif
+
/*
* Media stuff. Whenever a media command is first performed, the
* currently select media is grabbed for this interface. If `media'
@@ -395,6 +404,12 @@ const struct cmd {
{ "descr", NEXTARG, 0, setifdesc },
{ "-description", 1, 0, unsetifdesc },
{ "-descr", 1, 0, unsetifdesc },
+#ifndef SMALL
+ { "flowsrc", NEXTARG, 0, setpflow_sender },
+ { "-flowsrc", 1, 0, unsetpflow_sender },
+ { "flowdst", NEXTARG, 0, setpflow_receiver },
+ { "-flowdst", 1, 0, unsetpflow_receiver },
+#endif
{ NULL, /*src*/ 0, 0, setifaddr },
{ NULL, /*dst*/ 0, 0, setifdstaddr },
{ NULL, /*illegal*/0, 0, NULL },
@@ -2592,6 +2607,7 @@ status(int link, struct sockaddr_dl *sdl)
sppp_status();
trunk_status();
mpe_status();
+ pflow_status();
#endif
getifgroups();
@@ -3674,6 +3690,124 @@ pfsync_status(void)
}
}
+#ifndef SMALL
+void
+pflow_status(void)
+{
+ struct pflowreq preq;
+
+ bzero((char *)&preq, sizeof(struct pflowreq));
+ ifr.ifr_data = (caddr_t)&preq;
+
+ if (ioctl(s, SIOCGETPFLOW, (caddr_t)&ifr) == -1)
+ return;
+
+ printf("\tpflow: sender: %s ", inet_ntoa(preq.sender_ip));
+ printf("receiver: %s:%u\n", inet_ntoa(preq.receiver_ip),
+ ntohs(preq.receiver_port));
+}
+
+/* ARGSUSED */
+void
+setpflow_sender(const char *val, int d)
+{
+ struct pflowreq preq;
+ struct addrinfo hints, *sender;
+ int ecode;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+
+ if ((ecode = getaddrinfo(val, NULL, &hints, &sender)) != 0)
+ errx(1, "error in parsing address string: %s",
+ gai_strerror(ecode));
+
+ if (sender->ai_addr->sa_family != AF_INET)
+ errx(1, "only IPv4 addresses supported for the sender");
+
+ bzero((char *)&preq, sizeof(struct pflowreq));
+ ifr.ifr_data = (caddr_t)&preq;
+ preq.addrmask |= PFLOW_MASK_SRCIP;
+ preq.sender_ip.s_addr = ((struct sockaddr_in *)
+ sender->ai_addr)->sin_addr.s_addr;
+
+
+ if (ioctl(s, SIOCSETPFLOW, (caddr_t)&ifr) == -1)
+ err(1, "SIOCSETPFLOW");
+
+ freeaddrinfo(sender);
+}
+
+void
+unsetpflow_sender(const char *val, int d)
+{
+ struct pflowreq preq;
+
+ bzero((char *)&preq, sizeof(struct pflowreq));
+ preq.addrmask |= PFLOW_MASK_SRCIP;
+ ifr.ifr_data = (caddr_t)&preq;
+ if (ioctl(s, SIOCSETPFLOW, (caddr_t)&ifr) == -1)
+ err(1, "SIOCSETPFLOW");
+}
+
+/* ARGSUSED */
+void
+setpflow_receiver(const char *val, int d)
+{
+ const char *errmsg = NULL;
+ struct pflowreq preq;
+ struct addrinfo hints, *receiver;
+ int ecode;
+ char *ip, *port, buf[MAXHOSTNAMELEN+sizeof (":65535")];
+
+ if (strchr (val, ':') == NULL)
+ errx(1, "%s bad value", val);
+
+ if (strlcpy(buf, val, sizeof(buf)) >= sizeof(buf))
+ errx(1, "%s bad value", val);
+ port = strchr(buf, ':');
+ *port++ = '\0';
+ ip = buf;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+
+ if ((ecode = getaddrinfo(ip, port, &hints, &receiver)) != 0)
+ errx(1, "error in parsing address string: %s",
+ gai_strerror(ecode));
+
+ if (receiver->ai_addr->sa_family != AF_INET)
+ errx(1, "only IPv4 addresses supported for the receiver");
+
+ bzero((char *)&preq, sizeof(struct pflowreq));
+ ifr.ifr_data = (caddr_t)&preq;
+ preq.addrmask |= PFLOW_MASK_DSTIP | PFLOW_MASK_DSTPRT;
+ preq.receiver_ip.s_addr = ((struct sockaddr_in *)
+ receiver->ai_addr)->sin_addr.s_addr;
+ preq.receiver_port = (u_int16_t) ((struct sockaddr_in *)
+ receiver->ai_addr)->sin_port;
+
+ if (ioctl(s, SIOCSETPFLOW, (caddr_t)&ifr) == -1)
+ err(1, "SIOCSETPFLOW");
+
+ freeaddrinfo(receiver);
+}
+
+void
+unsetpflow_receiver(const char *val, int d)
+{
+ struct pflowreq preq;
+
+ bzero((char *)&preq, sizeof(struct pflowreq));
+ ifr.ifr_data = (caddr_t)&preq;
+ preq.addrmask |= PFLOW_MASK_DSTIP | PFLOW_MASK_DSTPRT;
+ if (ioctl(s, SIOCSETPFLOW, (caddr_t)&ifr) == -1)
+ err(1, "SIOCSETPFLOW");
+}
+#endif /* SMALL */
+
void
pppoe_status(void)
{
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index c9ccec6f2c3..fc075f9b0ae 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.550 2008/08/07 18:29:32 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.551 2008/09/09 13:56:38 henning Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -153,7 +153,8 @@ enum { PF_STATE_OPT_MAX, PF_STATE_OPT_NOSYNC, PF_STATE_OPT_SRCTRACK,
PF_STATE_OPT_MAX_SRC_STATES, PF_STATE_OPT_MAX_SRC_CONN,
PF_STATE_OPT_MAX_SRC_CONN_RATE, PF_STATE_OPT_MAX_SRC_NODES,
PF_STATE_OPT_OVERLOAD, PF_STATE_OPT_STATELOCK,
- PF_STATE_OPT_TIMEOUT, PF_STATE_OPT_SLOPPY };
+ PF_STATE_OPT_TIMEOUT, PF_STATE_OPT_SLOPPY,
+ PF_STATE_OPT_PFLOW };
enum { PF_SRCTRACK_NONE, PF_SRCTRACK, PF_SRCTRACK_GLOBAL, PF_SRCTRACK_RULE };
@@ -442,7 +443,7 @@ int parseport(char *, struct range *r, int);
%token QUEUE PRIORITY QLIMIT RTABLE
%token LOAD RULESET_OPTIMIZATION
%token STICKYADDRESS MAXSRCSTATES MAXSRCNODES SOURCETRACK GLOBAL RULE
-%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY
+%token MAXSRCCONN MAXSRCCONNRATE OVERLOAD FLUSH SLOPPY PFLOW
%token TAGGED TAG IFBOUND FLOATING STATEPOLICY ROUTE SETTOS
%token DIVERTTO DIVERTREPLY
%token <v.string> STRING
@@ -2061,6 +2062,15 @@ pfrule : action dir logquick interface route af proto fromto
}
r.rule_flag |= PFRULE_STATESLOPPY;
break;
+ case PF_STATE_OPT_PFLOW:
+ if (r.rule_flag & PFRULE_PFLOW) {
+ yyerror("state pflow "
+ "option: multiple "
+ "definitions");
+ YYERROR;
+ }
+ r.rule_flag |= PFRULE_PFLOW;
+ break;
case PF_STATE_OPT_TIMEOUT:
if (o->data.timeout.number ==
PFTM_ADAPTIVE_START ||
@@ -3541,6 +3551,14 @@ state_opt_item : MAXIMUM NUMBER {
$$->next = NULL;
$$->tail = $$;
}
+ | PFLOW {
+ $$ = calloc(1, sizeof(struct node_state_opt));
+ if ($$ == NULL)
+ err(1, "state_opt_item: calloc");
+ $$->type = PF_STATE_OPT_PFLOW;
+ $$->next = NULL;
+ $$->tail = $$;
+ }
| STRING NUMBER {
int i;
@@ -5256,6 +5274,7 @@ lookup(char *s)
{ "out", OUT},
{ "overload", OVERLOAD},
{ "pass", PASS},
+ { "pflow", PFLOW},
{ "port", PORT},
{ "priority", PRIORITY},
{ "priq", PRIQ},
diff --git a/sbin/pfctl/pf_print_state.c b/sbin/pfctl/pf_print_state.c
index 73eef1199c7..b20fc941c16 100644
--- a/sbin/pfctl/pf_print_state.c
+++ b/sbin/pfctl/pf_print_state.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_print_state.c,v 1.52 2008/08/12 16:40:18 david Exp $ */
+/* $OpenBSD: pf_print_state.c,v 1.53 2008/09/09 13:56:38 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -325,6 +325,8 @@ print_state(struct pfsync_state *s, int opts)
printf(", rule %u", ntohl(s->rule));
if (s->state_flags & PFSTATE_SLOPPY)
printf(", sloppy");
+ if (s->state_flags & PFSTATE_PFLOW)
+ printf(", pflow");
if (s->sync_flags & PFSYNC_FLAG_SRCNODE)
printf(", source-track");
if (s->sync_flags & PFSYNC_FLAG_NATSRCNODE)
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 7368dbe7d3c..86c5f90ffeb 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.240 2008/06/10 20:55:02 mcbride Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.241 2008/09/09 13:56:38 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -934,6 +934,12 @@ print_rule(struct pf_rule *r, const char *anchor_call, int verbose)
printf("sloppy");
opts = 0;
}
+ if (r->rule_flag & PFRULE_PFLOW) {
+ if (!opts)
+ printf(", ");
+ printf("pflow");
+ opts = 0;
+ }
for (i = 0; i < PFTM_MAX; ++i)
if (r->timeout[i]) {
int j;