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