diff options
author | Kristian Lyngstol <kristian@bohemians.org> | 2016-02-26 10:59:08 +0100 |
---|---|---|
committer | Kristian Lyngstol <kristian@bohemians.org> | 2016-02-26 10:59:08 +0100 |
commit | 9da864a8da29082369cdd2dd91a735b03577a117 (patch) | |
tree | 543d881f3746ddd4805dd0da449783eb42a8a92c /examples | |
parent | 9ecc4690b2546ac117204207bec21ee1f6d585cf (diff) |
Archive old/unused things
Diffstat (limited to 'examples')
23 files changed, 2502 insertions, 0 deletions
diff --git a/examples/historical/clients/lldpdiscover.pl b/examples/historical/clients/lldpdiscover.pl new file mode 100755 index 0000000..2f33bd9 --- /dev/null +++ b/examples/historical/clients/lldpdiscover.pl @@ -0,0 +1,247 @@ +#! /usr/bin/perl +use DBI; +use POSIX; +use Time::HiRes; +use strict; +use warnings; + +use lib '../include'; +use nms; + +my $dbh = nms::db_connect(); +$dbh->{AutoCommit} = 0; + +# If we are given one switch on the command line, add that and then exit. +my ($cmdline_ip, $cmdline_community) = @ARGV; +if (defined($cmdline_ip) && defined($cmdline_community)) { + eval { + my $session = nms::snmp_open_session($cmdline_ip, $cmdline_community); + my $sysname = $session->get('sysName.0'); + my $chassis_id = get_lldp_chassis_id($session); + add_switch($dbh, $cmdline_ip, $sysname, $chassis_id, $cmdline_community); + }; + if ($@) { + mylog("ERROR: $@ (during poll of $cmdline_ip)"); + $dbh->rollback; + } + $dbh->disconnect; + exit; +} + +# Find all candidate SNMP communities. +my $snmpq = $dbh->prepare("SELECT DISTINCT community FROM switches"); +$snmpq->execute; +my @communities = (); +while (my $ref = $snmpq->fetchrow_hashref) { + push @communities, $ref->{'community'}; +} + +# First, find all machines that lack an LLDP chassis ID. +my $q = $dbh->prepare("SELECT switch, ip, community FROM switches WHERE lldp_chassis_id IS NULL AND ip <> '127.0.0.1' and switchtype <> 'ex2200'"); +$q->execute; + +while (my $ref = $q->fetchrow_hashref) { + my ($switch, $ip, $community) = ($ref->{'switch'}, $ref->{'ip'}, $ref->{'community'}); + eval { + my $session = nms::snmp_open_session($ip, $community); + my $chassis_id = get_lldp_chassis_id($session); + die "SNMP error: " . $session->error() if (!defined($chassis_id)); + $dbh->do('UPDATE switches SET lldp_chassis_id=? WHERE switch=?', undef, + $chassis_id, $switch); + mylog("Set chassis ID for $ip to $chassis_id."); + }; + if ($@) { + mylog("ERROR: $@ (during poll of $ip)"); + $dbh->rollback; + } +} +$dbh->commit; + +# Now ask all switches for their LLDP neighbor table. +$q = $dbh->prepare("SELECT ip, sysname, community FROM switches WHERE lldp_chassis_id IS NOT NULL AND ip <> '127.0.0.1' AND switchtype <> 'ex2200'"); +$q->execute; + +while (my $ref = $q->fetchrow_hashref) { + my ($ip, $sysname, $community) = ($ref->{'ip'}, $ref->{'sysname'}, $ref->{'community'}); + eval { + discover_lldp_neighbors($dbh, $ip, $sysname, $community); + }; + if ($@) { + mylog("ERROR: $@ (during poll of $ip)"); + $dbh->rollback; + } + $dbh->commit; +} + +$dbh->disconnect; + +sub discover_lldp_neighbors { + my ($dbh, $ip, $local_sysname, $community) = @_; + my $qexist = $dbh->prepare('SELECT COUNT(*) AS cnt FROM switches WHERE lldp_chassis_id=?'); + + my $session = nms::snmp_open_session($ip, $community); + my $remtable = $session->gettable('lldpRemTable'); + my $addrtable; + while (my ($key, $value) = each %$remtable) { + my $chassis_id = nms::convert_mac($value->{'lldpRemChassisId'}); + my $sysname = $value->{'lldpRemSysName'}; + + # Do not try to poll servers. + my %caps = (); + nms::convert_lldp_caps($value->{'lldpRemSysCapEnabled'}, \%caps); + next if (!$caps{'cap_enabled_bridge'} && !$caps{'cap_enabled_router'}); + next if ($caps{'cap_enabled_ap'}); + next if ($caps{'cap_enabled_telephone'}); + + next if $sysname =~ /nocnexus/; + + my $sysdesc = $value->{'lldpRemSysDesc'}; + next if $sysdesc =~ /\b(C1530|C3600|C3700)\b/; + + my $exists = $dbh->selectrow_hashref($qexist, undef, $chassis_id)->{'cnt'}; + next if ($exists); + + print "Found $local_sysname -> $sysname ($chassis_id)\n"; + + # Pull in the management address table lazily. + $addrtable = $session->gettable("lldpRemManAddrTable") if (!defined($addrtable)); + + # Search for this key in the address table. + my @v4addrs = (); + my @v6addrs = (); + while (my ($addrkey, $addrvalue) = each %$addrtable) { + #next unless $addrkey =~ /^\Q$key\E\.1\.4\.(.*)$/; # 1.4 = ipv4, 2.16 = ipv6 + next unless $addrkey =~ /^\Q$key\E\./; # 1.4 = ipv4, 2.16 = ipv6 + my $addr = $addrvalue->{'lldpRemManAddr'}; + my $addrtype = $addrvalue->{'lldpRemManAddrSubtype'}; + if ($addrtype == 1) { + push @v4addrs, nms::convert_ipv4($addr); + } elsif ($addrtype == 2) { + my $v6addr = nms::convert_ipv6($addr); + next if $v6addr =~ /^fe80:/; # Ignore link-local. + push @v6addrs, $v6addr; + } else { + die "Unknown address type $addr"; + } + } + my $addr; + if (scalar @v6addrs > 0) { + $addr = $v6addrs[0]; + } elsif (scalar @v4addrs > 0) { + $addr = $v4addrs[0]; + } else { + warn "Could not find a management address for chassis ID $chassis_id (sysname=$sysname, lldpRemIndex=$key)"; + next; + } + + # We simply guess that the community is the same as ours. + add_switch($dbh, $addr, $sysname, $chassis_id, @communities); + } +} + +sub mylog { + my $msg = shift; + my $time = POSIX::ctime(time); + $time =~ s/\n.*$//; + printf STDERR "[%s] %s\n", $time, $msg; +} + +sub get_ports { + my ($ip, $sysname, $community) = @_; + my $ret = undef; + eval { + my $session = nms::snmp_open_session($ip, $community); + $ret = $session->gettable('ifTable', columns => [ 'ifType', 'ifDescr' ]); + }; + if ($@) { + mylog("Error during SNMP to $ip ($sysname): $@"); + return undef; + } + return $ret; +} + +sub get_ifindex_for_physical_ports { + my $ports = shift; + my @indices = (); + for my $port (values %$ports) { + next unless ($port->{'ifType'} eq 'ethernetCsmacd'); + push @indices, $port->{'ifIndex'}; + } + return @indices; +} + +sub compress_ports { + my (@ports) = @_; + my $current_range_start = undef; + my $last_port = undef; + + my @ranges = (); + for my $port (sort { $a <=> $b } (@ports)) { + if (!defined($current_range_start)) { + # First element. + $current_range_start = $last_port = $port; + next; + } + if ($port == $last_port + 1) { + # Just extend the current range. + ++$last_port; + } else { + push @ranges, range_from_to($current_range_start, $last_port); + $current_range_start = $last_port = $port; + } + } + push @ranges, range_from_to($current_range_start, $last_port); + return join(',', @ranges); +} + +sub range_from_to { + my ($from, $to) = @_; + if ($from == $to) { + return $from; + } else { + return "$from-$to"; + } +} + +sub add_switch { + my ($dbh, $addr, $sysname, $chassis_id, @communities) = @_; + + # Yay, a new switch! Make a new type for it. + my $ports; + my $community; + for my $cand_community (@communities) { + $community = $cand_community; + $ports = get_ports($addr, $sysname, $community); + last if (defined($ports)); + } + return if (!defined($ports)); + my $portlist = compress_ports(get_ifindex_for_physical_ports($ports)); + mylog("Inserting new switch $sysname ($addr, ports $portlist)."); + my $switchtype = "auto-$sysname-$chassis_id"; + $dbh->do('INSERT INTO switchtypes (switchtype, ports) VALUES (?, ?)', undef, + $switchtype, $portlist); + $dbh->do('INSERT INTO switches (ip, sysname, switchtype, community, lldp_chassis_id) VALUES (?, ?, ?, ?, ?)', undef, + $addr, $sysname, $switchtype, $community, $chassis_id); + for my $port (values %$ports) { + $dbh->do('INSERT INTO portnames (switchtype, port, description) VALUES (?, ?, ?)', + undef, $switchtype, $port->{'ifIndex'}, $port->{'ifDescr'}); + } + + # Entirely random placement. Annoying? Fix it yourself. + my $x = int(rand 1200); + my $y = int(rand 650); + my $box = sprintf "((%d,%d),(%d,%d))", $x, $y, $x+40, $y+40; + $dbh->do("INSERT INTO placements (switch,placement) VALUES (CURRVAL('switches_switch_seq'), ?)", + undef, $box); + + $dbh->commit; +} + +sub get_lldp_chassis_id { + my ($session) = @_; + + # Cisco returns completely bogus values if we use get() + # on lldpLocChassisId.0, it seems. Work around it by using getnext(). + my $response = $session->getnext('lldpLocChassisId'); + return nms::convert_mac($response); +} diff --git a/examples/historical/clients/portnames.pl b/examples/historical/clients/portnames.pl new file mode 100755 index 0000000..52e433a --- /dev/null +++ b/examples/historical/clients/portnames.pl @@ -0,0 +1,18 @@ +#! /usr/bin/perl + +my ($host,$switchtype,$community) = @ARGV; + +open SNMP, "snmpwalk -Os -c $community -v 2c $host -mALL ifDescr |" + or die "snmpwalk: $!"; + +print "begin;\n"; +print "delete from portnames where switchtype='$switchtype';\n"; + +while (<SNMP>) { + chomp; + /^ifDescr\.(\d+) = STRING: (.*)$/ or next; + + print "insert into portnames (switchtype,port,description) values ('$switchtype',$1,'$2 (port $1)');\n"; +} + +print "end;\n"; diff --git a/examples/historical/mbd/access_list.pl b/examples/historical/mbd/access_list.pl new file mode 100644 index 0000000..89a8182 --- /dev/null +++ b/examples/historical/mbd/access_list.pl @@ -0,0 +1,294 @@ + +package Config; + +sub game_id { + my ($data, $offset) = @_; + my $id = ((ord(substr($data, $offset, 1)) << 8) | ord(substr($data, $offset + 1, 1))); + return $id; +} + +our @access_list = ( + # half-life - untested (packet dump only) + { + name => 'Half-Life', + ports => [ 27015 ], + sizes => [ 16 ] + }, + + # cs 1.6 - verified + # (funker muligens for _alle_ source-spill inkl. hl2/cs:s) + { + name => 'CS:Source', + ports => [ "26900..26903", "27015..27017" ], + sizes => [ 25 ], + filter => sub { return (game_id(shift, 4) == 0x4325); } + }, + { + name => 'Left 4 Dead', + ports => [ "26900..26903", "27015..27017" ], + sizes => [ 25 ], + filter => sub { return (game_id(shift, 4) == 0x43f3); } + }, + { + name => 'CS 1.6', + ports => [ "26900..26903", "27015..27017" ], + sizes => [ 25 ], + filter => sub { return (game_id(shift, 4) == 0x5453); } + }, + { + name => 'Unknown Source-based game (ID 0x4326)', + ports => [ "26900..26903", "27015..27017" ], + sizes => [ 25 ], + filter => sub { return (game_id(shift, 4) == 0x4326); } + }, + { + name => 'Other Source game (unknown game ID)', + ports => [ "26900..26903", "27015..27017" ], + sizes => [ 25 ], + }, + { + name => 'Other Source game (unknown game ID, odd length 33)', + ports => [ "26900..26903", "27015..27017" ], + sizes => [ 33 ], + }, + { + name => 'Other Source game (unknown game ID, odd length 58)', + ports => [ "26900..26903", "27015..27017" ], + sizes => [ 58 ], + }, + { + name => 'Other Source game (unknown game ID, odd length 15)', + ports => [ "26900..26903", "27015..27017" ], + sizes => [ 15 ], + }, + + # doom 3 - verified + { + name => 'Doom 3', + ports => [ "27666" ], + sizes => [ 14 ] + }, + + # quake 1 - verified + { + name => 'Quake 1', + ports => [ 26000 ], + sizes => [ 12 ] + }, + + # q3a - tested with demo only + # rtcw: enemy territory - untested (packet dump only) + { + name => 'Quake 3 Arena, RTCW: ET', +# ports => [ "27960..27969" ], + ports => [ "27960..27961" ], + sizes => [ 15 ] + }, + + # bf2 - tested with demo only + # bf2142 reportedly uses same engine + { + name => 'BF2/BF2142', + ports => [ "29900" ], + sizes => [ 8 ] + }, + + # bf1942 - unverified (packet dump only) + { + name => 'BF1942', + ports => [ "22000..22010" ], + sizes => [ 8 ] + }, + + # quake 4 - tested with demo only, MUST select "internet" + { + name => 'Quake 4', + ports => [ 27950, 28004 ], + sizes => [ 14 ] + }, + + # quake 2 - untested (packet dump only) + { + name => 'Quake 2', + ports => [ 27910 ], + sizes => [ 11 ] + }, + + # warcraft 3 - untested (packet dump only) + { + name => 'Warcraft 3: Reign of Chaos (1.00)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x3352 && ord(substr($data, 8, 1)) == 0; } + }, + { + name => 'Warcraft 3: Reign of Chaos (1.07)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x3352 && ord(substr($data, 8, 1)) == 7; } + }, + { + name => 'Warcraft 3: Reign of Chaos (1.20)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x3352 && ord(substr($data, 8, 1)) == 20; } + }, + { + name => 'Warcraft 3: Reign of Chaos (1.22)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x3352 && ord(substr($data, 8, 1)) == 22; } + }, + { + name => 'Warcraft 3: Reign of Chaos (1.23)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x3352 && ord(substr($data, 8, 1)) == 23; } + }, + { + name => 'Warcraft 3: Reign of Chaos (other patch level)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x3352; } + }, + { + name => 'Warcraft 3: The Frozen Throne (1.17)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x5058 && ord(substr($data, 8, 1)) == 17; } + }, + { + name => 'Warcraft 3: The Frozen Throne (1.18)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x5058 && ord(substr($data, 8, 1)) == 18; } + }, + { + name => 'Warcraft 3: The Frozen Throne (1.20)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x5058 && ord(substr($data, 8, 1)) == 20; } + }, + { + name => 'Warcraft 3: The Frozen Throne (1.21)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x5058 && ord(substr($data, 8, 1)) == 21; } + }, + { + name => 'Warcraft 3: The Frozen Throne (1.22)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x5058 && ord(substr($data, 8, 1)) == 22; } + }, + { + name => 'Warcraft 3: The Frozen Throne (1.23)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x5058 && ord(substr($data, 8, 1)) == 23; } + }, + { + name => 'Warcraft 3: The Frozen Throne (1.26)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x5058 && ord(substr($data, 8, 1)) == 26; } + }, + { + name => 'Warcraft 3: The Frozen Throne (other patch level)', + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) == 0x5058; } + }, + { + name => 'Warcraft 3 (unknown version)', +# ports => [ "6112..6119" ], + ports => [ 6112 ], + sizes => [ 16 ], + filter => sub { my $data = shift; return (ord(substr($data, 1, 1)) == 0x2f) && game_id($data, 4) != 0x5058 && game_id($data, 4) != 0x3352; } + }, + { + name => 'Warcraft 3 (unknown version, odd length)', + ports => [ 6112 ], + sizes => [ 19 ], + }, + + # ut2003/ut2004 - untested (packet dump only) + { + name => 'UT2003/UT2004', + ports => [ 10777 ], + sizes => [ 5 ] + }, + + # soldat - untested (packet dump only) + { + name => 'Soldat', + ports => [ 23073 ], + sizes => [ 8 ] + }, + + # starcraft - untested (packet dump only) + { + name => 'Starcraft', + ports => [ 6111, 6112 ], + sizes => [ 8 ], + filter => sub { return (game_id(shift, 0) == 0x08ef); } + }, + { + name => 'Starcraft: Brood War', + ports => [ 6111, 6112 ], + sizes => [ 8 ], + filter => sub { return (game_id(shift, 0) == 0xf733); } + }, + { + name => 'Starcraft (unknown game ID)', + ports => [ 6111, 6112 ], + sizes => [ 8 ], + filter => sub { my $id = game_id(shift, 0); return ($id != 0x08ef && $id != 0xf733); } + }, + + # trackmania nations - untested (packet dump only) + { + name => 'Trackmania Nations', + ports => [ "2350" ], + sizes => [ 42, 30 ] + }, + + # company of heroes - untested (packet dump only) + { + name => 'Company of Heroes', + ports => [ 9100 ], + sizes => [ 39 ] + }, + + # command & conquer 3 - untested (packet dump only, reported to have some kind + # of chat functionality) +# { +# name => 'Command & Conquer 3', +# ports => [ "8086..8093" ], +# sizes => [ 476 ], +# filter => sub { return 0; } +# }, + + # openttd + { + name => 'OpenTTD', + ports => [ 3979 ], + sizes => [ 3 ] + }, + + # CoD4 + { + name => 'Call of Duty 4', + ports => [ 28960 ], + sizes => [ 15 ], + }, + + # Far Cry 2 + { + name => 'Far Cry 2', + ports => [ 9004 ], + sizes => [ 114, 118, 122, 126 ], + }, + + # unreal tournament, port 9777? +) diff --git a/examples/historical/mbd/derpspan.c b/examples/historical/mbd/derpspan.c new file mode 100644 index 0000000..b9fb362 --- /dev/null +++ b/examples/historical/mbd/derpspan.c @@ -0,0 +1,48 @@ +// gcc -O2 -o derspan derspan.c -lpcap -std=gnu99 -Wall + +#include <pcap.h> +#include <stdlib.h> +#include <netinet/ip.h> +#include <stdint.h> +#include <stdio.h> + +int rawsock; + +void my_callback(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) +{ + int len = h->caplen; + if (len < 40) { + //printf("skipped short packet\n"); + return; + } + if (bytes[14] != 0x88 || bytes[15] != 0xbe) { + //printf("skipped non-ethernet packet\n"); + return; + } + if (bytes[36] != 0x08 || bytes[37] != 0x00) { + //printf("skipped non-IPv4 packet\n"); + return; + } + + struct sockaddr_in self; + self.sin_family = AF_INET; + self.sin_addr.s_addr = htonl(0x7f000001); // localhost + self.sin_port = htons(1337); + + sendto(rawsock, bytes + 38, len - 38, 0, (struct sockaddr *)&self, sizeof(self)); +} + +int main(int argc, char **argv) +{ + rawsock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + if (rawsock == -1) { + perror("socket"); + exit(0); + } + + pcap_t *pcap = pcap_open_live(argv[1], 1500, 1, 1000, NULL); + pcap_activate(pcap); + pcap_loop(pcap, -1, my_callback, NULL); + return 0; +} + diff --git a/examples/historical/mbd/generate-helper-list.pl b/examples/historical/mbd/generate-helper-list.pl new file mode 100755 index 0000000..fd89475 --- /dev/null +++ b/examples/historical/mbd/generate-helper-list.pl @@ -0,0 +1,15 @@ +#! /usr/bin/perl +use strict; +use warnings; +require './access_list.pl'; +require './nets.pl'; +require './mbd.pm'; + +my @ports = mbd::find_all_ports(); + +print "no ip forward-protocol udp 137\n"; +print "no ip forward-protocol udp 138\n"; + +for my $port (@ports) { + print "ip forward-protocol udp $port\n"; +} diff --git a/examples/historical/mbd/make-mbd-nets.pl b/examples/historical/mbd/make-mbd-nets.pl new file mode 100755 index 0000000..7f6ec97 --- /dev/null +++ b/examples/historical/mbd/make-mbd-nets.pl @@ -0,0 +1,26 @@ +#!/usr/bin/perl -I /root/tgmanage/ +use strict; +use warnings; + +unless (@ARGV > 0) { + print "No arguments. Need netlist.txt.\n"; + exit 1; +} + +my $n = open(NETLIST, "$ARGV[0]") or die ("Cannot open netlist.txt"); + +print "# Autogenerated. Do not touch!\n"; +print "package Config;\n"; +print "our \@networks = (\n"; + +while(<NETLIST>) { + next if /^(.*#|\s+$)/; # skip if comment, or blank line + + chomp; + my ($v4_net, $v6_net, $net_name) = split; + + print "\t\"$v4_net\",\n"; +} + +print ");\n"; +print "1;\n"; diff --git a/examples/historical/mbd/mbd-unicast-segfaulting.pl b/examples/historical/mbd/mbd-unicast-segfaulting.pl new file mode 100644 index 0000000..c167511 --- /dev/null +++ b/examples/historical/mbd/mbd-unicast-segfaulting.pl @@ -0,0 +1,273 @@ +#! /usr/bin/perl +use strict; +use warnings; +use Socket; +use Net::CIDR; +use Net::RawIP; +use Time::HiRes; +require './access_list.pl'; +require './nets.pl'; +require './survey.pl'; +require './mbd.pm'; +use lib '../include'; +use nms; +use strict; +use warnings; +use threads; + +# Mark packets with DSCP CS7 +my $tos = 56; + +my ($dbh, $q); + +sub fhbits { + my $bits = 0; + for my $fh (@_) { + vec($bits, fileno($fh), 1) = 1; + } + return $bits; +} + +# used for rate limiting +my %last_sent = (); + +# for own surveying +my %active_surveys = (); +my %last_survey = (); + +my %cidrcache = (); +sub cache_cidrlookup { + my ($addr, $net) = @_; + my $key = $addr . " " . $net; + + if (!exists($cidrcache{$key})) { + $cidrcache{$key} = Net::CIDR::cidrlookup($addr, $net); + } + return $cidrcache{$key}; +} + +my %rangecache = (); +sub cache_cidrrange { + my ($net) = @_; + + if (!exists($rangecache{$net})) { + my ($range) = Net::CIDR::cidr2range($net); + $range =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)-(\d+)\.(\d+)\.(\d+)\.(\d+)/ or die "Did not understand range: $range"; + my @range = (); + for my $l (($4+1)..($8-1)) { + push @range, "$1.$2.$3.$l"; + } + ($rangecache{$net}) = \@range; + } + + return @{$rangecache{$net}}; +} + +open LOG, ">>", "mbd.log"; + +my @ports = ( mbd::find_all_ports() , $Config::survey_port_low .. $Config::survey_port_high ); + +# Open a socket for each port +my @socks = (); +my $udp = getprotobyname("udp"); +for my $p (@ports) { + my $sock; + socket($sock, PF_INET, SOCK_DGRAM, $udp); + bind($sock, sockaddr_in($p, INADDR_ANY)); + push @socks, $sock; +} + +my $sendsock = Net::RawIP->new({udp => {}}); + +print "Listening on " . scalar @ports . " ports.\n"; + +# Main loop +while (1) { + my $rin = fhbits(@socks); + my $rout; + + my $nfound = select($rout=$rin, undef, undef, undef); + my $now = [Time::HiRes::gettimeofday]; + + # First of all, close any surveys that are due. + for my $sport (keys %active_surveys) { + my $age = Time::HiRes::tv_interval($active_surveys{$sport}{start}, $now); + if ($age > $Config::survey_time && $active_surveys{$sport}{active}) { + my $hexdump = join(' ', map { sprintf "0x%02x", ord($_) } (split //, $active_surveys{$sport}{data})); + print "Survey ($hexdump) for '" . $Config::access_list[$active_surveys{$sport}{entry}]->{name} . "'/" . + $active_surveys{$sport}{dport} . ": " . $active_surveys{$sport}{num} . " active servers.\n"; + $active_surveys{$sport}{active} = 0; + + # (re)connect to the database if needed + if (!defined($dbh) || !$dbh->ping) { + $dbh = nms::db_connect(); + $q = $dbh->prepare("INSERT INTO mbd_log (ts,game,port,description,active_servers) VALUES (CURRENT_TIMESTAMP,?,?,?,?)") + or die "Couldn't prepare query"; + } + $q->execute($active_surveys{$sport}{entry}, $active_surveys{$sport}{dport}, $Config::access_list[$active_surveys{$sport}{entry}]->{name}, $active_surveys{$sport}{num}); + } + if ($age > $Config::survey_time * 3.0) { + delete $active_surveys{$sport}; + } + } + + for my $sock (@socks) { + next unless (vec($rout, fileno($sock), 1) == 1); + + my $data; + my $addr = recv($sock, $data, 8192, 0); # jumbo broadcast! :-P + my ($sport, $saddr) = sockaddr_in($addr); + my ($dport, $daddr) = sockaddr_in(getsockname($sock)); + my $size = length($data); + + # Check if this is a survey reply + if ($dport >= $Config::survey_port_low && $dport <= $Config::survey_port_high) { + if (!exists($active_surveys{$dport})) { + print "WARNING: Unknown survey port $dport, ignoring\n"; + next; + } + if (!$active_surveys{$dport}{active}) { + # remains + next; + } + + ++$active_surveys{$dport}{num}; + + next; + } + + # Rate limiting + if (exists($last_sent{$saddr}{$dport})) { + my $elapsed = Time::HiRes::tv_interval($last_sent{$saddr}{$dport}, $now); + if ($elapsed < 1.0) { + print LOG "$dport $size 2\n"; + print inet_ntoa($saddr), ", $dport, $size bytes => rate-limited ($elapsed secs since last)\n"; + next; + } + } + + # We don't get the packet's destination address, but I guess this should do... + # Check against the ACL. + my $pass = 0; + my $entry = -1; + for my $rule (@Config::access_list) { + ++$entry; + + next unless (mbd::match_ranges($dport, $rule->{'ports'})); + next unless (mbd::match_ranges($size, $rule->{'sizes'})); + + if ($rule->{'filter'}) { + next unless ($rule->{'filter'}($data)); + } + + $pass = 1; + last; + } + + print LOG "$dport $size $pass\n"; + + if (!$pass) { + print inet_ntoa($saddr), ", $dport, $size bytes => filtered\n"; + next; + } + + $last_sent{$saddr}{$dport} = $now; + + # The packet is OK! Do we already have a recent enough survey + # for this port, or should we use this packet? + my $survey = 1; + if (exists($last_survey{$entry . "/" . $dport})) { + my $age = Time::HiRes::tv_interval($last_survey{$entry . "/" . $dport}, $now); + if ($age < $Config::survey_freq) { + $survey = 0; + } + } + + # New survey; find an unused port + my $survey_sport; + if ($survey) { + for my $port ($Config::survey_port_low..$Config::survey_port_high) { + if (!exists($active_surveys{$port})) { + $survey_sport = $port; + + $active_surveys{$port} = { + start => $now, + active => 1, + dport => $dport, + entry => $entry, + num => 0, + data => $data, + }; + $last_survey{$entry . "/" . $dport} = $now; + + last; + } + } + + if (!defined($survey_sport)) { + print "WARNING: no free survey source ports, not surveying.\n"; + $survey = 0; + } + } + + # precache + for my $net (@Config::networks) { + cache_cidrrange($net); + cache_cidrlookup(inet_ntoa($saddr), $net); + } + + threads->create(sub { + my $sendsock = Net::RawIP->new({udp => {}}); + my ($survey_sport, $dport, $data) = @_; + + my $num_nets = 0; + for my $net (@Config::networks) { + my @daddrs = cache_cidrrange($net); + + if ($survey) { + for my $daddr (@daddrs) { + $sendsock->set({ + ip => { + saddr => $Config::survey_ip, + daddr => $daddr, + tos => $tos + }, + udp => { + source => $survey_sport, + dest => $dport, + data => $data + } + }); + $sendsock->send; + } + } + + next if (cache_cidrlookup(inet_ntoa($saddr), $net)); + + for my $daddr (@daddrs) { + $sendsock->set({ + ip => { + saddr => inet_ntoa($saddr), + daddr => $daddr, + tos => $tos + }, + udp => { + source => $sport, + dest => $dport, + data => $data + } + }); + $sendsock->send; + } + + ++$num_nets; + } + if ($survey) { + print inet_ntoa($saddr), ", $dport, $size bytes => ($num_nets networks) [+survey from port $survey_sport]\n"; + } else { + print inet_ntoa($saddr), ", $dport, $size bytes => ($num_nets networks)\n"; + } + }, $survey_sport, $dport, $data)->detach(); + } +} + diff --git a/examples/historical/mbd/mbd-unicast.pl b/examples/historical/mbd/mbd-unicast.pl new file mode 100644 index 0000000..6e63dee --- /dev/null +++ b/examples/historical/mbd/mbd-unicast.pl @@ -0,0 +1,254 @@ +#! /usr/bin/perl +use strict; +use warnings; +use Socket; +use Net::CIDR; +use Net::RawIP; +use Time::HiRes; +require './access_list.pl'; +require './nets.pl'; +require './survey.pl'; +require './mbd.pm'; +use lib '../include'; +use nms; +use strict; +use warnings; +use threads; + +# Mark packets with DSCP CS7 +my $tos = 56; + +my ($dbh, $q); + +sub fhbits { + my $bits = 0; + for my $fh (@_) { + vec($bits, fileno($fh), 1) = 1; + } + return $bits; +} + +# used for rate limiting +my %last_sent = (); + +# for own surveying +my %active_surveys = (); +my %last_survey = (); + +my %cidrcache = (); +sub cache_cidrlookup { + my ($addr, $net) = @_; + my $key = $addr . " " . $net; + + if (!exists($cidrcache{$key})) { + $cidrcache{$key} = Net::CIDR::cidrlookup($addr, $net); + } + return $cidrcache{$key}; +} + +my %rangecache = (); +sub cache_cidrrange { + my ($net) = @_; + + if (!exists($rangecache{$net})) { + my ($range) = Net::CIDR::cidr2range($net); + $range =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)-(\d+)\.(\d+)\.(\d+)\.(\d+)/ or die "Did not understand range: $range"; + my @range = (); + for my $l (($4+1)..($8-1)) { + push @range, "$1.$2.$3.$l"; + } + ($rangecache{$net}) = \@range; + } + + return @{$rangecache{$net}}; +} + +open LOG, ">>", "mbd.log"; + +my @ports = ( mbd::find_all_ports() , $Config::survey_port_low .. $Config::survey_port_high ); + +# Open a socket for each port +my @socks = (); +my $udp = getprotobyname("udp"); +for my $p (@ports) { + my $sock; + socket($sock, PF_INET, SOCK_DGRAM, $udp); + bind($sock, sockaddr_in($p, INADDR_ANY)); + push @socks, $sock; +} + +my $sendsock = Net::RawIP->new({udp => {}}); + +print "Listening on " . scalar @ports . " ports.\n"; + +open PKTS, "| ./packetpusher" + or die "./packetpusher: $!"; + +# Main loop +while (1) { + my $rin = fhbits(@socks); + my $rout; + + my $nfound = select($rout=$rin, undef, undef, undef); + my $now = [Time::HiRes::gettimeofday]; + + # First of all, close any surveys that are due. + for my $sport (keys %active_surveys) { + my $age = Time::HiRes::tv_interval($active_surveys{$sport}{start}, $now); + if ($age > $Config::survey_time && $active_surveys{$sport}{active}) { + my $hexdump = join(' ', map { sprintf "0x%02x", ord($_) } (split //, $active_surveys{$sport}{data})); + print "Survey ($hexdump) for '" . $Config::access_list[$active_surveys{$sport}{entry}]->{name} . "'/" . + $active_surveys{$sport}{dport} . ": " . $active_surveys{$sport}{num} . " active servers.\n"; + $active_surveys{$sport}{active} = 0; + + # (re)connect to the database if needed + if (!defined($dbh) || !$dbh->ping) { + $dbh = nms::db_connect(); + $q = $dbh->prepare("INSERT INTO mbd_log (ts,game,port,description,active_servers) VALUES (CURRENT_TIMESTAMP,?,?,?,?)") + or die "Couldn't prepare query"; + } + $q->execute($active_surveys{$sport}{entry}, $active_surveys{$sport}{dport}, $Config::access_list[$active_surveys{$sport}{entry}]->{name}, $active_surveys{$sport}{num}); + } + if ($age > $Config::survey_time * 3.0) { + delete $active_surveys{$sport}; + } + } + + for my $sock (@socks) { + next unless (vec($rout, fileno($sock), 1) == 1); + + my $data; + my $addr = recv($sock, $data, 8192, 0); # jumbo broadcast! :-P + my ($sport, $saddr) = sockaddr_in($addr); + my ($dport, $daddr) = sockaddr_in(getsockname($sock)); + my $size = length($data); + + # Check if this is a survey reply + if ($dport >= $Config::survey_port_low && $dport <= $Config::survey_port_high) { + if (!exists($active_surveys{$dport})) { + print "WARNING: Unknown survey port $dport, ignoring\n"; + next; + } + if (!$active_surveys{$dport}{active}) { + # remains + next; + } + + ++$active_surveys{$dport}{num}; + + next; + } + + # Rate limiting + if (exists($last_sent{$saddr}{$dport})) { + my $elapsed = Time::HiRes::tv_interval($last_sent{$saddr}{$dport}, $now); + if ($elapsed < 1.0) { + print LOG "$dport $size 2\n"; + print inet_ntoa($saddr), ", $dport, $size bytes => rate-limited ($elapsed secs since last)\n"; + next; + } + } + + # We don't get the packet's destination address, but I guess this should do... + # Check against the ACL. + my $pass = 0; + my $entry = -1; + for my $rule (@Config::access_list) { + ++$entry; + + next unless (mbd::match_ranges($dport, $rule->{'ports'})); + next unless (mbd::match_ranges($size, $rule->{'sizes'})); + + if ($rule->{'filter'}) { + next unless ($rule->{'filter'}($data)); + } + + $pass = 1; + last; + } + + print LOG "$dport $size $pass\n"; + + if (!$pass) { + print inet_ntoa($saddr), ", $dport, $size bytes => filtered\n"; + next; + } + + $last_sent{$saddr}{$dport} = $now; + + # The packet is OK! Do we already have a recent enough survey + # for this port, or should we use this packet? + my $survey = 1; + if (exists($last_survey{$entry . "/" . $dport})) { + my $age = Time::HiRes::tv_interval($last_survey{$entry . "/" . $dport}, $now); + if ($age < $Config::survey_freq) { + $survey = 0; + } + } + + # New survey; find an unused port + my $survey_sport; + if ($survey) { + for my $port ($Config::survey_port_low..$Config::survey_port_high) { + if (!exists($active_surveys{$port})) { + $survey_sport = $port; + + $active_surveys{$port} = { + start => $now, + active => 1, + dport => $dport, + entry => $entry, + num => 0, + data => $data, + }; + $last_survey{$entry . "/" . $dport} = $now; + + last; + } + } + + if (!defined($survey_sport)) { + print "WARNING: no free survey source ports, not surveying.\n"; + $survey = 0; + } + } + + # precache + for my $net (@Config::networks) { + cache_cidrrange($net); + cache_cidrlookup(inet_ntoa($saddr), $net); + } + + my @packets = (); + + my $num_nets = 0; + for my $net (@Config::networks) { + my @daddrs = cache_cidrrange($net); + + if ($survey) { + for my $daddr (@daddrs) { + push @packets, [ $Config::survey_ip, $survey_sport, $daddr, $dport ]; + } + } + + next if (cache_cidrlookup(inet_ntoa($saddr), $net)); + + for my $daddr (@daddrs) { + push @packets, [ inet_ntoa($saddr), $sport, $daddr, $dport ]; + } + + ++$num_nets; + } + if ($survey) { + print inet_ntoa($saddr), ", $dport, $size bytes => ($num_nets networks) [+survey from port $survey_sport]\n"; + } else { + print inet_ntoa($saddr), ", $dport, $size bytes => ($num_nets networks)\n"; + } + + printf PKTS "%d %s\n", scalar @packets, unpack('h*', $data); + for my $pkt (@packets) { + printf PKTS "%s %s %s %s\n", $pkt->[0], $pkt->[1], $pkt->[2], $pkt->[3]; + } + } +} + diff --git a/examples/historical/mbd/mbd.pl b/examples/historical/mbd/mbd.pl new file mode 100644 index 0000000..065e76c --- /dev/null +++ b/examples/historical/mbd/mbd.pl @@ -0,0 +1,254 @@ +#! /usr/bin/perl +use strict; +use warnings; +use Socket; +use Net::CIDR; +use Net::RawIP; +use Time::HiRes; +require './access_list.pl'; +require './nets.pl'; +require './survey.pl'; +require './mbd.pm'; +use lib '../include'; +use nms; +use strict; +use warnings; + +# Mark packets with DSCP CS7 +my $tos = 56; + +my ($dbh, $q); + +sub fhbits { + my $bits = 0; + for my $fh (@_) { + vec($bits, fileno($fh), 1) = 1; + } + return $bits; +} + +# used for rate limiting +my %last_sent = (); + +# for own surveying +my %active_surveys = (); +my %last_survey = (); + +my %cidrcache = (); +sub cache_cidrlookup { + my ($addr, $net) = @_; + my $key = $addr . " " . $net; + + if (!exists($cidrcache{$key})) { + $cidrcache{$key} = Net::CIDR::cidrlookup($addr, $net); + } + return $cidrcache{$key}; +} + +my %rangecache = (); +sub cache_cidrrange { + my ($net) = @_; + + if (!exists($rangecache{$net})) { + ($rangecache{$net}) = Net::CIDR::cidr2range($net); + } + + return $rangecache{$net}; +} + +open LOG, ">>", "mbd.log"; + +my @ports = ( mbd::find_all_ports() , $Config::survey_port_low .. $Config::survey_port_high ); + +# Open a socket for each port +my @socks = (); +my $udp = getprotobyname("udp"); +for my $p (@ports) { + my $sock; + socket($sock, PF_INET, SOCK_DGRAM, $udp); + bind($sock, sockaddr_in($p, INADDR_ANY)); + push @socks, $sock; +} + +my $sendsock = Net::RawIP->new({udp => {}}); + +print "Listening on " . scalar @ports . " ports.\n"; + +# Main loop +while (1) { + my $rin = fhbits(@socks); + my $rout; + + my $nfound = select($rout=$rin, undef, undef, undef); + my $now = [Time::HiRes::gettimeofday]; + + # First of all, close any surveys that are due. + for my $sport (keys %active_surveys) { + my $age = Time::HiRes::tv_interval($active_surveys{$sport}{start}, $now); + if ($age > $Config::survey_time && $active_surveys{$sport}{active}) { + my $hexdump = join(' ', map { sprintf "0x%02x", ord($_) } (split //, $active_surveys{$sport}{data})); + print "Survey ($hexdump) for '" . $Config::access_list[$active_surveys{$sport}{entry}]->{name} . "'/" . + $active_surveys{$sport}{dport} . ": " . $active_surveys{$sport}{num} . " active servers.\n"; + $active_surveys{$sport}{active} = 0; + + # (re)connect to the database if needed + if (!defined($dbh) || !$dbh->ping) { + $dbh = nms::db_connect(); + $q = $dbh->prepare("INSERT INTO mbd_log (ts,game,port,description,active_servers) VALUES (CURRENT_TIMESTAMP,?,?,?,?)") + or die "Couldn't prepare query"; + } + $q->execute($active_surveys{$sport}{entry}, $active_surveys{$sport}{dport}, $Config::access_list[$active_surveys{$sport}{entry}]->{name}, $active_surveys{$sport}{num}); + } + if ($age > $Config::survey_time * 3.0) { + delete $active_surveys{$sport}; + } + } + + for my $sock (@socks) { + next unless (vec($rout, fileno($sock), 1) == 1); + + my $data; + my $addr = recv($sock, $data, 8192, 0); # jumbo broadcast! :-P + my ($sport, $saddr) = sockaddr_in($addr); + my ($dport, $daddr) = sockaddr_in(getsockname($sock)); + my $size = length($data); + + # Check if this is a survey reply + if ($dport >= $Config::survey_port_low && $dport <= $Config::survey_port_high) { + if (!exists($active_surveys{$dport})) { + print "WARNING: Unknown survey port $dport, ignoring\n"; + next; + } + if (!$active_surveys{$dport}{active}) { + # remains + next; + } + + ++$active_surveys{$dport}{num}; + + next; + } + + # Rate limiting + if (exists($last_sent{$saddr}{$dport})) { + my $elapsed = Time::HiRes::tv_interval($last_sent{$saddr}{$dport}, $now); + if ($elapsed < 1.0) { + print LOG "$dport $size 2\n"; + print inet_ntoa($saddr), ", $dport, $size bytes => rate-limited ($elapsed secs since last)\n"; + next; + } + } + + # We don't get the packet's destination address, but I guess this should do... + # Check against the ACL. + my $pass = 0; + my $entry = -1; + for my $rule (@Config::access_list) { + ++$entry; + + next unless (mbd::match_ranges($dport, $rule->{'ports'})); + next unless (mbd::match_ranges($size, $rule->{'sizes'})); + + if ($rule->{'filter'}) { + next unless ($rule->{'filter'}($data)); + } + + $pass = 1; + last; + } + + print LOG "$dport $size $pass\n"; + + if (!$pass) { + print inet_ntoa($saddr), ", $dport, $size bytes => filtered\n"; + next; + } + + $last_sent{$saddr}{$dport} = $now; + + # The packet is OK! Do we already have a recent enough survey + # for this port, or should we use this packet? + my $survey = 1; + if (exists($last_survey{$entry . "/" . $dport})) { + my $age = Time::HiRes::tv_interval($last_survey{$entry . "/" . $dport}, $now); + if ($age < $Config::survey_freq) { + $survey = 0; + } + } + + # New survey; find an unused port + my $survey_sport; + if ($survey) { + for my $port ($Config::survey_port_low..$Config::survey_port_high) { + if (!exists($active_surveys{$port})) { + $survey_sport = $port; + + $active_surveys{$port} = { + start => $now, + active => 1, + dport => $dport, + entry => $entry, + num => 0, + data => $data, + }; + $last_survey{$entry . "/" . $dport} = $now; + + last; + } + } + + if (!defined($survey_sport)) { + print "WARNING: no free survey source ports, not surveying.\n"; + $survey = 0; + } + } + + my $num_nets = 0; + for my $net (@Config::networks) { + my ($range) = cache_cidrrange($net); + $range =~ /-(.*?)$/; + my $broadcast = $1; + + if ($survey) { + $sendsock->set({ + ip => { + saddr => $Config::survey_ip, + daddr => $broadcast, + tos => $tos + }, + udp => { + source => $survey_sport, + dest => $dport, + data => $data + } + }); + $sendsock->send; + } + + next if (cache_cidrlookup(inet_ntoa($saddr), $net)); + + $sendsock->set({ + ip => { + saddr => inet_ntoa($saddr), + daddr => $broadcast, + tos => $tos + }, + udp => { + source => $sport, + dest => $dport, + data => $data + } + }); + $sendsock->send; + + ++$num_nets; + } + + if ($survey) { + print inet_ntoa($saddr), ", $dport, $size bytes => ($num_nets networks) [+survey from port $survey_sport]\n"; + } else { + print inet_ntoa($saddr), ", $dport, $size bytes => ($num_nets networks)\n"; + } + } +} + diff --git a/examples/historical/mbd/mbd.pm b/examples/historical/mbd/mbd.pm new file mode 100644 index 0000000..b844e5b --- /dev/null +++ b/examples/historical/mbd/mbd.pm @@ -0,0 +1,50 @@ +#! /usr/bin/perl +use strict; +use warnings; +use Socket; +use Net::CIDR; +use Net::RawIP; +require './access_list.pl'; +require './nets.pl'; + +package mbd; + +sub expand_range { + my $range = shift; + + if ($range =~ /^(\d+)\.\.(\d+)$/) { + return $1..$2; + } else { + return $range; + } +} + +sub match_ranges { + my ($elem, $ranges) = @_; + + for my $range (@$ranges) { + if ($range =~ /^(\d+)\.\.(\d+)$/) { + return 1 if ($elem >= $1 && $elem <= $2); + } else { + return 1 if ($elem == $range); + } + } + + return 0; +} + +sub find_all_ports { + # Find what ports we need to listen on + my %port_hash = (); + for my $e (@Config::access_list) { + for my $r (@{$e->{'ports'}}) { + for my $p (expand_range($r)) { + $port_hash{$p} = 1; + } + } + } + my @ports = sort { $a <=> $b } keys %port_hash; + return @ports; +} + +1; diff --git a/examples/historical/mbd/nets.pl b/examples/historical/mbd/nets.pl new file mode 100644 index 0000000..3298657 --- /dev/null +++ b/examples/historical/mbd/nets.pl @@ -0,0 +1,171 @@ +# Autogenerated. Do not touch! +package Config; +our @networks = ( + "176.110.98.0/24", + "176.110.99.0/24", + "176.110.100.0/24", + "176.110.102.0/24", + "176.110.103.0/24", + "176.110.106.0/24", + "176.110.107.0/24", + "176.110.108.0/22", + "176.110.112.0/24", + "176.110.113.0/24", + "176.110.114.0/24", + "176.110.115.0/24", + "176.110.116.0/24", + "176.110.117.0/24", + "176.110.118.0/24", + "176.110.119.0/24", + "176.110.120.0/24", + "176.110.121.0/24", + "176.110.122.0/24", + "176.110.123.0/24", + "176.110.124.0/24", + "176.110.126.0/24", + "176.110.2.0/25", + "176.110.2.128/25", + "176.110.4.0/25", + "176.110.4.128/25", + "176.110.6.0/25", + "176.110.6.128/25", + "176.110.8.0/25", + "176.110.8.128/25", + "176.110.10.0/25", + "176.110.10.128/25", + "176.110.11.0/25", + "176.110.11.128/25", + "176.110.12.0/25", + "176.110.12.128/25", + "176.110.13.0/25", + "176.110.13.128/25", + "176.110.14.0/25", + "176.110.14.128/25", + "176.110.15.0/25", + "176.110.15.128/25", + "176.110.16.0/25", + "176.110.16.128/25", + "176.110.17.0/25", + "176.110.17.128/25", + "176.110.18.0/25", + "176.110.18.128/25", + "176.110.19.0/25", + "176.110.19.128/25", + "176.110.20.0/25", + "176.110.20.128/25", + "176.110.21.0/25", + "176.110.21.128/25", + "176.110.22.0/25", + "176.110.22.128/25", + "176.110.23.0/25", + "176.110.23.128/25", + "176.110.24.0/25", + "176.110.24.128/25", + "176.110.25.0/25", + "176.110.25.128/25", + "176.110.26.0/25", + "176.110.26.128/25", + "176.110.27.0/25", + "176.110.27.128/25", + "176.110.29.0/25", + "176.110.29.128/25", + "176.110.31.0/25", + "176.110.31.128/25", + "176.110.33.0/25", + "176.110.33.128/25", + "176.110.35.0/25", + "176.110.35.128/25", + "176.110.37.0/25", + "176.110.37.128/25", + "176.110.39.0/25", + "176.110.39.128/25", + "176.110.41.0/25", + "176.110.41.128/25", + "176.110.43.0/25", + "176.110.43.128/25", + "176.110.44.0/25", + "176.110.44.128/25", + "176.110.45.0/25", + "176.110.45.128/25", + "176.110.46.0/25", + "176.110.46.128/25", + "176.110.47.0/25", + "176.110.47.128/25", + "176.110.48.0/25", + "176.110.48.128/25", + "176.110.49.0/25", + "176.110.49.128/25", + "176.110.50.0/25", + "176.110.50.128/25", + "176.110.51.0/25", + "176.110.51.128/25", + "176.110.52.0/25", + "176.110.52.128/25", + "176.110.53.0/25", + "176.110.53.128/25", + "176.110.54.0/25", + "176.110.54.128/25", + "176.110.55.0/25", + "176.110.55.128/25", + "176.110.56.0/25", + "176.110.56.128/25", + "176.110.57.0/25", + "176.110.57.128/25", + "176.110.58.0/25", + "176.110.58.128/25", + "176.110.59.0/25", + "176.110.59.128/25", + "176.110.60.0/25", + "176.110.60.128/25", + "176.110.61.0/25", + "176.110.61.128/25", + "176.110.62.0/25", + "176.110.62.128/25", + "176.110.63.0/25", + "176.110.63.128/25", + "176.110.64.0/25", + "176.110.64.128/25", + "176.110.65.0/25", + "176.110.65.128/25", + "176.110.66.0/25", + "176.110.66.128/25", + "176.110.67.0/25", + "176.110.67.128/25", + "176.110.68.0/25", + "176.110.68.128/25", + "176.110.69.0/25", + "176.110.69.128/25", + "176.110.70.0/25", + "176.110.70.128/25", + "176.110.71.0/25", + "176.110.71.128/25", + "176.110.72.0/25", + "176.110.72.128/25", + "176.110.73.0/25", + "176.110.73.128/25", + "176.110.74.0/25", + "176.110.74.128/25", + "176.110.75.0/25", + "176.110.75.128/25", + "176.110.76.0/25", + "176.110.76.128/25", + "176.110.77.0/25", + "176.110.77.128/25", + "176.110.79.0/25", + "176.110.79.128/25", + "176.110.81.0/25", + "176.110.81.128/25", + "176.110.83.0/25", + "176.110.83.128/25", + "176.110.84.0/25", + "176.110.84.128/25", + "176.110.85.0/25", + "176.110.85.128/25", + "176.110.86.0/25", + "176.110.86.128/25", + "176.110.87.0/25", + "176.110.87.128/25", + "176.110.88.0/25", + "176.110.88.128/25", +); +1; diff --git a/examples/historical/mbd/packetpusher.c b/examples/historical/mbd/packetpusher.c new file mode 100644 index 0000000..c21a084 --- /dev/null +++ b/examples/historical/mbd/packetpusher.c @@ -0,0 +1,127 @@ +#include <stdio.h> +#include <sys/socket.h> +#include <stdlib.h> +#include <string.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/udp.h> +#include <stdint.h> +#include <arpa/inet.h> + +char encoded_pkt[4096], workspace[4096]; +unsigned char pkt[2048]; + +typedef uint32_t u_int32_t; + +u_int32_t checksum(unsigned char *buf, unsigned nbytes, u_int32_t sum) +{ + int i; + /* Checksum all the pairs of bytes first... */ + for (i = 0; i < (nbytes & ~1U); i += 2) { + sum += (u_int16_t)ntohs(*((u_int16_t *)(buf + i))); + if (sum > 0xFFFF) + sum -= 0xFFFF; + } + + /* + * If there's a single byte left over, checksum it, too. + * Network byte order is big-endian, so the remaining byte is + * the high byte. + */ + + if (i < nbytes) { + sum += buf[i] << 8; + if (sum > 0xFFFF) + sum -= 0xFFFF; + } + + return (sum); +} + +u_int32_t wrapsum(u_int32_t sum) +{ + sum = ~sum & 0xFFFF; + return (htons(sum)); +} + +int main(int argc, char **argv) +{ + int sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + if (sock == -1) { + perror("socket"); + exit(1); + } + + for ( ;; ) { + int num_pkts; + int ret = scanf("%d %s", &num_pkts, encoded_pkt); + if (ret != 2) { + fprintf(stderr, "error parsing! ret=%d\n", ret); + exit(1); + } + if ((strlen(encoded_pkt) % 2) != 0) { + fprintf(stderr, "hex packet has odd length\n"); + exit(1); + } + + // de-hex packet + for (int i = 0; i < strlen(encoded_pkt); i += 2) { + char c[3]; + c[0] = encoded_pkt[i]; + c[1] = encoded_pkt[i + 1]; + c[2] = 0; + int h = strtol(c, NULL, 16); + pkt[i / 2] = h; + } + + int datalen = strlen(encoded_pkt) / 2; + + for (int i = 0; i < num_pkts; ++i) { + char from_ip[256], to_ip[256]; + int sport, dport; + if (scanf("%s %d %s %d", from_ip, &sport, to_ip, &dport) != 4) { + fprintf(stderr, "error parsing packet %d!\n", i); + exit(1); + } + + // IP header + struct iphdr *ip = (struct iphdr *)workspace; + ip->version = 4; + ip->ihl = 5; + ip->tos = 0; + ip->tot_len = htons(datalen + sizeof(struct iphdr) + sizeof(struct udphdr)); + ip->id = 0; + ip->frag_off = 0; + ip->ttl = 64; + ip->protocol = 17; // UDP + ip->saddr = inet_addr(from_ip); + ip->daddr = inet_addr(to_ip); + ip->check = 0; + ip->check = wrapsum(checksum((unsigned char *)ip, sizeof(*ip), 0)); + + // UDP header + struct udphdr *udp = (struct udphdr *)(workspace + sizeof(struct iphdr)); + udp->source = htons(sport); + udp->dest = htons(dport); + udp->len = htons(datalen + sizeof(struct udphdr)); + udp->check = 0; + + int sum = checksum((unsigned char *)&ip->saddr, 2 * sizeof(ip->saddr), IPPROTO_UDP + ntohs(udp->len)); + sum = checksum((unsigned char *)pkt, datalen, sum); + sum = checksum((unsigned char *)udp, sizeof(*udp), sum); + udp->check = wrapsum(sum); + + // Data + memcpy(workspace + sizeof(struct iphdr) + sizeof(struct udphdr), + pkt, datalen); + + // Send out the packet physically + struct sockaddr_in to; + to.sin_family = AF_INET; + to.sin_addr.s_addr = inet_addr(to_ip); + to.sin_port = htons(dport); + + sendto(sock, workspace, ntohs(ip->tot_len), 0, (struct sockaddr *)&to, sizeof(to)); + } + } +} diff --git a/examples/historical/mbd/survey.pl b/examples/historical/mbd/survey.pl new file mode 100644 index 0000000..be33038 --- /dev/null +++ b/examples/historical/mbd/survey.pl @@ -0,0 +1,10 @@ +package Config; + +our $survey_ip = "176.110.125.15"; +our $survey_port_low = 60100; +our $survey_port_high = 60200; +our $survey_freq = 60.0; +our $survey_time = 10.0; + +1; + diff --git a/examples/historical/munin/backfill_total_network_traffic.pl b/examples/historical/munin/backfill_total_network_traffic.pl new file mode 100755 index 0000000..000b0d5 --- /dev/null +++ b/examples/historical/munin/backfill_total_network_traffic.pl @@ -0,0 +1,55 @@ +#! /usr/bin/perl -I/root/tgmanage/include +use strict; +use warnings; +use lib 'include'; +use nms; +use Data::Dumper::Simple; + +use Date::Parse; + +my $dbh = nms::db_connect(); +$dbh->{AutoCommit} = 0; + +# This has a slightly modded version of get_current_datarate inlined. It's probably outdated by the time you read this. +my $total_traffic = $dbh->prepare("select sum(bytes_in) * 8 / 1048576.0 / 1024.0 as traffic_out, sum(bytes_out) * 8 / 1048576.0 / 1024.0 as traffic_in from (SELECT switch,port, + (bytes_out[1] - bytes_out[2]) / EXTRACT(EPOCH FROM (time[1] - time[2])) AS bytes_out, + (bytes_in[1] - bytes_in[2]) / EXTRACT(EPOCH FROM (time[1] - time[2])) AS bytes_in, + time[1] AS last_poll_time + FROM ( + SELECT switch,port, + ARRAY_AGG(time) AS time, + ARRAY_AGG(bytes_in) AS bytes_in, + ARRAY_AGG(bytes_out) AS bytes_out + FROM ( + SELECT *,rank() OVER (PARTITION BY switch,port ORDER BY time DESC) AS poll_num + FROM polls WHERE time BETWEEN (to_timestamp(?) - interval '5 minutes') AND to_timestamp(?) + AND official_port + ) t1 + WHERE poll_num <= 2 + GROUP BY switch,port + ) t2 + WHERE + time[2] IS NOT NULL + AND bytes_in[1] >= 0 AND bytes_out[1] >= 0 + AND bytes_in[2] >= 0 AND bytes_out[2] >= 0 + AND bytes_out[1] >= bytes_out[2] + AND bytes_in[1] >= bytes_in[2]) as datarate natural join switches where switchtype like 'dlink3100%' and port < 45") + or die "Can't prepare query: $!"; + +my $inout = shift @ARGV; +while (<>) { + if (m,<!-- [^/]* CEST / (\d+) --> <row><v>[^<]*</v></row>, && $1 > 1397458800) { + my $time = $1; + if ($time > 1397458800) { + $total_traffic->execute($time, $time); + my $ref = $total_traffic->fetchrow_hashref; + my $value = $ref->{'traffic_' . $inout}; + $value = (!defined $value || $value == 0 || $value > 400) ? "NaN" : sprintf "%e", $value; + s,<v>[^<]*</v>,<v>$value</v>,; + } + } + print; +} +$total_traffic->finish; +$dbh->disconnect(); +exit 0 diff --git a/examples/historical/munin/clients_connected.pl b/examples/historical/munin/clients_connected.pl new file mode 100755 index 0000000..5301c63 --- /dev/null +++ b/examples/historical/munin/clients_connected.pl @@ -0,0 +1,26 @@ +#! /usr/bin/perl -I/root/tgmanage/include +use strict; +use warnings; +use lib 'include'; +use nms; +use Data::Dumper::Simple; + +my $dbh = nms::db_connect(); +$dbh->{AutoCommit} = 0; + +my $active_clients = $dbh->prepare("select family(address), count(distinct(mac)) from seen_mac where family(address) in (6,4) and seen >= now() - INTERVAL '1 hour' group by family(address);") + or die "Can't prepare query: $!"; + +$active_clients->execute; +print <<EOF; +graph_title Clients seen the last hour +graph_vlabel count +graph_scale no +EOF +while (my $ref = $active_clients->fetchrow_hashref) { + print "clients_".$ref->{'family'}.".label v".$ref->{'family'}." clients\n"; + print "clients_".$ref->{'family'}.".value ".$ref->{'count'}."\n"; +} +$active_clients->finish; +$dbh->disconnect(); +exit 0 diff --git a/examples/historical/munin/total_network_traffic.pl b/examples/historical/munin/total_network_traffic.pl new file mode 100755 index 0000000..2c0799b --- /dev/null +++ b/examples/historical/munin/total_network_traffic.pl @@ -0,0 +1,31 @@ +#! /usr/bin/perl -I/root/tgmanage/include +use strict; +use warnings; +use lib 'include'; +use nms; +use Data::Dumper::Simple; + +# By the looks of this code, the in/out values are from the perspective of the +# switch. However, something gets flipped somewhere which makes it from the +# perspective of the client. I have no idea why. Have fun! + +my $dbh = nms::db_connect(); +$dbh->{AutoCommit} = 0; + +my $total_traffic = $dbh->prepare("select sum(bytes_in) * 8 / 1048576.0 / 1024.0 as traffic_in, sum(bytes_out) * 8 / 1048576.0 / 1024.0 as traffic_out from get_current_datarate() natural join switches where switchtype like 'dlink3100%' and port < 45") + or die "Can't prepare query: $!"; + +$total_traffic->execute; +print <<EOF; +graph_title Total network traffic +graph_vlabel Gb/s +graph_scale no +EOF +my $ref = $total_traffic->fetchrow_hashref; +print "total_network_traffic_in.label Total incoming traffic\n"; +print "total_network_traffic_in.value ". $ref->{'traffic_in'}."\n"; +print "total_network_traffic_out.label Total outgoing traffic\n"; +print "total_network_traffic_out.value ". $ref->{'traffic_out'}."\n"; +$total_traffic->finish; +$dbh->disconnect(); +exit 0; diff --git a/examples/historical/tg15/netlist.txt b/examples/historical/tg15/netlist.txt new file mode 100644 index 0000000..67f2c11 --- /dev/null +++ b/examples/historical/tg15/netlist.txt @@ -0,0 +1,189 @@ +## start manuelle nett +151.216.165.0/26 2a02:ed02:165a::/64 e3-2 +151.216.170.0/24 2a02:ed02:170::/64 crew +151.216.171.64/26 2a02:ed02:171b::/64 sw1-crew +151.216.171.128/26 2a02:ed02:171c::/64 sw2-crew +151.216.171.192/26 2a02:ed02:171d::/64 sw3-crew +151.216.178.0/26 2a02:ed02:178a::/64 ap-distro0 +151.216.178.128/26 2a02:ed02:178c::/64 ap-distro2 +151.216.178.192/26 2a02:ed02:178d::/64 ap-distro3 +151.216.178.64/26 2a02:ed02:178b::/64 ap-distro1 +151.216.179.0/26 2a02:ed02:179a::/64 ap-distro4 +151.216.179.128/26 2a02:ed02:179c::/64 ap-distro6 +151.216.179.192/26 2a02:ed02:179d::/64 ap-distro7 +151.216.179.64/26 2a02:ed02:179b::/64 ap-distro5 +151.216.192.0/19 2a02:ed02:192::/64 tg15-wlan +151.216.224.0/24 2a02:ed02:224::/64 logistikk +151.216.226.0/24 2a02:ed02:226::/64 presse +151.216.227.0/24 2a02:ed02:227::/64 fugleberget1 +151.216.229.0/24 2a02:ed02:229::/64 game +151.216.230.0/24 2a02:ed02:230::/64 infodesk +151.216.232.0/24 2a02:ed02:232::/64 resepsjon +151.216.233.0/24 2a02:ed02:233::/64 sponsor +151.216.234.0/24 2a02:ed02:234::/64 lounge +151.216.235.0/24 2a02:ed02:235::/64 stage +151.216.236.0/24 2a02:ed02:236::/64 medic +151.216.237.0/24 2a02:ed02:237::/64 gamecrew +151.216.240.0/24 2a02:ed02:240::/64 studio +151.216.241.0/24 2a02:ed02:241::/64 motell +151.216.243.0/24 2a02:ed02:243::/64 nextron +151.216.244.0/24 2a02:ed02:244::/64 event-north +151.216.249.0/26 2a02:ed02:249a::/64 southcam +151.216.254.0/24 2a02:ed02:254::/64 noc +## slutt manuelle nett +# make netlist.txt from switches.txt; +# cat switches.txt | perl -lne '($n,$v4,$v6)=split;print "$v4 $v6 $n";' +## start creativia +151.216.166.0/26 2a02:ed02:166a::/64 creativia1 +151.216.166.64/26 2a02:ed02:166b::/64 creativia2 +151.216.166.128/26 2a02:ed02:166c::/64 creativia3 +151.216.166.192/26 2a02:ed02:166d::/64 creativia4 +151.216.167.0/26 2a02:ed02:167a::/64 creativia5 +151.216.167.64/26 2a02:ed02:167b::/64 creativia6 +151.216.167.128/26 2a02:ed02:167c::/64 creativia7 +151.216.167.192/26 2a02:ed02:167d::/64 creativia8 +## slutt creativia +## start switches.txt +151.216.129.0/26 2a02:ed02:129a::/64 e1-3 +151.216.129.64/26 2a02:ed02:129b::/64 e3-3 +151.216.129.128/26 2a02:ed02:129c::/64 e3-4 +151.216.129.192/26 2a02:ed02:129d::/64 e5-2 +151.216.130.0/26 2a02:ed02:130a::/64 e5-3 +151.216.130.64/26 2a02:ed02:130b::/64 e5-4 +151.216.130.128/26 2a02:ed02:130c::/64 e7-2 +151.216.130.192/26 2a02:ed02:130d::/64 e7-3 +151.216.131.0/26 2a02:ed02:131a::/64 e7-4 +151.216.131.64/26 2a02:ed02:131b::/64 e9-2 +151.216.131.128/26 2a02:ed02:131c::/64 e9-3 +151.216.131.192/26 2a02:ed02:131d::/64 e9-4 +151.216.132.0/26 2a02:ed02:132a::/64 e11-1 +151.216.132.64/26 2a02:ed02:132b::/64 e11-2 +151.216.132.128/26 2a02:ed02:132c::/64 e11-3 +151.216.132.192/26 2a02:ed02:132d::/64 e11-4 +151.216.133.0/26 2a02:ed02:133a::/64 e13-1 +151.216.133.64/26 2a02:ed02:133b::/64 e13-2 +151.216.133.128/26 2a02:ed02:133c::/64 e13-3 +151.216.133.192/26 2a02:ed02:133d::/64 e13-4 +151.216.134.0/26 2a02:ed02:134a::/64 e15-1 +151.216.134.64/26 2a02:ed02:134b::/64 e15-2 +151.216.134.128/26 2a02:ed02:134c::/64 e15-3 +151.216.134.192/26 2a02:ed02:134d::/64 e15-4 +151.216.135.0/26 2a02:ed02:135a::/64 e17-1 +151.216.135.64/26 2a02:ed02:135b::/64 e17-2 +151.216.135.128/26 2a02:ed02:135c::/64 e17-3 +151.216.135.192/26 2a02:ed02:135d::/64 e17-4 +151.216.136.0/26 2a02:ed02:136a::/64 e19-1 +151.216.136.64/26 2a02:ed02:136b::/64 e19-2 +151.216.136.128/26 2a02:ed02:136c::/64 e19-3 +151.216.136.192/26 2a02:ed02:136d::/64 e19-4 +151.216.137.0/26 2a02:ed02:137a::/64 e21-1 +151.216.137.64/26 2a02:ed02:137b::/64 e21-2 +151.216.137.128/26 2a02:ed02:137c::/64 e21-3 +151.216.137.192/26 2a02:ed02:137d::/64 e21-4 +151.216.138.0/26 2a02:ed02:138a::/64 e23-1 +151.216.138.64/26 2a02:ed02:138b::/64 e23-2 +151.216.138.128/26 2a02:ed02:138c::/64 e23-3 +151.216.138.192/26 2a02:ed02:138d::/64 e23-4 +151.216.139.0/26 2a02:ed02:139a::/64 e25-1 +151.216.139.64/26 2a02:ed02:139b::/64 e25-2 +151.216.139.128/26 2a02:ed02:139c::/64 e25-3 +151.216.139.192/26 2a02:ed02:139d::/64 e25-4 +151.216.140.0/26 2a02:ed02:140a::/64 e27-1 +151.216.140.64/26 2a02:ed02:140b::/64 e27-2 +151.216.140.128/26 2a02:ed02:140c::/64 e27-3 +151.216.140.192/26 2a02:ed02:140d::/64 e27-4 +151.216.141.0/26 2a02:ed02:141a::/64 e27-1 +151.216.141.64/26 2a02:ed02:141b::/64 e27-2 +151.216.141.128/26 2a02:ed02:141c::/64 e29-1 +151.216.141.192/26 2a02:ed02:141d::/64 e29-2 +151.216.142.0/26 2a02:ed02:142a::/64 e31-1 +151.216.142.64/26 2a02:ed02:142b::/64 e31-2 +151.216.142.128/26 2a02:ed02:142c::/64 e33-1 +151.216.142.192/26 2a02:ed02:142d::/64 e33-2 +151.216.143.0/26 2a02:ed02:143a::/64 e35-1 +151.216.143.64/26 2a02:ed02:143b::/64 e35-2 +151.216.143.128/26 2a02:ed02:143c::/64 e37-1 +151.216.143.192/26 2a02:ed02:143d::/64 e37-2 +151.216.144.0/26 2a02:ed02:144a::/64 e39-1 +151.216.144.64/26 2a02:ed02:144b::/64 e39-2 +151.216.144.128/26 2a02:ed02:144c::/64 e41-1 +151.216.144.192/26 2a02:ed02:144d::/64 e41-2 +151.216.145.0/26 2a02:ed02:145a::/64 e43-1 +151.216.145.64/26 2a02:ed02:145b::/64 e43-2 +151.216.145.128/26 2a02:ed02:145c::/64 e45-1 +151.216.145.192/26 2a02:ed02:145d::/64 e45-2 +151.216.146.0/26 2a02:ed02:146a::/64 e45-3 +151.216.146.64/26 2a02:ed02:146b::/64 e45-4 +151.216.146.128/26 2a02:ed02:146c::/64 e47-1 +151.216.146.192/26 2a02:ed02:146d::/64 e47-2 +151.216.147.0/26 2a02:ed02:147a::/64 e47-3 +151.216.147.64/26 2a02:ed02:147b::/64 e47-4 +151.216.147.128/26 2a02:ed02:147c::/64 e49-1 +151.216.147.192/26 2a02:ed02:147d::/64 e49-2 +151.216.148.0/26 2a02:ed02:148a::/64 e49-3 +151.216.148.64/26 2a02:ed02:148b::/64 e49-4 +151.216.148.128/26 2a02:ed02:148c::/64 e51-1 +151.216.148.192/26 2a02:ed02:148d::/64 e51-2 +151.216.149.0/26 2a02:ed02:149a::/64 e51-3 +151.216.149.64/26 2a02:ed02:149b::/64 e51-4 +151.216.149.128/26 2a02:ed02:149c::/64 e53-1 +151.216.149.192/26 2a02:ed02:149d::/64 e53-2 +151.216.150.0/26 2a02:ed02:150a::/64 e53-3 +151.216.150.64/26 2a02:ed02:150b::/64 e53-4 +151.216.150.128/26 2a02:ed02:150c::/64 e55-1 +151.216.150.192/26 2a02:ed02:150d::/64 e55-2 +151.216.151.0/26 2a02:ed02:151a::/64 e55-3 +151.216.151.64/26 2a02:ed02:151b::/64 e55-4 +151.216.151.128/26 2a02:ed02:151c::/64 e57-1 +151.216.151.192/26 2a02:ed02:151d::/64 e57-2 +151.216.152.0/26 2a02:ed02:152a::/64 e57-3 +151.216.152.64/26 2a02:ed02:152b::/64 e57-4 +151.216.152.128/26 2a02:ed02:152c::/64 e59-1 +151.216.152.192/26 2a02:ed02:152d::/64 e59-2 +151.216.153.0/26 2a02:ed02:153a::/64 e59-3 +151.216.153.64/26 2a02:ed02:153b::/64 e59-4 +151.216.153.128/26 2a02:ed02:153c::/64 e61-1 +151.216.153.192/26 2a02:ed02:153d::/64 e61-2 +151.216.154.0/26 2a02:ed02:154a::/64 e61-3 +151.216.154.64/26 2a02:ed02:154b::/64 e61-4 +151.216.154.128/26 2a02:ed02:154c::/64 e63-1 +151.216.154.192/26 2a02:ed02:154d::/64 e63-2 +151.216.155.0/26 2a02:ed02:155a::/64 e63-3 +151.216.155.64/26 2a02:ed02:155b::/64 e63-4 +151.216.155.128/26 2a02:ed02:155c::/64 e65-1 +151.216.155.192/26 2a02:ed02:155d::/64 e65-2 +151.216.156.0/26 2a02:ed02:156a::/64 e65-3 +151.216.156.64/26 2a02:ed02:156b::/64 e65-4 +151.216.156.128/26 2a02:ed02:156c::/64 e67-1 +151.216.156.192/26 2a02:ed02:156d::/64 e67-2 +151.216.157.0/26 2a02:ed02:157a::/64 e67-3 +151.216.157.64/26 2a02:ed02:157b::/64 e67-4 +151.216.157.128/26 2a02:ed02:157c::/64 e69-1 +151.216.157.192/26 2a02:ed02:157d::/64 e69-2 +151.216.158.0/26 2a02:ed02:158a::/64 e69-3 +151.216.158.64/26 2a02:ed02:158b::/64 e69-4 +151.216.158.128/26 2a02:ed02:158c::/64 e71-1 +151.216.158.192/26 2a02:ed02:158d::/64 e71-2 +151.216.159.0/26 2a02:ed02:159a::/64 e71-3 +151.216.159.64/26 2a02:ed02:159b::/64 e71-4 +151.216.159.128/26 2a02:ed02:159c::/64 e73-1 +151.216.159.192/26 2a02:ed02:159d::/64 e73-2 +151.216.160.0/26 2a02:ed02:160a::/64 e73-3 +151.216.160.64/26 2a02:ed02:160b::/64 e73-4 +151.216.160.128/26 2a02:ed02:160c::/64 e75-1 +151.216.160.192/26 2a02:ed02:160d::/64 e75-2 +151.216.161.0/26 2a02:ed02:161a::/64 e75-3 +151.216.161.64/26 2a02:ed02:161b::/64 e75-4 +151.216.161.128/26 2a02:ed02:161c::/64 e77-1 +151.216.161.192/26 2a02:ed02:161d::/64 e77-2 +151.216.162.0/26 2a02:ed02:162a::/64 e77-3 +151.216.162.64/26 2a02:ed02:162b::/64 e77-4 +151.216.162.128/26 2a02:ed02:162c::/64 e79-1 +151.216.162.192/26 2a02:ed02:162d::/64 e79-2 +151.216.163.0/26 2a02:ed02:163a::/64 e79-3 +151.216.163.64/26 2a02:ed02:163b::/64 e79-4 +151.216.163.128/26 2a02:ed02:163c::/64 e81-1 +151.216.163.192/26 2a02:ed02:163d::/64 e81-2 +151.216.164.0/26 2a02:ed02:164a::/64 e83-1 +151.216.164.64/26 2a02:ed02:164b::/64 e83-2 +## slutt switches.txt diff --git a/examples/historical/tg15/patchlist.txt b/examples/historical/tg15/patchlist.txt new file mode 100644 index 0000000..3f73092 --- /dev/null +++ b/examples/historical/tg15/patchlist.txt @@ -0,0 +1,148 @@ +e1-3 distro0 ge-0/0/0 ge-1/0/0 ge-2/0/0 ge-3/0/0 +e3-3 distro0 ge-0/0/1 ge-1/0/1 ge-2/0/1 ge-3/0/1 +e3-4 distro0 ge-0/0/2 ge-1/0/2 ge-2/0/2 ge-3/0/2 +e5-2 distro1 ge-0/0/0 ge-1/0/0 ge-2/0/0 ge-3/0/0 +e5-3 distro0 ge-0/0/3 ge-1/0/3 ge-2/0/3 ge-3/0/3 +e5-4 distro0 ge-0/0/4 ge-1/0/4 ge-2/0/4 ge-3/0/4 +e7-2 distro1 ge-0/0/1 ge-1/0/1 ge-2/0/1 ge-3/0/1 +e7-3 distro0 ge-0/0/5 ge-1/0/5 ge-2/0/5 ge-3/0/5 +e7-4 distro0 ge-0/0/6 ge-1/0/6 ge-2/0/6 ge-3/0/6 +e9-2 distro1 ge-0/0/2 ge-1/0/2 ge-2/0/2 ge-3/0/2 +e9-3 distro0 ge-0/0/7 ge-1/0/7 ge-2/0/7 ge-3/0/7 +e9-4 distro0 ge-0/0/8 ge-1/0/8 ge-2/0/8 ge-3/0/8 +e11-1 distro1 ge-0/0/3 ge-1/0/3 ge-2/0/3 ge-3/0/3 +e11-2 distro1 ge-0/0/4 ge-1/0/4 ge-2/0/4 ge-3/0/4 +e11-3 distro0 ge-0/0/9 ge-1/0/9 ge-2/0/9 ge-3/0/9 +e11-4 distro0 ge-0/0/10 ge-1/0/10 ge-2/0/10 ge-3/0/10 +e13-1 distro1 ge-0/0/5 ge-1/0/5 ge-2/0/5 ge-3/0/5 +e13-2 distro1 ge-0/0/6 ge-1/0/6 ge-2/0/6 ge-3/0/6 +e13-3 distro0 ge-0/0/11 ge-1/0/11 ge-2/0/11 ge-3/0/11 +e13-4 distro0 ge-0/0/12 ge-1/0/12 ge-2/0/12 ge-3/0/12 +e15-1 distro1 ge-0/0/7 ge-1/0/7 ge-2/0/7 ge-3/0/7 +e15-2 distro1 ge-0/0/8 ge-1/0/8 ge-2/0/8 ge-3/0/8 +e15-3 distro0 ge-0/0/13 ge-1/0/13 ge-2/0/13 ge-3/0/13 +e15-4 distro0 ge-0/0/14 ge-1/0/14 ge-2/0/14 ge-3/0/14 +e17-1 distro1 ge-0/0/9 ge-1/0/9 ge-2/0/9 ge-3/0/9 +e17-2 distro1 ge-0/0/10 ge-1/0/10 ge-2/0/10 ge-3/0/10 +e17-3 distro2 ge-0/0/0 ge-1/0/0 ge-2/0/0 ge-3/0/0 +e17-4 distro2 ge-0/0/1 ge-1/0/1 ge-2/0/1 ge-3/0/1 +e19-1 distro1 ge-0/0/11 ge-1/0/11 ge-2/0/11 ge-3/0/11 +e19-2 distro1 ge-0/0/12 ge-1/0/12 ge-2/0/12 ge-3/0/12 +e19-3 distro2 ge-0/0/2 ge-1/0/2 ge-2/0/2 ge-3/0/2 +e19-4 distro2 ge-0/0/3 ge-1/0/3 ge-2/0/3 ge-3/0/3 +e21-1 distro1 ge-0/0/13 ge-1/0/13 ge-2/0/13 ge-3/0/13 +e21-2 distro1 ge-0/0/14 ge-1/0/14 ge-2/0/14 ge-3/0/14 +e21-3 distro2 ge-0/0/4 ge-1/0/4 ge-2/0/4 ge-3/0/4 +e21-4 distro2 ge-0/0/5 ge-1/0/5 ge-2/0/5 ge-3/0/5 +e23-1 distro1 ge-0/0/15 ge-1/0/15 ge-2/0/15 ge-3/0/15 +e23-2 distro1 ge-0/0/16 ge-1/0/16 ge-2/0/16 ge-3/0/16 +e23-3 distro2 ge-0/0/6 ge-1/0/6 ge-2/0/6 ge-3/0/6 +e23-4 distro2 ge-0/0/7 ge-1/0/7 ge-2/0/7 ge-3/0/7 +e25-1 distro1 ge-0/0/17 ge-1/0/17 ge-2/0/17 ge-3/0/17 +e25-2 distro1 ge-0/0/18 ge-1/0/18 ge-2/0/18 ge-3/0/18 +e25-3 distro2 ge-0/0/8 ge-1/0/8 ge-2/0/8 ge-3/0/8 +e25-4 distro2 ge-0/0/9 ge-1/0/9 ge-2/0/9 ge-3/0/9 +e27-1 distro1 ge-0/0/19 ge-1/0/19 ge-2/0/19 ge-3/0/19 +e27-2 distro1 ge-0/0/20 ge-1/0/20 ge-2/0/20 ge-3/0/20 +e27-3 distro2 ge-0/0/10 ge-1/0/10 ge-2/0/10 ge-3/0/10 +e27-4 distro2 ge-0/0/11 ge-1/0/11 ge-2/0/11 ge-3/0/11 +e29-1 distro3 ge-0/0/0 ge-1/0/0 ge-2/0/0 ge-3/0/0 +e29-2 distro3 ge-0/0/1 ge-1/0/1 ge-2/0/1 ge-3/0/1 +e31-1 distro3 ge-0/0/2 ge-1/0/2 ge-2/0/2 ge-3/0/2 +e31-2 distro3 ge-0/0/3 ge-1/0/3 ge-2/0/3 ge-3/0/3 +e33-1 distro3 ge-0/0/4 ge-1/0/4 ge-2/0/4 ge-3/0/4 +e33-2 distro3 ge-0/0/5 ge-1/0/5 ge-2/0/5 ge-3/0/5 +e35-1 distro3 ge-0/0/6 ge-1/0/6 ge-2/0/6 ge-3/0/6 +e35-2 distro3 ge-0/0/7 ge-1/0/7 ge-2/0/7 ge-3/0/7 +e37-1 distro3 ge-0/0/8 ge-1/0/8 ge-2/0/8 ge-3/0/8 +e37-2 distro3 ge-0/0/9 ge-1/0/9 ge-2/0/9 ge-3/0/9 +e39-1 distro3 ge-0/0/10 ge-1/0/10 ge-2/0/10 ge-3/0/10 +e39-2 distro3 ge-0/0/11 ge-1/0/11 ge-2/0/11 ge-3/0/11 +e41-1 distro3 ge-0/0/12 ge-1/0/12 ge-2/0/12 ge-3/0/12 +e41-2 distro3 ge-0/0/13 ge-1/0/13 ge-2/0/13 ge-3/0/13 +e43-1 distro3 ge-0/0/14 ge-1/0/14 ge-2/0/14 ge-3/0/14 +e43-2 distro3 ge-0/0/15 ge-1/0/15 ge-2/0/15 ge-3/0/15 +e45-1 distro4 ge-0/0/0 ge-1/0/0 ge-2/0/0 ge-3/0/0 +e45-2 distro4 ge-0/0/1 ge-1/0/1 ge-2/0/1 ge-3/0/1 +e45-3 distro5 ge-0/0/0 ge-1/0/0 ge-2/0/0 ge-3/0/0 +e45-4 distro5 ge-0/0/1 ge-1/0/1 ge-2/0/1 ge-3/0/1 +e47-1 distro4 ge-0/0/2 ge-1/0/2 ge-2/0/2 ge-3/0/2 +e47-2 distro4 ge-0/0/3 ge-1/0/3 ge-2/0/3 ge-3/0/3 +e47-3 distro5 ge-0/0/2 ge-1/0/2 ge-2/0/2 ge-3/0/2 +e47-4 distro5 ge-0/0/3 ge-1/0/3 ge-2/0/3 ge-3/0/3 +e49-1 distro4 ge-0/0/4 ge-1/0/4 ge-2/0/4 ge-3/0/4 +e49-2 distro4 ge-0/0/5 ge-1/0/5 ge-2/0/5 ge-3/0/5 +e49-3 distro5 ge-0/0/4 ge-1/0/4 ge-2/0/4 ge-3/0/4 +e49-4 distro5 ge-0/0/5 ge-1/0/5 ge-2/0/5 ge-3/0/5 +e51-1 distro4 ge-0/0/6 ge-1/0/6 ge-2/0/6 ge-3/0/6 +e51-2 distro4 ge-0/0/7 ge-1/0/7 ge-2/0/7 ge-3/0/7 +e51-3 distro5 ge-0/0/6 ge-1/0/6 ge-2/0/6 ge-3/0/6 +e51-4 distro5 ge-0/0/7 ge-1/0/7 ge-2/0/7 ge-3/0/7 +e53-1 distro4 ge-0/0/8 ge-1/0/8 ge-2/0/8 ge-3/0/8 +e53-2 distro4 ge-0/0/9 ge-1/0/9 ge-2/0/9 ge-3/0/9 +e53-3 distro5 ge-0/0/8 ge-1/0/8 ge-2/0/8 ge-3/0/8 +e53-4 distro5 ge-0/0/9 ge-1/0/9 ge-2/0/9 ge-3/0/9 +e55-1 distro4 ge-0/0/10 ge-1/0/10 ge-2/0/10 ge-3/0/10 +e55-2 distro4 ge-0/0/11 ge-1/0/11 ge-2/0/11 ge-3/0/11 +e55-3 distro5 ge-0/0/10 ge-1/0/10 ge-2/0/10 ge-3/0/10 +e55-4 distro5 ge-0/0/11 ge-1/0/11 ge-2/0/11 ge-3/0/11 +e57-1 distro4 ge-0/0/12 ge-1/0/12 ge-2/0/12 ge-3/0/12 +e57-2 distro4 ge-0/0/13 ge-1/0/13 ge-2/0/13 ge-3/0/13 +e57-3 distro5 ge-0/0/12 ge-1/0/12 ge-2/0/12 ge-3/0/12 +e57-4 distro5 ge-0/0/13 ge-1/0/13 ge-2/0/13 ge-3/0/13 +e59-1 distro4 ge-0/0/14 ge-1/0/14 ge-2/0/14 ge-3/0/14 +e59-2 distro4 ge-0/0/15 ge-1/0/15 ge-2/0/15 ge-3/0/15 +e59-3 distro5 ge-0/0/14 ge-1/0/14 ge-2/0/14 ge-3/0/14 +e59-4 distro5 ge-0/0/15 ge-1/0/15 ge-2/0/15 ge-3/0/15 +e61-1 distro4 ge-0/0/16 ge-1/0/16 ge-2/0/16 ge-3/0/16 +e61-2 distro4 ge-0/0/17 ge-1/0/17 ge-2/0/17 ge-3/0/17 +e61-3 distro5 ge-0/0/16 ge-1/0/16 ge-2/0/16 ge-3/0/16 +e61-4 distro5 ge-0/0/17 ge-1/0/17 ge-2/0/17 ge-3/0/17 +e63-1 distro7 ge-0/0/0 ge-1/0/0 ge-2/0/0 ge-3/0/0 +e63-2 distro7 ge-0/0/1 ge-1/0/1 ge-2/0/1 ge-3/0/1 +e63-3 distro6 ge-0/0/0 ge-1/0/0 ge-2/0/0 ge-3/0/0 +e63-4 distro6 ge-0/0/1 ge-1/0/1 ge-2/0/1 ge-3/0/1 +e65-1 distro7 ge-0/0/2 ge-1/0/2 ge-2/0/2 ge-3/0/2 +e65-2 distro7 ge-0/0/3 ge-1/0/3 ge-2/0/3 ge-3/0/3 +e65-3 distro6 ge-0/0/2 ge-1/0/2 ge-2/0/2 ge-3/0/2 +e65-4 distro6 ge-0/0/3 ge-1/0/3 ge-2/0/3 ge-3/0/3 +e67-1 distro7 ge-0/0/4 ge-1/0/4 ge-2/0/4 ge-3/0/4 +e67-2 distro7 ge-0/0/5 ge-1/0/5 ge-2/0/5 ge-3/0/5 +e67-3 distro6 ge-0/0/4 ge-1/0/4 ge-2/0/4 ge-3/0/4 +e67-4 distro6 ge-0/0/5 ge-1/0/5 ge-2/0/5 ge-3/0/5 +e69-1 distro7 ge-0/0/6 ge-1/0/6 ge-2/0/6 ge-3/0/6 +e69-2 distro7 ge-0/0/7 ge-1/0/7 ge-2/0/7 ge-3/0/7 +e69-3 distro6 ge-0/0/6 ge-1/0/6 ge-2/0/6 ge-3/0/6 +e69-4 distro6 ge-0/0/7 ge-1/0/7 ge-2/0/7 ge-3/0/7 +e71-1 distro7 ge-0/0/8 ge-1/0/8 ge-2/0/8 ge-3/0/8 +e71-2 distro7 ge-0/0/9 ge-1/0/9 ge-2/0/9 ge-3/0/9 +e71-3 distro6 ge-0/0/8 ge-1/0/8 ge-2/0/8 ge-3/0/8 +e71-4 distro6 ge-0/0/9 ge-1/0/9 ge-2/0/9 ge-3/0/9 +e73-1 distro7 ge-0/0/10 ge-1/0/10 ge-2/0/10 ge-3/0/10 +e73-2 distro7 ge-0/0/11 ge-1/0/11 ge-2/0/11 ge-3/0/11 +e73-3 distro6 ge-0/0/10 ge-1/0/10 ge-2/0/10 ge-3/0/10 +e73-4 distro6 ge-0/0/11 ge-1/0/11 ge-2/0/11 ge-3/0/11 +e75-1 distro7 ge-0/0/12 ge-1/0/12 ge-2/0/12 ge-3/0/12 +e75-2 distro7 ge-0/0/13 ge-1/0/13 ge-2/0/13 ge-3/0/13 +e75-3 distro6 ge-0/0/12 ge-1/0/12 ge-2/0/12 ge-3/0/12 +e75-4 distro6 ge-0/0/13 ge-1/0/13 ge-2/0/13 ge-3/0/13 +e77-1 distro7 ge-0/0/14 ge-1/0/14 ge-2/0/14 ge-3/0/14 +e77-2 distro7 ge-0/0/15 ge-1/0/15 ge-2/0/15 ge-3/0/15 +e77-3 distro6 ge-0/0/14 ge-1/0/14 ge-2/0/14 ge-3/0/14 +e77-4 distro6 ge-0/0/15 ge-1/0/15 ge-2/0/15 ge-3/0/15 +e79-1 distro7 ge-0/0/16 ge-1/0/16 ge-2/0/16 ge-3/0/16 +e79-2 distro7 ge-0/0/17 ge-1/0/17 ge-2/0/17 ge-3/0/17 +e79-3 distro6 ge-0/0/16 ge-1/0/16 ge-2/0/16 ge-3/0/16 +e79-4 distro6 ge-0/0/17 ge-1/0/17 ge-2/0/17 ge-3/0/17 +e81-1 distro7 ge-0/0/18 ge-1/0/18 ge-2/0/18 ge-3/0/18 +e81-2 distro7 ge-0/0/19 ge-1/0/19 ge-2/0/19 ge-3/0/19 +e83-1 distro7 ge-0/0/20 ge-1/0/20 ge-2/0/20 ge-3/0/20 +e83-2 distro7 ge-0/0/21 ge-1/0/21 ge-2/0/21 ge-3/0/21 +sw1-creativia distro6 ge-0/0/18 ge-1/0/18 +sw2-creativia distro6 ge-0/0/19 ge-1/0/19 +sw3-creativia distro6 ge-0/0/20 ge-1/0/20 +sw4-creativia distro6 ge-0/0/21 ge-1/0/21 +sw5-creativia distro6 ge-0/0/22 ge-1/0/22 +sw6-creativia distro6 ge-0/0/23 ge-1/0/23 +sw7-creativia distro6 ge-0/0/24 ge-1/0/24 +sw8-creativia distro6 ge-0/0/25 ge-1/0/25 diff --git a/examples/historical/tg15/patchlist_extras.txt b/examples/historical/tg15/patchlist_extras.txt new file mode 100644 index 0000000..f7b0fb2 --- /dev/null +++ b/examples/historical/tg15/patchlist_extras.txt @@ -0,0 +1,7 @@ +sw1-infodesk rs1.north ge-0/0/12 +sw2-gamestudio rs1.north ge-0/0/45 +sw3-streamerlounge rs1.north ge-0/0/16 +sw1-crew rs1.crew ge-0/0/39 ge-0/0/40 ge-0/0/41 +sw2-crew rs1.crew ge-0/0/42 ge-0/0/43 ge-0/0/44 +sw3-crew rs1.crew ge-0/0/45 ge-0/0/46 ge-0/0/47 +e3-2 distro1 ge-0/0/21 ge-1/0/21 ge-2/0/21 diff --git a/examples/historical/tg15/switches.txt b/examples/historical/tg15/switches.txt new file mode 100644 index 0000000..c9ea727 --- /dev/null +++ b/examples/historical/tg15/switches.txt @@ -0,0 +1,148 @@ +e1-3 151.216.129.0/26 2a02:ed02:129a::/64 151.216.180.2/26 2a02:ed02:180a::2/64 1013 distro0 +e3-3 151.216.129.64/26 2a02:ed02:129b::/64 151.216.180.3/26 2a02:ed02:180a::3/64 1033 distro0 +e3-4 151.216.129.128/26 2a02:ed02:129c::/64 151.216.180.4/26 2a02:ed02:180a::4/64 1034 distro0 +e5-2 151.216.129.192/26 2a02:ed02:129d::/64 151.216.180.66/26 2a02:ed02:180b::66/64 1052 distro1 +e5-3 151.216.130.0/26 2a02:ed02:130a::/64 151.216.180.5/26 2a02:ed02:180a::5/64 1053 distro0 +e5-4 151.216.130.64/26 2a02:ed02:130b::/64 151.216.180.6/26 2a02:ed02:180a::6/64 1054 distro0 +e7-2 151.216.130.128/26 2a02:ed02:130c::/64 151.216.180.67/26 2a02:ed02:180b::67/64 1072 distro1 +e7-3 151.216.130.192/26 2a02:ed02:130d::/64 151.216.180.7/26 2a02:ed02:180a::7/64 1073 distro0 +e7-4 151.216.131.0/26 2a02:ed02:131a::/64 151.216.180.8/26 2a02:ed02:180a::8/64 1074 distro0 +e9-2 151.216.131.64/26 2a02:ed02:131b::/64 151.216.180.68/26 2a02:ed02:180b::68/64 1092 distro1 +e9-3 151.216.131.128/26 2a02:ed02:131c::/64 151.216.180.9/26 2a02:ed02:180a::9/64 1093 distro0 +e9-4 151.216.131.192/26 2a02:ed02:131d::/64 151.216.180.10/26 2a02:ed02:180a::10/64 1094 distro0 +e11-1 151.216.132.0/26 2a02:ed02:132a::/64 151.216.180.69/26 2a02:ed02:180b::69/64 1111 distro1 +e11-2 151.216.132.64/26 2a02:ed02:132b::/64 151.216.180.70/26 2a02:ed02:180b::70/64 1112 distro1 +e11-3 151.216.132.128/26 2a02:ed02:132c::/64 151.216.180.11/26 2a02:ed02:180a::11/64 1113 distro0 +e11-4 151.216.132.192/26 2a02:ed02:132d::/64 151.216.180.12/26 2a02:ed02:180a::12/64 1114 distro0 +e13-1 151.216.133.0/26 2a02:ed02:133a::/64 151.216.180.71/26 2a02:ed02:180b::71/64 1131 distro1 +e13-2 151.216.133.64/26 2a02:ed02:133b::/64 151.216.180.72/26 2a02:ed02:180b::72/64 1132 distro1 +e13-3 151.216.133.128/26 2a02:ed02:133c::/64 151.216.180.13/26 2a02:ed02:180a::13/64 1133 distro0 +e13-4 151.216.133.192/26 2a02:ed02:133d::/64 151.216.180.14/26 2a02:ed02:180a::14/64 1134 distro0 +e15-1 151.216.134.0/26 2a02:ed02:134a::/64 151.216.180.73/26 2a02:ed02:180b::73/64 1151 distro1 +e15-2 151.216.134.64/26 2a02:ed02:134b::/64 151.216.180.74/26 2a02:ed02:180b::74/64 1152 distro1 +e15-3 151.216.134.128/26 2a02:ed02:134c::/64 151.216.180.15/26 2a02:ed02:180a::15/64 1153 distro0 +e15-4 151.216.134.192/26 2a02:ed02:134d::/64 151.216.180.16/26 2a02:ed02:180a::16/64 1154 distro0 +e17-1 151.216.135.0/26 2a02:ed02:135a::/64 151.216.180.75/26 2a02:ed02:180b::75/64 1171 distro1 +e17-2 151.216.135.64/26 2a02:ed02:135b::/64 151.216.180.76/26 2a02:ed02:180b::76/64 1172 distro1 +e17-3 151.216.135.128/26 2a02:ed02:135c::/64 151.216.180.130/26 2a02:ed02:180c::130/64 1173 distro2 +e17-4 151.216.135.192/26 2a02:ed02:135d::/64 151.216.180.131/26 2a02:ed02:180c::131/64 1174 distro2 +e19-1 151.216.136.0/26 2a02:ed02:136a::/64 151.216.180.77/26 2a02:ed02:180b::77/64 1191 distro1 +e19-2 151.216.136.64/26 2a02:ed02:136b::/64 151.216.180.78/26 2a02:ed02:180b::78/64 1192 distro1 +e19-3 151.216.136.128/26 2a02:ed02:136c::/64 151.216.180.132/26 2a02:ed02:180c::132/64 1193 distro2 +e19-4 151.216.136.192/26 2a02:ed02:136d::/64 151.216.180.133/26 2a02:ed02:180c::133/64 1194 distro2 +e21-1 151.216.137.0/26 2a02:ed02:137a::/64 151.216.180.79/26 2a02:ed02:180b::79/64 1211 distro1 +e21-2 151.216.137.64/26 2a02:ed02:137b::/64 151.216.180.80/26 2a02:ed02:180b::80/64 1212 distro1 +e21-3 151.216.137.128/26 2a02:ed02:137c::/64 151.216.180.134/26 2a02:ed02:180c::134/64 1213 distro2 +e21-4 151.216.137.192/26 2a02:ed02:137d::/64 151.216.180.135/26 2a02:ed02:180c::135/64 1214 distro2 +e23-1 151.216.138.0/26 2a02:ed02:138a::/64 151.216.180.81/26 2a02:ed02:180b::81/64 1231 distro1 +e23-2 151.216.138.64/26 2a02:ed02:138b::/64 151.216.180.82/26 2a02:ed02:180b::82/64 1232 distro1 +e23-3 151.216.138.128/26 2a02:ed02:138c::/64 151.216.180.136/26 2a02:ed02:180c::136/64 1233 distro2 +e23-4 151.216.138.192/26 2a02:ed02:138d::/64 151.216.180.137/26 2a02:ed02:180c::137/64 1234 distro2 +e25-1 151.216.139.0/26 2a02:ed02:139a::/64 151.216.180.83/26 2a02:ed02:180b::83/64 1251 distro1 +e25-2 151.216.139.64/26 2a02:ed02:139b::/64 151.216.180.84/26 2a02:ed02:180b::84/64 1252 distro1 +e25-3 151.216.139.128/26 2a02:ed02:139c::/64 151.216.180.138/26 2a02:ed02:180c::138/64 1253 distro2 +e25-4 151.216.139.192/26 2a02:ed02:139d::/64 151.216.180.139/26 2a02:ed02:180c::139/64 1254 distro2 +e27-1 151.216.140.0/26 2a02:ed02:140a::/64 151.216.180.85/26 2a02:ed02:180b::85/64 1271 distro1 +e27-2 151.216.140.64/26 2a02:ed02:140b::/64 151.216.180.86/26 2a02:ed02:180b::86/64 1272 distro1 +e27-3 151.216.140.128/26 2a02:ed02:140c::/64 151.216.180.140/26 2a02:ed02:180c::140/64 1273 distro2 +e27-4 151.216.140.192/26 2a02:ed02:140d::/64 151.216.180.141/26 2a02:ed02:180c::141/64 1274 distro2 +e29-1 151.216.141.128/26 2a02:ed02:141c::/64 151.216.180.194/26 2a02:ed02:180d::194/64 1291 distro3 +e29-2 151.216.141.192/26 2a02:ed02:141d::/64 151.216.180.195/26 2a02:ed02:180d::195/64 1292 distro3 +e31-1 151.216.142.0/26 2a02:ed02:142a::/64 151.216.180.196/26 2a02:ed02:180d::196/64 1311 distro3 +e31-2 151.216.142.64/26 2a02:ed02:142b::/64 151.216.180.197/26 2a02:ed02:180d::197/64 1312 distro3 +e33-1 151.216.142.128/26 2a02:ed02:142c::/64 151.216.180.198/26 2a02:ed02:180d::198/64 1331 distro3 +e33-2 151.216.142.192/26 2a02:ed02:142d::/64 151.216.180.199/26 2a02:ed02:180d::199/64 1332 distro3 +e35-1 151.216.143.0/26 2a02:ed02:143a::/64 151.216.180.200/26 2a02:ed02:180d::200/64 1351 distro3 +e35-2 151.216.143.64/26 2a02:ed02:143b::/64 151.216.180.201/26 2a02:ed02:180d::201/64 1352 distro3 +e37-1 151.216.143.128/26 2a02:ed02:143c::/64 151.216.180.202/26 2a02:ed02:180d::202/64 1371 distro3 +e37-2 151.216.143.192/26 2a02:ed02:143d::/64 151.216.180.203/26 2a02:ed02:180d::203/64 1372 distro3 +e39-1 151.216.144.0/26 2a02:ed02:144a::/64 151.216.180.204/26 2a02:ed02:180d::204/64 1391 distro3 +e39-2 151.216.144.64/26 2a02:ed02:144b::/64 151.216.180.205/26 2a02:ed02:180d::205/64 1392 distro3 +e41-1 151.216.144.128/26 2a02:ed02:144c::/64 151.216.180.206/26 2a02:ed02:180d::206/64 1411 distro3 +e41-2 151.216.144.192/26 2a02:ed02:144d::/64 151.216.180.207/26 2a02:ed02:180d::207/64 1412 distro3 +e43-1 151.216.145.0/26 2a02:ed02:145a::/64 151.216.180.208/26 2a02:ed02:180d::208/64 1431 distro3 +e43-2 151.216.145.64/26 2a02:ed02:145b::/64 151.216.180.209/26 2a02:ed02:180d::209/64 1432 distro3 +e45-1 151.216.145.128/26 2a02:ed02:145c::/64 151.216.181.2/26 2a02:ed02:181a::2/64 1451 distro4 +e45-2 151.216.145.192/26 2a02:ed02:145d::/64 151.216.181.3/26 2a02:ed02:181a::3/64 1452 distro4 +e45-3 151.216.146.0/26 2a02:ed02:146a::/64 151.216.181.66/26 2a02:ed02:181b::66/64 1453 distro5 +e45-4 151.216.146.64/26 2a02:ed02:146b::/64 151.216.181.67/26 2a02:ed02:181b::67/64 1454 distro5 +e47-1 151.216.146.128/26 2a02:ed02:146c::/64 151.216.181.4/26 2a02:ed02:181a::4/64 1471 distro4 +e47-2 151.216.146.192/26 2a02:ed02:146d::/64 151.216.181.5/26 2a02:ed02:181a::5/64 1472 distro4 +e47-3 151.216.147.0/26 2a02:ed02:147a::/64 151.216.181.68/26 2a02:ed02:181b::68/64 1473 distro5 +e47-4 151.216.147.64/26 2a02:ed02:147b::/64 151.216.181.69/26 2a02:ed02:181b::69/64 1474 distro5 +e49-1 151.216.147.128/26 2a02:ed02:147c::/64 151.216.181.6/26 2a02:ed02:181a::6/64 1491 distro4 +e49-2 151.216.147.192/26 2a02:ed02:147d::/64 151.216.181.7/26 2a02:ed02:181a::7/64 1492 distro4 +e49-3 151.216.148.0/26 2a02:ed02:148a::/64 151.216.181.70/26 2a02:ed02:181b::70/64 1493 distro5 +e49-4 151.216.148.64/26 2a02:ed02:148b::/64 151.216.181.71/26 2a02:ed02:181b::71/64 1494 distro5 +e51-1 151.216.148.128/26 2a02:ed02:148c::/64 151.216.181.8/26 2a02:ed02:181a::8/64 1511 distro4 +e51-2 151.216.148.192/26 2a02:ed02:148d::/64 151.216.181.9/26 2a02:ed02:181a::9/64 1512 distro4 +e51-3 151.216.149.0/26 2a02:ed02:149a::/64 151.216.181.72/26 2a02:ed02:181b::72/64 1513 distro5 +e51-4 151.216.149.64/26 2a02:ed02:149b::/64 151.216.181.73/26 2a02:ed02:181b::73/64 1514 distro5 +e53-1 151.216.149.128/26 2a02:ed02:149c::/64 151.216.181.10/26 2a02:ed02:181a::10/64 1531 distro4 +e53-2 151.216.149.192/26 2a02:ed02:149d::/64 151.216.181.11/26 2a02:ed02:181a::11/64 1532 distro4 +e53-3 151.216.150.0/26 2a02:ed02:150a::/64 151.216.181.74/26 2a02:ed02:181b::74/64 1533 distro5 +e53-4 151.216.150.64/26 2a02:ed02:150b::/64 151.216.181.75/26 2a02:ed02:181b::75/64 1534 distro5 +e55-1 151.216.150.128/26 2a02:ed02:150c::/64 151.216.181.12/26 2a02:ed02:181a::12/64 1551 distro4 +e55-2 151.216.150.192/26 2a02:ed02:150d::/64 151.216.181.13/26 2a02:ed02:181a::13/64 1552 distro4 +e55-3 151.216.151.0/26 2a02:ed02:151a::/64 151.216.181.76/26 2a02:ed02:181b::76/64 1553 distro5 +e55-4 151.216.151.64/26 2a02:ed02:151b::/64 151.216.181.77/26 2a02:ed02:181b::77/64 1554 distro5 +e57-1 151.216.151.128/26 2a02:ed02:151c::/64 151.216.181.14/26 2a02:ed02:181a::14/64 1571 distro4 +e57-2 151.216.151.192/26 2a02:ed02:151d::/64 151.216.181.15/26 2a02:ed02:181a::15/64 1572 distro4 +e57-3 151.216.152.0/26 2a02:ed02:152a::/64 151.216.181.78/26 2a02:ed02:181b::78/64 1573 distro5 +e57-4 151.216.152.64/26 2a02:ed02:152b::/64 151.216.181.79/26 2a02:ed02:181b::79/64 1574 distro5 +e59-1 151.216.152.128/26 2a02:ed02:152c::/64 151.216.181.16/26 2a02:ed02:181a::16/64 1591 distro4 +e59-2 151.216.152.192/26 2a02:ed02:152d::/64 151.216.181.17/26 2a02:ed02:181a::17/64 1592 distro4 +e59-3 151.216.153.0/26 2a02:ed02:153a::/64 151.216.181.80/26 2a02:ed02:181b::80/64 1593 distro5 +e59-4 151.216.153.64/26 2a02:ed02:153b::/64 151.216.181.81/26 2a02:ed02:181b::81/64 1594 distro5 +e61-1 151.216.153.128/26 2a02:ed02:153c::/64 151.216.181.18/26 2a02:ed02:181a::18/64 1611 distro4 +e61-2 151.216.153.192/26 2a02:ed02:153d::/64 151.216.181.19/26 2a02:ed02:181a::19/64 1612 distro4 +e61-3 151.216.154.0/26 2a02:ed02:154a::/64 151.216.181.82/26 2a02:ed02:181b::82/64 1613 distro5 +e61-4 151.216.154.64/26 2a02:ed02:154b::/64 151.216.181.83/26 2a02:ed02:181b::83/64 1614 distro5 +e63-1 151.216.154.128/26 2a02:ed02:154c::/64 151.216.181.194/26 2a02:ed02:181d::194/64 1631 distro7 +e63-2 151.216.154.192/26 2a02:ed02:154d::/64 151.216.181.195/26 2a02:ed02:181d::195/64 1632 distro7 +e63-3 151.216.155.0/26 2a02:ed02:155a::/64 151.216.181.130/26 2a02:ed02:181c::130/64 1633 distro6 +e63-4 151.216.155.64/26 2a02:ed02:155b::/64 151.216.181.131/26 2a02:ed02:181c::131/64 1634 distro6 +e65-1 151.216.155.128/26 2a02:ed02:155c::/64 151.216.181.196/26 2a02:ed02:181d::196/64 1651 distro7 +e65-2 151.216.155.192/26 2a02:ed02:155d::/64 151.216.181.197/26 2a02:ed02:181d::197/64 1652 distro7 +e65-3 151.216.156.0/26 2a02:ed02:156a::/64 151.216.181.132/26 2a02:ed02:181c::132/64 1653 distro6 +e65-4 151.216.156.64/26 2a02:ed02:156b::/64 151.216.181.133/26 2a02:ed02:181c::133/64 1654 distro6 +e67-1 151.216.156.128/26 2a02:ed02:156c::/64 151.216.181.198/26 2a02:ed02:181d::198/64 1671 distro7 +e67-2 151.216.156.192/26 2a02:ed02:156d::/64 151.216.181.199/26 2a02:ed02:181d::199/64 1672 distro7 +e67-3 151.216.157.0/26 2a02:ed02:157a::/64 151.216.181.134/26 2a02:ed02:181c::134/64 1673 distro6 +e67-4 151.216.157.64/26 2a02:ed02:157b::/64 151.216.181.135/26 2a02:ed02:181c::135/64 1674 distro6 +e69-1 151.216.157.128/26 2a02:ed02:157c::/64 151.216.181.200/26 2a02:ed02:181d::200/64 1691 distro7 +e69-2 151.216.157.192/26 2a02:ed02:157d::/64 151.216.181.201/26 2a02:ed02:181d::201/64 1692 distro7 +e69-3 151.216.158.0/26 2a02:ed02:158a::/64 151.216.181.136/26 2a02:ed02:181c::136/64 1693 distro6 +e69-4 151.216.158.64/26 2a02:ed02:158b::/64 151.216.181.137/26 2a02:ed02:181c::137/64 1694 distro6 +e71-1 151.216.158.128/26 2a02:ed02:158c::/64 151.216.181.202/26 2a02:ed02:181d::202/64 1711 distro7 +e71-2 151.216.158.192/26 2a02:ed02:158d::/64 151.216.181.203/26 2a02:ed02:181d::203/64 1712 distro7 +e71-3 151.216.159.0/26 2a02:ed02:159a::/64 151.216.181.138/26 2a02:ed02:181c::138/64 1713 distro6 +e71-4 151.216.159.64/26 2a02:ed02:159b::/64 151.216.181.139/26 2a02:ed02:181c::139/64 1714 distro6 +e73-1 151.216.159.128/26 2a02:ed02:159c::/64 151.216.181.204/26 2a02:ed02:181d::204/64 1731 distro7 +e73-2 151.216.159.192/26 2a02:ed02:159d::/64 151.216.181.205/26 2a02:ed02:181d::205/64 1732 distro7 +e73-3 151.216.160.0/26 2a02:ed02:160a::/64 151.216.181.140/26 2a02:ed02:181c::140/64 1733 distro6 +e73-4 151.216.160.64/26 2a02:ed02:160b::/64 151.216.181.141/26 2a02:ed02:181c::141/64 1734 distro6 +e75-1 151.216.160.128/26 2a02:ed02:160c::/64 151.216.181.206/26 2a02:ed02:181d::206/64 1751 distro7 +e75-2 151.216.160.192/26 2a02:ed02:160d::/64 151.216.181.207/26 2a02:ed02:181d::207/64 1752 distro7 +e75-3 151.216.161.0/26 2a02:ed02:161a::/64 151.216.181.142/26 2a02:ed02:181c::142/64 1753 distro6 +e75-4 151.216.161.64/26 2a02:ed02:161b::/64 151.216.181.143/26 2a02:ed02:181c::143/64 1754 distro6 +e77-1 151.216.161.128/26 2a02:ed02:161c::/64 151.216.181.208/26 2a02:ed02:181d::208/64 1771 distro7 +e77-2 151.216.161.192/26 2a02:ed02:161d::/64 151.216.181.209/26 2a02:ed02:181d::209/64 1772 distro7 +e77-3 151.216.162.0/26 2a02:ed02:162a::/64 151.216.181.144/26 2a02:ed02:181c::144/64 1773 distro6 +e77-4 151.216.162.64/26 2a02:ed02:162b::/64 151.216.181.145/26 2a02:ed02:181c::145/64 1774 distro6 +e79-1 151.216.162.128/26 2a02:ed02:162c::/64 151.216.181.210/26 2a02:ed02:181d::210/64 1791 distro7 +e79-2 151.216.162.192/26 2a02:ed02:162d::/64 151.216.181.211/26 2a02:ed02:181d::211/64 1792 distro7 +e79-3 151.216.163.0/26 2a02:ed02:163a::/64 151.216.181.146/26 2a02:ed02:181c::146/64 1793 distro6 +e79-4 151.216.163.64/26 2a02:ed02:163b::/64 151.216.181.147/26 2a02:ed02:181c::147/64 1794 distro6 +e81-1 151.216.163.128/26 2a02:ed02:163c::/64 151.216.181.212/26 2a02:ed02:181d::212/64 1811 distro7 +e81-2 151.216.163.192/26 2a02:ed02:163d::/64 151.216.181.213/26 2a02:ed02:181d::213/64 1812 distro7 +e83-1 151.216.164.0/26 2a02:ed02:164a::/64 151.216.181.214/26 2a02:ed02:181d::214/64 1831 distro7 +e83-2 151.216.164.64/26 2a02:ed02:164b::/64 151.216.181.215/26 2a02:ed02:181d::215/64 1832 distro7 +sw1-creativia 151.216.166.0/26 2a02:ed02:166a::/64 151.216.181.148/26 2a02:ed02:181c::148/64 2001 distro6 +sw2-creativia 151.216.166.64/26 2a02:ed02:166b::/64 151.216.181.149/26 2a02:ed02:181c::149/64 2002 distro6 +sw3-creativia 151.216.166.128/26 2a02:ed02:166c::/64 151.216.181.150/26 2a02:ed02:181c::150/64 2003 distro6 +sw4-creativia 151.216.166.192/26 2a02:ed02:166d::/64 151.216.181.151/26 2a02:ed02:181c::151/64 2004 distro6 +sw5-creativia 151.216.167.0/26 2a02:ed02:167a::/64 151.216.181.152/26 2a02:ed02:181c::152/64 2005 distro6 +sw6-creativia 151.216.167.64/26 2a02:ed02:167b::/64 151.216.181.153/26 2a02:ed02:181c::153/64 2006 distro6 +sw7-creativia 151.216.167.128/26 2a02:ed02:167c::/64 151.216.181.154/26 2a02:ed02:181c::154/64 2007 distro6 +sw8-creativia 151.216.167.192/26 2a02:ed02:167d::/64 151.216.181.155/26 2a02:ed02:181c::155/64 2008 distro6 diff --git a/examples/historical/tg15/switches_extras.txt b/examples/historical/tg15/switches_extras.txt new file mode 100644 index 0000000..afb3415 --- /dev/null +++ b/examples/historical/tg15/switches_extras.txt @@ -0,0 +1,7 @@ +sw1-infodesk 151.216.130.0/24 2a02:ed02:230::/64 151.216.183.229/27 2a02:ed02:1837::229/64 230 rs1.north +sw2-gamestudio 151.216.229.0/24 2a02:ed02:229::/64 151.216.183.230/27 2a02:ed02:1837::230/64 229 rs1.north +sw3-streamerlounge 151.216.229.0/24 2a02:ed02:229::/64 151.216.183.231/27 2a02:ed02:1837::231/64 229 rs1.north +sw1-crew 151.216.170.64/26 2a02:ed02:170b::/64 151.216.183.66/27 2a02:ed02:1832::66/64 1701 rs1.crew +sw2-crew 151.216.170.128/26 2a02:ed02:170c::/64 151.216.183.67/27 2a02:ed02:1832::67/64 1702 rs1.crew +sw3-crew 151.216.170.192/26 2a02:ed02:170d::/64 151.216.183.68/27 2a02:ed02:1832::68/64 1703 rs1.crew +e3-2 151.216.165.0/26 2a02:ed02:165a::/64 151.216.180.87/26 2a02:ed02:180b::87/64 1032 distro1 diff --git a/examples/historical/tools/fetch-portlist.sh b/examples/historical/tools/fetch-portlist.sh new file mode 100755 index 0000000..978b590 --- /dev/null +++ b/examples/historical/tools/fetch-portlist.sh @@ -0,0 +1,42 @@ +print_range() { + FIRST=$1 + LAST=$2 + if [ "$1" = "$2" ]; then + echo $FIRST + else + echo $FIRST-$LAST + fi +} + +walk_ports() { + IP=$1 + COMMUNITY=$2 + + FIRST_PORT= + LAST_PORT= + + for PORT in $( snmpwalk -Os -m IF-MIB -v 2c -c $COMMUNITY $IP ifDescr 2>/dev/null | grep -E ' ge|et|xe' | cut -d. -f2 | cut -d" " -f1 ); do + if ! snmpget -m IF-MIB -v 2c -c $COMMUNITY $IP ifHCInOctets.$PORT 2>/dev/null | grep -q 'No Such Instance'; then + if [ "$LAST_PORT" ] && [ `expr $LAST_PORT + 1` = $PORT ]; then + LAST_PORT=$PORT + else + if [ "$LAST_PORT" ]; then + print_range $FIRST_PORT $LAST_PORT + fi + FIRST_PORT=$PORT + LAST_PORT=$PORT + fi + fi + done + + print_range $FIRST_PORT $LAST_PORT +} + +COMMUNITY=$1 +IP=$2 +SYSNAME=$3 +PORTS=$( walk_ports $IP $COMMUNITY | tr "\n" "," | sed 's/,$//' ) + +echo "insert into switchtypes values ('$SYSNAME','$PORTS',true);" +echo "insert into switches values (default,'$IP','$SYSNAME','$SYSNAME',null,default, default, '1 minute', '$COMMUNITY');" + diff --git a/examples/historical/tools/ping-graph.pl b/examples/historical/tools/ping-graph.pl new file mode 100755 index 0000000..2cd6996 --- /dev/null +++ b/examples/historical/tools/ping-graph.pl @@ -0,0 +1,62 @@ +#! /usr/bin/perl + +# Makes latency-against-time graphs, one per switch. + +use warnings; +use strict; +use DBI; +use lib '../include'; +use nms; + +BEGIN { + require "../include/config.pm"; + eval { + require "../include/config.local.pm"; + }; +} + +my $dbh = db_connect(); +my $switches = $dbh->selectall_hashref('SELECT sysname,switch FROM switches ORDER BY sysname', 'sysname'); +if (1) { + my %switchfds = (); + while (my ($sysname, $switch) = each %$switches) { + print "$sysname -> $switch->{switch}\n"; + open my $fh, ">", "$sysname.txt" + or die "$sysname.txt: $!"; + $switchfds{$switch->{'switch'}} = $fh; + } + + my $q = $dbh->prepare('SELECT switch,EXTRACT(EPOCH FROM updated),latency_ms FROM ping'); + $q->execute; + + my $i = 0; + while (my $ref = $q->fetchrow_arrayref) { + next if (!defined($ref->[2])); + my $fh = $switchfds{$ref->[0]}; + next if (!defined($fh)); + print $fh $ref->[1], " ", $ref->[2], "\n"; + if (++$i % 1000000 == 0) { + printf "%dM records...\n", int($i / 1000000); + } + } + + while (my ($sysname, $switch) = each %$switches) { + close $switchfds{$switch->{'switch'}}; + } +} + +while (my ($sysname, $switch) = each %$switches) { + print "$sysname -> $switch->{switch}\n"; + open my $gnuplot, "|-", "gnuplot" + or die "gnuplot: $!"; + print $gnuplot <<"EOF"; +set timefmt "%s" +set xdata time +set format x "%d/%m %H:%M" +set term png size 1280,720 +set output '$sysname.png' +set yrange [0:200] +plot "$sysname.txt" using (int(\$1)):2 ps 0.1 +EOF + close $gnuplot; +} |