summaryrefslogtreecommitdiff
path: root/sbin/ifconfig/ifconfig.c
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/ifconfig/ifconfig.c
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/ifconfig/ifconfig.c')
-rw-r--r--sbin/ifconfig/ifconfig.c136
1 files changed, 135 insertions, 1 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)
{