xref: /openbsd-src/regress/sys/net/pflow/template.pl (revision bfa684ac25aa831afda4a9f0631fb3f41f0aaa88)
1#! /usr/bin/perl
2# $OpenBSD: template.pl,v 1.5 2017/03/03 21:34:14 bluhm Exp $
3
4# Copyright (c) 2013 Florian Obser <florian@openbsd.org>
5#
6# Permission to use, copy, modify, and distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18
19use strict;
20use warnings;
21
22use IO::Socket::INET;
23use Net::Flow;
24
25my $port = 9996;
26
27sub usage
28{
29	print STDERR "$0 [9|10]\n";
30	exit(1);
31}
32
33{
34	my $id2name = {
35		  1 => 'octetDeltaCount',
36		  2 => 'packetDeltaCount',
37		  4 => 'protocolIdentifier',
38		  5 => 'ipClassOfService',
39		  7 => 'sourceTransportPort',
40		  8 => 'sourceIPv4Address',
41		 10 => 'ingressInterface',
42		 11 => 'destinationTransportPort',
43		 12 => 'destinationIPv4Address',
44		 14 => 'egressInterface',
45		 21 => 'flowEndSysUpTime',
46		 22 => 'flowStartSysUpTime',
47		 27 => 'sourceIPv6Address',
48		 28 => 'destinationIPv6Address',
49		150 => 'flowStartSeconds',
50		151 => 'flowEndSeconds',
51		152 => 'flowStartMilliseconds',
52		153 => 'flowEndMilliseconds',
53	};
54	sub id2name { return $id2name->{$_[0]} || $_[0]; }
55}
56
57if (scalar(@ARGV) != 1 || ($ARGV[0] != 9 && $ARGV[0] != 10)) {
58	usage();
59}
60
61if (`ifconfig pflow0 2>&1` ne "pflow0: no such interface\n") {
62	system('ifconfig', 'pflow0', 'destroy');
63}
64
65my $sock = IO::Socket::INET->new( LocalPort =>$port, Proto => 'udp');
66my $pid = fork();
67if (!defined $pid) {
68	die 'cannot fork';
69} elsif ( $pid == 0) {
70	my ($packet, $header_ref, $template_ref, $flow_ref, $errors_ref);
71	$sock->recv($packet,1548);
72	($header_ref, $template_ref, $flow_ref, $errors_ref) =
73	    Net::Flow::decode(\$packet, $template_ref);
74	foreach my $template (@$template_ref) {
75		print('Template Id: ', $template->{TemplateId}, "\n");
76		foreach my $template_elem (@{$template->{Template}}) {
77			print(id2name($template_elem->{Id}), '(',
78			    $template_elem->{Length}, ')', "\n");
79		}
80	}
81} else {
82	close($sock);
83	system('ifconfig', 'pflow0', 'flowsrc', '127.0.0.1', 'flowdst',
84	    '127.0.0.1:9996', 'pflowproto', $ARGV[0]);
85	waitpid($pid, 0);
86	system('ifconfig', 'pflow0', 'destroy');
87}
88