diff options
Diffstat (limited to 'examples/historical')
46 files changed, 2243 insertions, 0 deletions
diff --git a/examples/historical/dlink-ng/dlink-ng-config.pm.dist b/examples/historical/dlink-ng/dlink-ng-config.pm.dist new file mode 100755 index 0000000..82abbf6 --- /dev/null +++ b/examples/historical/dlink-ng/dlink-ng-config.pm.dist @@ -0,0 +1,169 @@ +#!/usr/bin/perl +use strict; +use warnings; +no warnings 'closure'; # remove "Variable $foo will not stay shared" :-D +package dlinkng::config; + +# Common config +our $domain_name = ".net.party.bylan.net"; # DNS-name to append to hostnames (overriden later on for TG-mode) +our $dlink_def_user = "admin"; # Default user for a factory-default D-Link +our $dlink_def_ip = "10.90.90.90"; # IP for a factory-default D-Link +our $dlink_def_mask = "255.255.255.0"; # Mask for a factory-default D-Link +our $dlink_router_ip = "10.90.90.91"; # IP to use on the router/core +our $dlink_prefix = "30"; # Prefix to use when setting D-Link IP +our $dhcp4_proxyprofile = "DHCPv4Proxy"; # DHCPv4 proxy profile to use on IOS-XR +our $dhcp6_proxyprofile = "DHCPv6Proxy"; # DHCPv6 proxy profile to use on IOS-XR +our $vrf_prefix = "dlink"; # What to prefix the VRF-number (Thread ID) with +our $max_threads = 1; # Max threads to use +our $dlink_host_suffix = "_DGS-3100"; # Suffix for hostname on the D-Link switches (needed by NMS) +our $default_coreswos = "ios"; # Default OS on coresw +our $dlink_lacp_start = '45'; # First port for LACP-group on D-Links +our $dlink_lacp_end = '48'; # Last port for LACP-group on D-Links +our $configure_last_port = 0; # Configure last port differently than the rest +our $last_port_regex = '^e([1-8][1-9]|[2-8][0-9])-'; # Regex to use in combination with $configure_last_port +our $use_ssh_cisco = 0; # Use SSH towards Cisco-boxes +our $use_ssh_dlink = 0; # Use SSH towards D-Link switches +our $cdp_enable = 0; # Enable or disable CDP on each port +our $save_config = 1; # Save configuration to Cisco switch +our $access_vlan = '3602'; # VLAN to use for last port + +# Specific config -- just declare empty +our $cisco_user = ""; # Username used when logging into the swithces +our $cisco_pass = ""; # Password used when logging into the switches +our $dhcprelay4_pri = ""; # Primary ip helper-address / ip dhcp relay address +our $dhcprelay4_sec = ""; # Secondary ip helper-address / ip dhcp relay address +our $dhcprelay6_pri = ""; # Primary ipv6 dhcp relay +our $dhcprelay6_sec = ""; # Secondary ipv6 dhcp relay +our $log_dir = ""; # Path to logfiles + +# Placeholders, setting them after all config loaded +our ($po_config, $last_port_config, $os_regex, $os_info); + +# Set variables that relies on all config being loaded +sub set_variables{ + # Custom Portchannel-config + $po_config = { + ios => [ + "ip directed-broadcast 2699", + "ip pim sparse-mode", + "ip pim bsr-border", + "logging event link-status", + "ipv6 nd other-config-flag", + "ipv6 dhcp server sexdhcp", + ], + nx => [ + "", + ], + xr => [ + "logging events link-status", + "ipv4 directed-broadcast", + "ipv6 nd prefix default 300 300 no-autoconfig", + "ipv6 nd other-config-flag", + "ipv6 nd managed-config-flag", + ], + }; + + # Custom last port config + $last_port_config = { + ios => [ + "logging event link-status", + "switchport mode access", + "switchport access vlan $access_vlan", + "spanning-tree bpduguard enable", + ], + nx => [ + "", + ], + xr => [ + "", + ], + }; + + # Define what OS-version a coresw runs + # NX, XR, XE, etc + # The regex is matched against $coreswip + $os_regex = { + ios => 'iosbox', + nx => 'flexusnexus', + xr => 'c01', + }; + + # Configure settings for each OS + $os_info = { + ios => { + max_sessions => 10, + }, + nx => { + # define 64 sessions on nxos + # nx-os# conf t + # nx-os(config)# feature dhcp + # nx-os(config)# line vty + # nx-os(config-line)# session-limit 64 + max_sessions => 50, + }, + xr => { + # telnet vrf default ipv4 server max-servers 100 access-list MGNTv4 + # telnet vrf default ipv6 server max-servers 100 access-list MGNTv6 + max_sessions => 50, + }, + }; +} + +# Load ByLAN related configuration +sub load_bylan_config{ + # Define bylan-dir, and add it to %INC + my $bylan_dir; + BEGIN { + use FindBin; + $bylan_dir = "$FindBin::Bin"; # Assume working-folder is the path where this script resides + } + use lib $bylan_dir; + eval "use bylan"; + use Getopt::Long; + + # Load config + my $config_file = "$bylan_dir/bylan.conf"; + my $conf = Config::General->new( + -ConfigFile => $config_file, + -InterPolateVars => 1); + my %config = $conf->getall; + + # Options + $cisco_user = "$config{switches}->{user}"; # Username used when logging into the swithces + $cisco_pass = "$config{switches}->{pw}"; # Password used when logging into the switches + $dhcprelay4_pri = "$config{servers}->{dhcp1_ipv4}"; # Primary ip helper-address / ip dhcp relay address + $dhcprelay4_sec = "$config{servers}->{dhcp2_ipv4}"; # Secondary ip helper-address / ip dhcp relay address + $dhcprelay6_pri = "$config{servers}->{dhcp1_ipv6}"; # Primary ipv6 dhcp relay + $dhcprelay6_sec = "$config{servers}->{dhcp2_ipv6}"; # Secondary ipv6 dhcp relay + $log_dir = "$bylan_dir/logs/telnet"; # Path to logfiles +} + +# Load TG related configuration +sub load_tg_config{ + my $tg_dir; + BEGIN { + $tg_dir = '/root/tgmanage'; + require "$tg_dir/include/config.pm"; + eval { + require "$tg_dir/include/config.local.pm"; + }; + } + + # Options + $cisco_user = "$nms::config::ios_user"; # Username used when logging into the swithces + $cisco_pass = "$nms::config::ios_pass"; # Password used when logging into the switches + $domain_name = ".infra.$nms::config::tgname.gathering.org"; # DNS-name to append to hostnames + $dhcprelay4_pri = "$nms::config::dhcp_server1"; # Primary ip helper-address / ip dhcp relay address + $dhcprelay4_sec = "$nms::config::dhcp_server2"; # Secondary ip helper-address / ip dhcp relay address + $log_dir = "$tg_dir/dlink-ng/log"; # Path to logfiles +} + +# Uncomment the one you want +#load_bylan_config(); +#load_tg_config(); + +# Set last variables that depend on the config above being set +set_variables(); + + +1; diff --git a/examples/historical/dlink-ng/dlink-ng.pl b/examples/historical/dlink-ng/dlink-ng.pl new file mode 100755 index 0000000..5d9efa0 --- /dev/null +++ b/examples/historical/dlink-ng/dlink-ng.pl @@ -0,0 +1,1242 @@ +#!/usr/bin/perl +use strict; +use warnings; +use Net::Telnet::Cisco; +use Net::Ping; +use Term::ANSIColor; +use threads; +use threads::shared; +use Thread::Queue; +use Getopt::Long; +use Net::IP; +use Net::OpenSSH; +BEGIN { + use File::Basename; + my $dlink_dir = dirname(__FILE__); + require "$dlink_dir/dlink-ng-config.pm"; +} + +# Make sure dlinkconfig.pm loads config (i.e. one config type has been uncommented) +die("No config type specified. Uncomment the wanted subroutine in the config file.\n") unless ($dlinkng::config::cisco_user); + +# Stuff +my $switchq = Thread::Queue->new(); # Queue to put switches in +my $switches : shared = 0; # Number of successful switches +my $failed_switches : shared = 0; # Number of failed switches +my $total_time : shared = 0; # Total time spent for all switches +my %telnet_sessions : shared; # Number of sessions currently in use +my $DLINK_TEMPLATE; # Filehandle used for reading D-Link template + +# Autoflush +$| = 1; + +# Get options +my ($cisco_config, $single_switch, $dlink_config, $last_port_config, $last_port_desc); +if (@ARGV > 0) { + GetOptions( + 'c|cisco|ciscoconfig' => \$cisco_config, # Configure on the Cisco-side only (Portchannel, interfaces, etc) + 's|switch=s' => \$single_switch, # Configure a single switch + 'd|dlink|dlinkconfig=s' => \$dlink_config, # Push D-Link-template-config to D-Link (not used @ TG) + 'lastport' => \$last_port_config, # Configure the last port only (Cisco-side) + 'lastportdesc' => \$last_port_desc, # Configure the description on the last port (Cisco-side) + ) +} + +# Exit if D-Link template file doesn't exist +if ($dlink_config){ + unless(-e $dlink_config){ + die("File '$dlink_config' does not exists. Aborting.\n"); + } +} + +# Exit if $cisco_config and $last_port_config or $last_port_desc is set +if ($cisco_config && ($last_port_config || $last_port_desc)){ + die("\$cisco_config and \$last_port_config (or \$last_port_desc) can't be used together.\n"); +} + +# If $last_port_desc, assume $last_port_config +if ($last_port_desc){ + $last_port_config = 1; +} + +# Exit if we give $last_port_config or $last_port_desc parameters, but $configure_last_port is not set +if ($last_port_config || $last_port_desc){ + unless($dlinkng::config::configure_last_port){ + die("\$configure_last_port not set, but expected due to either \$last_port_config or \$last_port_desc.\n"); + } +} + +# Print stuff +sub log_it{ + my ($logtype, $color, $switchname, $msg) = @_; + printf ("%-38s %s\n", colored("$logtype", "$color") . "/" . colored("$switchname", "bold") . ":", "$msg"); +} + +# INFO-logs +sub info{ + my ($switchname, $msg) = @_; + log_it("INFO", "blue", $switchname, $msg); + return 1; +} + +# ERROR-logs +sub error{ + my ($switchname, $msg) = @_; + printf ("%-38s %s\n", colored("ERROR", "red") . "/" . colored("$switchname", "bold") . ":", "$msg"); + return 0; +} + +# Debug from Net::Telnet::Cisco and similar +sub debug{ + my ($switchname, $errmsg) = @_; + + if ($errmsg){ + foreach my $line (split('\\n', $errmsg)){ + error($switchname, $line); + } + } +} + +# Abort +sub abort{ + my ($switchname, $t1, $t2) = @_; + + $t1->close if defined($t1); + $t2->close if defined($t2); + + return error($switchname, "Aborting."); +} + +# Set coreswos +sub set_coreswos{ + my $coreswip = shift; + + my $os = $dlinkng::config::default_coreswos; + + foreach my $swos ( sort keys %$dlinkng::config::os_regex ){ + $os = $swos if ($coreswip =~ m/$dlinkng::config::os_regex->{$swos}/); + } + + return $os; +} + +# Is normal IOS? +sub is_ios{ + my $coreswos = shift; + return 1 if ($coreswos =~ m/^ios$/i); + return 0; +} + +# Is NX-OS? +sub is_nx{ + my $coreswos = shift; + return 1 if ($coreswos =~ m/^nx$/i); + return 0; +} + +# Is IOS-XR? +sub is_xr{ + my $coreswos = shift; + return 1 if ($coreswos =~ m/^xr$/i); + return 0; +} + +# Cisco-ping +sub cisco_ping{ + my ($cisco, $ip, $timeout, $coreswos, $vrf) = @_; + my $cmd; + + if (is_nx($coreswos)){ + $cmd = "ping $ip count 1 timeout 1"; + $cmd .= " vrf ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf)); + + } elsif (is_xr($coreswos)){ + # IOS-XR + $cmd = "ping"; + $cmd .= " vrf ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf)); + $cmd .= " $ip count 1 timeout 1"; + + } else { + # IOS + $cmd = "ping"; + $cmd .= " vrf ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf)); + $cmd .= " $ip repeat 1 timeout 1"; + } + + my $pong = 0; + my $tries = 0; + while (($pong == 0) && ($tries < $timeout)){ + my @res = $cisco->cmd($cmd); + + # if blank, try again + # happens at least on ME3600X + next unless @res; + + # sleep if it complains about no valid source address + # % VRF does not have a usable source address + # this is caused by no link, or network not propagated + # observed on WS-C6506-E with sup720 running 122-33.SXJ5 + sleep 1 if ("@res" =~ m/VRF does not have a usable source address/); + + if (is_nx($coreswos)){ + $pong = 1 if ($res[1] =~ m/^64 bytes from $ip/i); + } else { + $pong = 1 if ($res[-1] =~ m/^\s*Success rate is 100 percent/i); + } + $tries++; + } + return $pong; +} + +# Net::Ping-ping +sub pong{ + my ($ip, $timeout) = @_; + my $pong = 0; + my $tries = 0; + + while(($pong == 0) && ($tries < $timeout)){ + my $p = Net::Ping->new(); + + if ($p->ping($ip, 5)) { + $pong = 1; + } + + $tries++; + } + return $pong; +} + +# Create login to D-Link +sub dlink_login{ + my ($switch, $ip, $vrf, $telnet_source) = @_; + + my $dlink = Net::Telnet::Cisco->new( + Host => $switch->{coreswip} . $dlinkng::config::domain_name, + Errmode => 'return', + output_log => "$dlinkng::config::log_dir/dlink-output-$switch->{coreswip}-$switch->{switchname}.log", + input_log => "$dlinkng::config::log_dir/dlink-input-$switch->{coreswip}-$switch->{switchname}.log", + Prompt => '/\S+[#>]/', + Timeout => 60 + ); + + unless (defined($dlink)) { + return error($switch->{switchname}, "Could not connect to '$switch->{coreswip}'."); + } + + info($switch->{switchname}, "Logging in to coreswitch '$switch->{coreswip}' to telnet to D-Link."); + + unless ($dlink->login($dlinkng::config::cisco_user, $dlinkng::config::cisco_pass)){ + $dlink->close; + return error($switch->{switchname}, "Can't log in to coreswitch '$switch->{coreswip}' (to telnet to D-Link)."); + } + + # Don't do enable on IOS-XR + unless(is_xr($switch->{coreswos})){ + $dlink->enable; + debug($switch->{switchname}, $dlink->errmsg); + } + + my $cmd; + if (is_nx($switch->{coreswos})){ + # NX-OS + $cmd = "telnet $ip"; + $cmd .= " vrf ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf)); + $cmd .= " source $telnet_source" if ($telnet_source && defined($telnet_source)); + + } elsif (is_xr($switch->{coreswos})){ + # IOS-XR + $cmd = "telnet "; + $cmd .= "vrf ${dlinkng::config::vrf_prefix}${vrf} " if ($vrf && defined($vrf)); + $cmd .= "$ip"; + $cmd .= " source-interface $telnet_source" if ($telnet_source && defined($telnet_source)); + + } else { + # IOS + $cmd = "telnet $ip"; + $cmd .= " /vrf ${dlinkng::config::vrf_prefix}${vrf}" if ($vrf && defined($vrf)); + $cmd .= " /source-interface $telnet_source" if ($telnet_source && defined($telnet_source)); + } + + info($switch->{switchname}, "Telneting to D-Link."); + $dlink->print($cmd); + + info($switch->{switchname}, "Waiting for login prompt."); + $dlink->waitfor('/User ?Name:/') + or return abort($switch->{switchname}, $dlink); + + info($switch->{switchname}, "Got login prompt, logging in."); + telnet_print($switch, $dlink, $dlinkng::config::dlink_def_user, 0) + or return abort($switch->{switchname}, $dlink); + + info($switch->{switchname}, "Waiting for prompt."); + $dlink->waitfor('/\S+\#/') + or return abort($switch->{switchname}, $dlink); + + # disable CLI paging + telnet_print($switch, $dlink, "disable clipaging") + or return abort($switch->{switchname}, $dlink); + + info($switch->{switchname}, "Logged in to D-Link"); + return $dlink; +} + +# Execute telnet-command +sub telnet_cmd{ + my ($switch, $telnet, $cmd) = @_; + + unless ($telnet->cmd($cmd)){ + error($switch->{switchname}, "Command '$cmd' failed"); + debug($switch->{switchname}, $telnet->errmsg); + + if($cmd =~ m/commit/){ + # If commit on IOS-XR failed, print the reason + if(is_xr($switch->{coreswos})){ + # Redundant check, but whatever + my @failed = $telnet->cmd("show configuration failed"); + + if(@failed){ + foreach my $line (@failed){ + chomp($line); + error($switch->{switchname}, $line); + } + } + } + } + + return 0; + } + + return 1; +} + +# Execute telnet-print +sub telnet_print{ + my ($switch, $telnet, $cmd, $waitfor) = @_; + + unless (defined($waitfor)){ + $waitfor = 1; + } + + unless ($telnet->print($cmd)){ + error($switch->{switchname}, "Command '$cmd' failed."); + debug($switch->{switchname}, $telnet->errmsg); + return 0; + } + + if ($waitfor){ + $telnet->waitfor('/\S+\#/') or return 0; + } + + return 1; +} + +# Make sure interface actually is shut +sub no_no_shut{ + my ($switch, $cisco, $port) = @_; + + info($switch->{switchname}, "Making sure interface $port /REALLY/ gets shut."); + + # There is a few reasons as to why we want to do this. + # On some boxes/OSes, default config for an interface is 'no shut'. + # On some boxes/OSes, the 'shut' command isn't applied right away after + # you do a 'shut'. + + my $return = 0; + if(is_xr($switch->{coreswos})){ + # don't need to do any checks on XR + telnet_cmd($switch, $cisco, "shut") + or return abort($switch->{switchname}, $cisco); + + $return = 1; + } else { + # on all other OS + my $tries = 0; + + while (1){ + if($tries >= 5){ + # max 5 tries + last; + } + + sleep 1; # wait a bit + + telnet_cmd($switch, $cisco, "shut") + or return abort($switch->{switchname}, $cisco); + + # now we need to check that the 'running config' actually reflects this + + my @shut_info = $cisco->cmd("do sh run int $port | i shutdown"); + + unless(@shut_info){ + $tries++; + next; + } + + my $shut = "@shut_info"; + chomp($shut); + + if ($shut =~ m/shutdown/i){ + $return = 1; + last; + } else { + $tries++; + next; + } + } + } + + return $return; +} + +# Reset all interfaces +sub reset_interfaces{ + my ($switch, $cisco) = @_; + + # Take down interface + info($switch->{switchname}, "Resetting interfaces."); + + telnet_cmd($switch, $cisco, "conf t") + or return abort($switch->{switchname}, $cisco); + + # Remove old config/return to defaults on interfaces + # We also shut them to avoid D-Link looping + foreach my $port (@{$switch->{ports}}){ + telnet_cmd($switch, $cisco, "default int $port") + or return abort($switch->{switchname}, $cisco); + telnet_cmd($switch, $cisco, "int $port") + or return abort($switch->{switchname}, $cisco); + no_no_shut($switch, $cisco, $port) + or return abort($switch->{switchname}, $cisco); + + unless(is_xr($switch->{coreswos})){ + # only do this if not IOS-XR + telnet_cmd($switch, $cisco, "no switchport") + or return abort($switch->{switchname}, $cisco); + } + } + + # Remove portchannel + if(is_ios($switch->{coreswos})){ + # IOS fails on the next command, if the portchannel doesn't exist + # Ignore error on this command + $cisco->cmd("no int Po$switch->{etherchannel}"); + + } elsif(is_xr($switch->{coreswos})){ + # Other syntax on XR, called Bundle-Ether + telnet_cmd($switch, $cisco, "no int Bundle-Ether$switch->{etherchannel}") + or return abort($switch->{switchname}, $cisco); + + } else { + # Other OS, that doesnt fail + telnet_cmd($switch, $cisco, "no int Po$switch->{etherchannel}") + or return abort($switch->{switchname}, $cisco); + + } + + # Commit on XR + if(is_xr($switch->{coreswos})){ + telnet_cmd($switch, $cisco, "commit") + or return abort($switch->{switchname}, $cisco); + } + + telnet_cmd($switch, $cisco, "end") + or return abort($switch->{switchname}, $cisco); + + return 1; +} + +# Set up single interface +sub configure_interface{ + my ($switch, $cisco, $port, $ip, $mask, $vrf) = @_; + + # Configure port + telnet_cmd($switch, $cisco, "int $port") + or return abort($switch->{switchname}, $cisco); + + unless(is_xr($switch->{coreswos})){ + # only do this if not IOS-XR + telnet_cmd($switch, $cisco, "no switchport") + or return abort($switch->{switchname}, $cisco); + } + + # Only do VRF-config if $vrf is defined + if($vrf && defined($vrf)){ + if(is_nx($switch->{coreswos})){ + # No error-check on the next command, as NX-OS + # spits out "% Deleted all L3 config on interface Ethernet1/45" + # making Net::Telnet::Cisco think it's an error + + $cisco->cmd("vrf member ${dlinkng::config::vrf_prefix}${vrf}"); + + } elsif(is_xr($switch->{coreswos})){ + # IOS-XR + telnet_cmd($switch, $cisco, "vrf ${dlinkng::config::vrf_prefix}${vrf}") + or return abort($switch->{switchname}, $cisco); + + } else { + # IOS + telnet_cmd($switch, $cisco, "ip vrf forwarding ${dlinkng::config::vrf_prefix}${vrf}") + or return abort($switch->{switchname}, $cisco); + } + } + + # Add IP + info($switch->{switchname}, "Adding IP-address to interface."); + + if(is_xr($switch->{coreswos})){ + # IOS-XR + telnet_cmd($switch, $cisco, "ipv4 address $ip $mask") + or return abort($switch->{switchname}, $cisco); + + } else { + # All other + telnet_cmd($switch, $cisco, "ip address $ip $mask") + or return abort($switch->{switchname}, $cisco); + } + + # 'no shut'-patrol reporting in! + telnet_cmd($switch, $cisco, "no shut") + or return abort($switch->{switchname}, $cisco); + + # Commit on XR + if(is_xr($switch->{coreswos})){ + telnet_cmd($switch, $cisco, "commit") + or return abort($switch->{switchname}, $cisco); + } + + telnet_cmd($switch, $cisco, "end") + or return abort($switch->{switchname}, $cisco); + + return 1; +} + +# Push D-Link template config to a D-Link +sub push_dlink_template_config{ + my $switch = shift; # switchinfo + + # No need to bounce via Cisco-box; login directly to D-Link + my $dlink = Net::Telnet::Cisco->new( + Host => $switch->{ipv4address}, + Errmode => 'return', + output_log => "$dlinkng::config::log_dir/dlink-output-$switch->{coreswip}-$switch->{switchname}.log", + input_log => "$dlinkng::config::log_dir/dlink-input-$switch->{coreswip}-$switch->{switchname}.log", + Prompt => '/\S+[#>]/', + Timeout => 60 + ); + + unless (defined($dlink)) { + return error($switch->{switchname}, "Could not connect to '$switch->{switchname}' ($switch->{ipv4})."); + } + + info($switch->{switchname}, "Logging in to D-Link '$switch->{switchname}' ($switch->{ipv4address})."); + $dlink->waitfor('/User ?Name:/') + or return abort($switch->{switchname}, $dlink); + + info($switch->{switchname}, "Got login prompt, logging in."); + telnet_print($switch, $dlink, $dlinkng::config::dlink_def_user, 0) + or return abort($switch->{switchname}, $dlink); + + info($switch->{switchname}, "Waiting for prompt."); + $dlink->waitfor('/\S+\#/') + or return abort($switch->{switchname}, $dlink); + + # disable CLI paging + telnet_print($switch, $dlink, "disable clipaging") + or return abort($switch->{switchname}, $dlink); + + info($switch->{switchname}, "Logged in to D-Link"); + + # Done logging in, let's configure stuff + info($switch->{switchname}, "Opening D-Link template file ($dlink_config)."); + open $DLINK_TEMPLATE, '<', $dlink_config or return error($switch->{switchname}, "Couldn't open D-Link template ($dlink_config): $!"); + + info($switch->{switchname}, "Applying config from D-Link template file ($dlink_config)."); + + while (my $line=<$DLINK_TEMPLATE>) { + chomp $line; + + next if ($line =~ m/^\s*(((#|\!).*)|$)/); # skip if comment, or blank line + + telnet_print($switch, $dlink, $line) + or return abort($switch->{switchname}, $dlink); + + sleep 1; # The D-Link's are a bit slow... + } + + close $DLINK_TEMPLATE or return error($switch->{switchname}, "Couldn't close D-Link template ($dlink_config): $!"); + + info($switch->{switchname}, "Done applying config from D-Link template file ($dlink_config). Saving..."); + + # Save config + logout + telnet_print($switch, $dlink, "save", 0) + or return abort($switch->{switchname}, $dlink); + telnet_print($switch, $dlink, "Y") + or return abort($switch->{switchname}, $dlink); + telnet_print($switch, $dlink, "logout") + or return abort($switch->{switchname}, $dlink); + + # Done + log_it("SUCCESS", "green", $switch->{switchname}, "Done pushing D-Link template config to switch $switch->{switchname} ($switch->{ipv4address}). \\o/"); + $dlink->close; + return 1; +} + +# Setup a switch +sub setup{ + my $switch = shift; # switchinfo + my $vrf = threads->tid(); # use thread ID as VRF-number + + # Remove last port if we're skipping it + my $last_port; + if ($dlinkng::config::configure_last_port){ + # assume we want to skip a port, so we check against regex + if($switch->{switchname} =~ m/$dlinkng::config::last_port_regex/){ + $last_port = pop(@{$switch->{ports}}); + } + } + + if($last_port_config){ + info($switch->{switchname}, "Configuring last port only."); + } + + if($cisco_config){ + info($switch->{switchname}, "Configuring things on the Cisco-side only."); + } + + unless($cisco_config || $last_port_config){ + info($switch->{switchname}, "Starting configuration of $switch->{switchname} ($switch->{ipv4address})."); + info($switch->{switchname}, "Trying to ping $switch->{ipv4address}."); + + if (pong($switch->{ipv4address}, 1)){ + # push template-config to D-Link if template-file is given as argument + if($dlink_config){ + log_it("INFO", "green", $switch->{switchname}, "Switch $switch->{switchname} ($switch->{ipv4address}) is already responding to ping! \\o/"); + info($switch->{switchname}, "Going to push D-Link template config to switch $switch->{switchname} ($switch->{ipv4address})"); + return push_dlink_template_config($switch); + } else { + # if not + log_it("INFO", "green", $switch->{switchname}, "Skipping $switch->{switchname} ($switch->{ipv4address}): is already responding to ping! \\o/"); + return 1; + } + } + + info($switch->{switchname}, "Not responding to ping, configuring device."); + } + + info($switch->{switchname}, "Connecting to coreswitch '$switch->{coreswip}'."); + + my $cisco; + if ($dlinkng::config::use_ssh_cisco){ + # Use SSH + my $ssh = Net::OpenSSH->new( $dlinkng::config::cisco_user . ':' . + $dlinkng::config::cisco_pass . '@' . + $switch->{coreswip} . $dlinkng::config::domain_name, + timeout => 60); + + if ($ssh->error){ + return debug($switch->{switchname}, $ssh->error); + } + + my ($pty, $pid) = $ssh->open2pty({stderr_to_stdout => 1}) + or return debug($switch->{switchname}, $ssh->error); + + $cisco = Net::Telnet::Cisco->new( + Fhopen => $pty, + Telnetmode => 0, + #Cmd_remove_mode => 1, + Errmode => 'return', + output_log => "$dlinkng::config::log_dir/cisco-output-$switch->{coreswip}-$switch->{switchname}.log", + input_log => "$dlinkng::config::log_dir/cisco-input-$switch->{coreswip}-$switch->{switchname}.log", + Prompt => '/\S+[#>]/', + #Prompt => '/(?m:^\\s?(?:[\\w.\/]+\:)?(?:[\\w.-]+\@)?[\\w.-]+\\s?(?:\(config[^\)]*\))?\\s?[\$#>]\\s?(?:\(enable\))?\\s*$)/', + ); + } else { + # Don't use SSH + $cisco = Net::Telnet::Cisco->new( + Host => $switch->{coreswip} . $dlinkng::config::domain_name, + Errmode => 'return', + output_log => "$dlinkng::config::log_dir/cisco-output-$switch->{coreswip}-$switch->{switchname}.log", + input_log => "$dlinkng::config::log_dir/cisco-input-$switch->{coreswip}-$switch->{switchname}.log", + Prompt => '/\S+[#>]/', + #Prompt => '/(?m:^\\s?(?:[\\w.\/]+\:)?(?:[\\w.-]+\@)?[\\w.-]+\\s?(?:\(config[^\)]*\))?\\s?[\$#>]\\s?(?:\(enable\))?\\s*$)/', + Timeout => 60 + ); + } + + unless (defined($cisco)){ + return error($switch->{switchname}, "Could not connect to '$switch->{coreswip}'."); + } + + unless ($dlinkng::config::use_ssh_cisco){ + info($switch->{switchname}, "Logging in to coreswitch '$switch->{coreswip}'."); + + unless ($cisco->login($dlinkng::config::cisco_user, $dlinkng::config::cisco_pass)){ + $cisco->close; + return error($switch->{switchname}, "Can't log in to '$switch->{coreswip}'."); + } + } + + # Don't do enable on IOS-XR + unless(is_xr($switch->{coreswos})){ + $cisco->enable; + debug($switch->{switchname}, $cisco->errmsg); + } + + # Disable paging + telnet_cmd($switch, $cisco, "terminal length 0") + or return abort($switch->{switchname}, $cisco); + + unless($cisco_config || $last_port_config){ + # Prepare ports + reset_interfaces($switch, $cisco) + or return abort($switch->{switchname}, $cisco); + + # Set up port 1 for D-Link telneting + telnet_cmd($switch, $cisco, "conf t") + or return abort($switch->{switchname}, $cisco); + + info($switch->{switchname}, "Enabling VRF (${dlinkng::config::vrf_prefix}${vrf}). Applying to interface."); + if(is_nx($switch->{coreswos})){ + # Remove previous VRF + # No error-check on the next command, as NX-OS + # spits out "% VRF dlink-X not found" + # making Net::Telnet::Cisco think it's an error + + # Extra overhead to delete, not used + #$cisco->cmd("no vrf context ${dlinkng::config::vrf_prefix}${vrf}"); + #sleep 10; # NX-OS seems to need some time to delete a VRF + + # Create VRF + telnet_cmd($switch, $cisco, "vrf context ${dlinkng::config::vrf_prefix}${vrf}") + or return abort($switch->{switchname}, $cisco); + + } elsif(is_xr($switch->{coreswos})){ + # IOS-XR + telnet_cmd($switch, $cisco, "vrf ${dlinkng::config::vrf_prefix}${vrf}") + or return abort($switch->{switchname}, $cisco); + + } else { + # Default OS + # IOS fails on the next command, if the vrf doesn't exist + # Ignore error on this command + + # Extra overhead to delete, not used + #$cisco->cmd("no ip vrf ${dlinkng::config::vrf_prefix}${vrf}"); + + # Create VRF + telnet_cmd($switch, $cisco, "ip vrf ${dlinkng::config::vrf_prefix}${vrf}") + or return abort($switch->{switchname}, $cisco); + telnet_cmd($switch, $cisco, "rd $vrf:$vrf") + or return abort($switch->{switchname}, $cisco); + } + + # Configure port #1 + configure_interface($switch, $cisco, @{$switch->{ports}}[0], $dlinkng::config::dlink_router_ip, $dlinkng::config::dlink_def_mask, $vrf) + or return abort($switch->{switchname}, $cisco); + + info($switch->{switchname}, "Waiting for D-Link to answer on $dlinkng::config::dlink_def_ip in VRF ${dlinkng::config::vrf_prefix}${vrf} on port #1 (" . @{$switch->{ports}}[0] . ")."); + + # Use port 1 if ping succeeds + my $p_count = 0; + my $dlink_port = @{$switch->{ports}}[$p_count]; + + until (cisco_ping($cisco, $dlinkng::config::dlink_def_ip, 30, $switch->{coreswos}, $vrf)) { + # Did not ping, let's try next port + # We do this because port#1 might be damaged/not patched + + # First we need to check if there are more ports to test + if ($p_count >= $#{$switch->{ports}}){ + # Current port is last port available + # Since it did not ping, we reset all interfaces + + reset_interfaces($switch, $cisco) + or return abort($switch->{switchname}, $cisco); + $cisco->close; + return error($switch->{switchname}, "No more ports on $switch->{switchname}. Aborting."); + } + + # Use next port + $p_count++; + + info($switch->{switchname}, "D-Link on port #" . ($p_count) . " ($dlink_port) did not respond. Trying next port (" . @{$switch->{ports}}[$p_count] . ")."); + + # Try next port, reset old port + telnet_cmd($switch, $cisco, "conf t") + or return abort($switch->{switchname}, $cisco); + telnet_cmd($switch, $cisco, "default int $dlink_port") + or return abort($switch->{switchname}, $cisco); + telnet_cmd($switch, $cisco, "int $dlink_port") + or return abort($switch->{switchname}, $cisco); + no_no_shut($switch, $cisco, $dlink_port) + or return abort($switch->{switchname}, $cisco); + + # Set new port + $dlink_port = @{$switch->{ports}}[$p_count]; + + # Configure new port + configure_interface($switch, $cisco, $dlink_port, $dlinkng::config::dlink_router_ip, $dlinkng::config::dlink_def_mask, $vrf) + or return abort($switch->{switchname}, $cisco); + + info($switch->{switchname}, "Waiting for D-Link to answer on $dlinkng::config::dlink_def_ip in VRF ${dlinkng::config::vrf_prefix}${vrf} on port #" . ($p_count+1) . " (" . @{$switch->{ports}}[$p_count] . ")."); + } + + # Telnet to D-Link + info($switch->{switchname}, "Starting D-Link config phase 1."); + my $dlink = dlink_login($switch, $dlinkng::config::dlink_def_ip, $vrf) + or return abort($switch->{switchname}, $cisco); + + info($switch->{switchname}, "Setting hostname to $switch->{switchname}${dlinkng::config::dlink_host_suffix}"); + telnet_print($switch, $dlink, "config snmp system_name $switch->{switchname}${dlinkng::config::dlink_host_suffix}") + or return abort($switch->{switchname}, $cisco, $dlink); + + info($switch->{switchname}, "Adding LACP. Enabling STP."); + telnet_print($switch, $dlink, "create link_aggregation group_id 1 type lacp") + or return abort($switch->{switchname}, $cisco, $dlink); + telnet_print($switch, $dlink, "config link_aggregation group_id 1 ports 1:($dlinkng::config::dlink_lacp_start-$dlinkng::config::dlink_lacp_end)") + or return abort($switch->{switchname}, $cisco, $dlink); + telnet_print($switch, $dlink, "enable stp") + or return abort($switch->{switchname}, $cisco, $dlink); + + info($switch->{switchname}, "STP enabled, logging in again."); + $dlink->close; + + unless (cisco_ping($cisco, $dlinkng::config::dlink_def_ip, 60, $switch->{coreswos}, $vrf)) { + reset_interfaces($switch, $cisco) + or return abort($switch->{switchname}, $cisco); + $cisco->close; + return error($switch->{switchname}, "Can't login to $switch->{switchname} on $dlinkng::config::dlink_def_ip, aborting."); + } + + $dlink = dlink_login($switch, $dlinkng::config::dlink_def_ip, $vrf) + or return abort($switch->{switchname}, $cisco); + + info($switch->{switchname}, "Running STP config."); + telnet_print($switch, $dlink, "config stp version mstp") + or return abort($switch->{switchname}, $cisco, $dlink); + telnet_print($switch, $dlink, "config stp priority 61440 instance_id 0") + or return abort($switch->{switchname}, $cisco, $dlink); + telnet_print($switch, $dlink, "config stp ports 1:(1-44) edge true") + or return abort($switch->{switchname}, $cisco, $dlink); + telnet_print($switch, $dlink, "enable lldp") + or return abort($switch->{switchname}, $cisco, $dlink); + + info($switch->{switchname}, "Setting IP address."); + telnet_print($switch, $dlink, "config ipif System ipaddress $switch->{ipv4address}/$dlinkng::config::dlink_prefix vlan default") + or return abort($switch->{switchname}, $cisco, $dlink); + + info($switch->{switchname}, "Closing D-Link link."); + $dlink->close; + + info($switch->{switchname}, "Configuring IP on gateway."); + telnet_cmd($switch, $cisco, "conf t") + or return abort($switch->{switchname}, $cisco); + telnet_cmd($switch, $cisco, "default int $dlink_port") + or return abort($switch->{switchname}, $cisco); + configure_interface($switch, $cisco, $dlink_port, $switch->{ipv4gateway}, $switch->{netmask}) + or return abort($switch->{switchname}, $cisco); + + # Wait for network convergence + info($switch->{switchname}, "Waiting for network to converge."); + unless (cisco_ping($cisco, $switch->{ipv4address}, 60, $switch->{coreswos})) { + reset_interfaces($switch, $cisco) + or return abort($switch->{switchname}, $cisco); + $cisco->close; + return error($switch->{switchname}, "Can't ping $switch->{switchname} on $switch->{ipv4address}, aborting."); + } + + # Do it again! + info($switch->{switchname}, "D-Link config phase 2."); + $dlink = dlink_login($switch, $switch->{ipv4address}, '', $dlink_port) or return abort($switch->{switchname}, $cisco); + + info($switch->{switchname}, "Setting default route on switch. Saving config."); + telnet_print($switch, $dlink, "create iproute default $switch->{ipv4gateway}") + or return abort($switch->{switchname}, $cisco, $dlink); + telnet_print($switch, $dlink, "save", 0) + or return abort($switch->{switchname}, $cisco, $dlink); + telnet_print($switch, $dlink, "Y") + or return abort($switch->{switchname}, $cisco, $dlink); + telnet_print($switch, $dlink, "logout") + or return abort($switch->{switchname}, $cisco, $dlink); + + info($switch->{switchname}, "Closing D-Link link."); + $dlink->close; + } + + unless($last_port_config){ + # Configure final IOS stuff + info($switch->{switchname}, "Final IOS config phase. Setting up all interfaces + Port-Channel."); + + # Reset interfaces + reset_interfaces($switch, $cisco) + or return abort($switch->{switchname}, $cisco); + + telnet_cmd($switch, $cisco, "conf t") + or return abort($switch->{switchname}, $cisco); + + # Portchannel needs to exist before we can assign interfaces to it + # This needs to be done on IOS-XE, but we do it on all + if(is_xr($switch->{coreswos})){ + # Other syntax on XR, called Bundle-Ether + telnet_cmd($switch, $cisco, "int Bundle-Ether$switch->{etherchannel}") + or return abort($switch->{switchname}, $cisco); + + } else { + telnet_cmd($switch, $cisco, "int Po$switch->{etherchannel}") + or return abort($switch->{switchname}, $cisco); + + } + + # Rest of the config + my $etherchan_desc; + foreach my $port (@{$switch->{ports}}){ + telnet_cmd($switch, $cisco, "int $port") + or return abort($switch->{switchname}, $cisco); + + unless(is_xr($switch->{coreswos})){ + # only do this if not IOS-XR + telnet_cmd($switch, $cisco, "no switchport") + or return abort($switch->{switchname}, $cisco); + } + + # 'no shut'-patrol reporting in! + telnet_cmd($switch, $cisco, "no shut") + or return abort($switch->{switchname}, $cisco); + telnet_cmd($switch, $cisco, "description D-Link $switch->{switchname}; RJ-45; 1G;") + or return abort($switch->{switchname}, $cisco); + + # disable CDP if specified + unless($dlinkng::config::cdp_enable){ + telnet_cmd($switch, $cisco, "no cdp enable") + or return abort($switch->{switchname}, $cisco); + } + + # Assign to Etherchannel + if(is_xr($switch->{coreswos})){ + # Other syntax on XR, called Bundle-Ether + telnet_cmd($switch, $cisco, "bundle id $switch->{etherchannel} mode passive") + or return abort($switch->{switchname}, $cisco); + + } else { + telnet_cmd($switch, $cisco, "channel-group $switch->{etherchannel} mode passive") + or return abort($switch->{switchname}, $cisco); + + } + + # add port to descr + $etherchan_desc .= "$port; "; + } + + if(is_xr($switch->{coreswos})){ + # Other syntax on XR, called Bundle-Ether + telnet_cmd($switch, $cisco, "int Bundle-Ether$switch->{etherchannel}") + or return abort($switch->{switchname}, $cisco); + + } else { + telnet_cmd($switch, $cisco, "int Po$switch->{etherchannel}") + or return abort($switch->{switchname}, $cisco); + + } + + telnet_cmd($switch, $cisco, "description D-Link $switch->{switchname}; $etherchan_desc") + or return abort($switch->{switchname}, $cisco); + + + if(is_xr($switch->{coreswos})){ + # IOS-XR + telnet_cmd($switch, $cisco, "ipv4 address $switch->{ipv4gateway} $switch->{netmask}") + or return abort($switch->{switchname}, $cisco); + + } else { + # All other + telnet_cmd($switch, $cisco, "ip address $switch->{ipv4gateway} $switch->{netmask}") + or return abort($switch->{switchname}, $cisco); + } + + # IPv6-stuff + unless (is_nx($switch->{coreswos})){ + # IOS + IOS-XR + telnet_cmd($switch, $cisco, "ipv6 enable") + or return abort($switch->{switchname}, $cisco); + } + + telnet_cmd($switch, $cisco, "ipv6 address $switch->{ipv6address}") + or return abort($switch->{switchname}, $cisco); + + # DHCP-relay/forwarding + MBD/Blazon-forwarding (broadcast) + if (is_nx($switch->{coreswos})){ + # NX-OS + telnet_cmd($switch, $cisco, "ip dhcp relay address $dlinkng::config::dhcprelay4_pri") + or return abort($switch->{switchname}, $cisco); + + # define secondary if present + if (defined($dlinkng::config::dhcprelay4_sec) && $dlinkng::config::dhcprelay4_sec){ + telnet_cmd($switch, $cisco, "ip dhcp relay address $dlinkng::config::dhcprelay4_sec") + or return abort($switch->{switchname}, $cisco); + } + } elsif (is_xr($switch->{coreswos})){ + # IOS-XR + telnet_cmd($switch, $cisco, "ipv4 helper-address vrf default $dlinkng::config::dhcprelay4_pri") + or return abort($switch->{switchname}, $cisco); + + # define secondary if present + if (defined($dlinkng::config::dhcprelay4_sec) && $dlinkng::config::dhcprelay4_sec){ + telnet_cmd($switch, $cisco, "ipv4 helper-address vrf default $dlinkng::config::dhcprelay4_sec") + or return abort($switch->{switchname}, $cisco); + } + } else { + # IOS + telnet_cmd($switch, $cisco, "ip helper-address $dlinkng::config::dhcprelay4_pri") + or return abort($switch->{switchname}, $cisco); + + # define secondary if present + if (defined($dlinkng::config::dhcprelay4_sec) && $dlinkng::config::dhcprelay4_sec){ + telnet_cmd($switch, $cisco, "ip helper-address $dlinkng::config::dhcprelay4_sec") + or return abort($switch->{switchname}, $cisco); + } + } + + # Custom Portchannel-config + # Dynamically applied depending on OS + foreach my $cmd (@{$dlinkng::config::po_config->{$switch->{coreswos}}}){ + telnet_cmd($switch, $cisco, $cmd) + or return abort($switch->{switchname}, $cisco); + } + + # 'no shut'-patrol reporting in! + telnet_cmd($switch, $cisco, "no shut") + or return abort($switch->{switchname}, $cisco); + + # Done with interface-config + # Apply DHCP-profiling if using IOS-XR + if (is_xr($switch->{coreswos})){ + telnet_cmd($switch, $cisco, "dhcp ipv4") + or return abort($switch->{switchname}, $cisco); + telnet_cmd($switch, $cisco, "interface Bundle-Ether$switch->{etherchannel} proxy profile $dlinkng::config::dhcp4_proxyprofile") + or return abort($switch->{switchname}, $cisco); + + if(defined($dlinkng::config::dhcp6_proxyprofile) && $dlinkng::config::dhcp6_proxyprofile){ + # Do DHCPv6 proxy as well + + telnet_cmd($switch, $cisco, "dhcp ipv6") + or return abort($switch->{switchname}, $cisco); + telnet_cmd($switch, $cisco, "interface Bundle-Ether$switch->{etherchannel} proxy profile $dlinkng::config::dhcp6_proxyprofile") + or return abort($switch->{switchname}, $cisco); + } + } + + # Commit on XR + if(is_xr($switch->{coreswos})){ + telnet_cmd($switch, $cisco, "commit") + or return abort($switch->{switchname}, $cisco); + } + + telnet_cmd($switch, $cisco, "end") + or return abort($switch->{switchname}, $cisco); + } + + # If we skipped last port at the start, we configure it now + if ($dlinkng::config::configure_last_port && $last_port){ + if ($last_port_desc){ + info($switch->{switchname}, "Configuring last port... (description only)"); + } else { + info($switch->{switchname}, "Configuring last port..."); + } + + telnet_cmd($switch, $cisco, "conf t") + or return abort($switch->{switchname}, $cisco); + unless ($last_port_desc){ + telnet_cmd($switch, $cisco, "default int $last_port") + or return abort($switch->{switchname}, $cisco); + } + + telnet_cmd($switch, $cisco, "int $last_port") + or return abort($switch->{switchname}, $cisco); + telnet_cmd($switch, $cisco, "description AP \@ D-Link $switch->{switchname}; RJ-45; 1G;") + or return abort($switch->{switchname}, $cisco); + + unless ($last_port_desc){ + foreach my $cmd (@{$dlinkng::config::last_port_config->{$switch->{coreswos}}}){ + telnet_cmd($switch, $cisco, $cmd) + or return abort($switch->{switchname}, $cisco); + } + # 'no shut'-patrol reporting in! + telnet_cmd($switch, $cisco, "no shut") + or return abort($switch->{switchname}, $cisco); + } + + # Commit on XR + if(is_xr($switch->{coreswos})){ + telnet_cmd($switch, $cisco, "commit") + or return abort($switch->{switchname}, $cisco); + } + + telnet_cmd($switch, $cisco, "end") + or return abort($switch->{switchname}, $cisco); + } + + # If only cisco-config + if($cisco_config){ + log_it("CONFIG", "green", $switch->{switchname}, "Cisco-config relevant to switch '$switch->{switchname}' ($switch->{ipv4address}) done! \\o/"); + } + + # Check if all is OK, but not if configuring skipped port only + my $return = 0; + if ($last_port_config){ + info($switch->{switchname}, "Done doing skipped port config. Not checking if anything is online."); + $return = 1; + } else { + if(pong($switch->{ipv4address}, 15)){ + # pingable, OK + log_it("SUCCESS", "green", $switch->{switchname}, "Switch $switch->{switchname} ($switch->{ipv4address}) set up! \\o/"); + + $return = 1; + + # push template-config to D-Link if template-file is given as argument + if($dlink_config){ + info($switch->{switchname}, "Going to push D-Link template config to switch $switch->{switchname} ($switch->{ipv4address})"); + $return = push_dlink_template_config($switch); + } + } else { + # Not pingable + if (cisco_ping($cisco, $switch->{ipv4address}, 60, $switch->{coreswos})) { + # we can reach from core, but not from other places, lets warn + log_it("ERROR", "red", $switch->{switchname}, "Switch $switch->{switchname} reachable only from core/distro."); + } else { + reset_interfaces($switch, $cisco) + or return abort($switch->{switchname}, $cisco); + $cisco->close; + return error($switch->{switchname}, "Can't ping $switch->{switchname} on $switch->{ipv4address}, aborting."); + } + } + } + + if($dlinkng::config::save_config && !is_xr($switch->{coreswos})){ + # save the cisco-config, but not if IOS-XR + info($switch->{switchname}, "Saving config on core-switch ($switch->{coreswip})."); + telnet_cmd($switch, $cisco, "write") + or return abort($switch->{switchname}, $cisco); + } + + $cisco->close; + return $return; +} + +# Process switches +sub process_switches { + while (my $switch = $switchq->dequeue()){ + last if ($switch eq 'DONE'); # all done + + my $time_start = time(); + + # Wait till there is sessions/VTYs available + while (1){ + $telnet_sessions{$switch->{coreswip}} = 0 unless $telnet_sessions{$switch->{coreswip}}; + $telnet_sessions{$switch->{coreswip}} += 2; + + if ($telnet_sessions{$switch->{coreswip}} <= $dlinkng::config::os_info->{$switch->{coreswos}}{max_sessions}){ + # lower or equal to max_sessions on current switch + # lets move on + last; + } else { + # we would exceed max_sessions on current switch + # we wait until there are free sessions + info($switch->{switchname}, "There are no more free sessions left on '$switch->{coreswip}' ($switch->{coreswos}). Waiting..."); + $telnet_sessions{$switch->{coreswip}} -= 2; + sleep (int(rand(10)) + 10); + } + } + + info($switch->{switchname}, "Number of sessions on switch '$switch->{coreswip}': $telnet_sessions{$switch->{coreswip}}."); + + if (setup($switch)) { + # Count number of switches + $switches++; + + } else { + log_it("FAILED", "red", $switch->{switchname}, "Configuring $switch->{switchname} failed."); + + # Count failed switches + $failed_switches++; + } + + # Remove session + $telnet_sessions{$switch->{coreswip}} -= 2; + + # Summarize total time spent, used to calculate average per switch + $total_time += time() - $time_start; + } + + # detach thread -- we're done + threads->detach; +} + +# Let's start +my $time_start = time(); +log_it("INFO", "yellow", "dlink-ng", "Starting dlink-ng with $dlinkng::config::max_threads threads..."); +log_it("INFO", "yellow", "dlink-ng", "Configured to skip last port on all switches.") if $dlinkng::config::configure_last_port; + +# Let's add all switches to the queue +while (<STDIN>){ + next if /^(.*#|\s+$)/; # skip if comment, or blank line + + my ($switchname, $coreswip, $etherchannel, $cidr, $ipv4address, $ipv4gateway, $ipv6address, @ports) = split; + + # skip if less than 1 port is provided + if (scalar(@ports) < 1){ + log_it("FAILED", "red", $switchname, "Switch '$switchname' had less than 1 port configured. Skipping."); + next; + } + + # define OS of the coresw + my $coreswos = set_coreswos($coreswip); + + # find netmask + my $netmask = Net::IP->new($cidr)->mask(); + + my %switch = ( + switchname => $switchname, + coreswip => $coreswip, + coreswos => $coreswos, + etherchannel => $etherchannel, + ipv4address => $ipv4address, + ipv4gateway => $ipv4gateway, + netmask => $netmask, + ipv6address => $ipv6address, + ports => \@ports, + ); + + # Only configure a single switch? + if (defined $single_switch){ + unless ($single_switch eq $switchname){ + next; + } + } + + # Add switch to queue + $switchq->enqueue(\%switch); +} + +# Let the threads know when they're done +$switchq->enqueue("DONE") for (1..$dlinkng::config::max_threads); + +# Start processing the queue +threads->create("process_switches") for (1..$dlinkng::config::max_threads); + +# Wait till all threads is done +sleep 5 while (threads->list(threads::running)); + +# If 0 switches +my $runtime = time() - $time_start; +my $total_switches = $switches + $failed_switches; +if($total_switches == 0){ + log_it("INFO", "yellow", "dlink-ng", "Finished!"); + log_it("INFO", "yellow", "dlink-ng", "Crunched 0 switches in $runtime seconds."); + exit 1; +} + +# Done +my $avg = sprintf("%.1f", $total_time / $total_switches); +log_it("INFO", "yellow", "dlink-ng", "Finished!"); +log_it("INFO", "yellow", "dlink-ng", "Crunched $total_switches switches in $runtime seconds."); +log_it("INFO", "yellow", "dlink-ng", "$switches of these were successful, while $failed_switches failed."); +log_it("INFO", "yellow", "dlink-ng", "Average of $avg seconds per switch."); diff --git a/examples/historical/dlink-ng/make-dlink-config.pl b/examples/historical/dlink-ng/make-dlink-config.pl new file mode 100755 index 0000000..7a20820 --- /dev/null +++ b/examples/historical/dlink-ng/make-dlink-config.pl @@ -0,0 +1,71 @@ +#!/usr/bin/perl -I /root/tgmanage/ +use strict; +use warnings; +use lib '..'; +BEGIN { + require "include/config.pm"; + eval { + require "include/config.local.pm"; + }; +} + +unless (@ARGV > 0) { + print "No arguments. Need switches.txt and patchlist.txt.\n"; + exit 1; +} + +my $s = open(SWITCHES, "$ARGV[0]") or die ("Cannot open switches.txt"); +my $p = open(PATCH, "$ARGV[1]") or die ("Cannot open patchlist.txt"); + +my $portchannel_start = 10; +my %portchannels; +my $letter = "a"; + +my %switches; +while(<SWITCHES>) { + chomp; + my ($network, $netmask, $switchname, $mngmt_ip) = split; # $mngmt_ip is unused + $switches{$switchname} = { + network => $network, + netmask => $netmask, + }; +} +while (<PATCH>) { + chomp; + my ($switchname, $coregw, @ports) = split; + my $network = $switches{$switchname}{network}; + my $netmask = $switches{$switchname}{netmask}; + my ($o1, $o2, $o3, $o4) = split(/\./, $network); + + # portchannel per distro + if($coregw =~ m/distro0/){ + # TG14-fix for distro0 + $portchannels{$coregw} = 15 unless ($portchannels{$coregw} && defined($portchannels{$coregw})); + } else { + $portchannels{$coregw} = $portchannel_start unless ($portchannels{$coregw} && defined($portchannels{$coregw})); + } + + if ($o4 eq "0") { + $letter = "a"; + } elsif ($o4 eq "64") { + $letter = "b"; + } elsif ($o4 eq "128") { + $letter = "c"; + } elsif ($o4 eq "192") { + $letter = "d"; + } + + my $v6addr = $nms::config::base_ipv6net . $o3 . $letter ."::1/64"; + + $o4 += 1; + my $gateway_addr = "$o1.$o2.$o3.$o4"; + $o4 += 1; + my $switch_addr = "$o1.$o2.$o3.$o4"; + + print "$switchname $coregw $portchannels{$coregw} $network/$netmask $switch_addr $gateway_addr $v6addr " . join(' ', @ports) . "\n"; + + # increase portchannel + $portchannels{$coregw}++; + + die("NO MORE ETHERCHANNELS!") if($portchannels{$coregw} > 64); # IOS-XE 4500 only supports 64 portchannels +} diff --git a/examples/historical/patches/README b/examples/historical/patches/README new file mode 100644 index 0000000..bc6a962 --- /dev/null +++ b/examples/historical/patches/README @@ -0,0 +1,17 @@ + +Patches from pre TG14. None of these patches were in use under TG14. + + +Includes various patch(es) we had to use. + +> dhcpd-never-broadcast.diff + +When using DHCP in routed networks, the router has to participate in rewriting +and sending DHCP replies on to the user. Unfortunately, some devices, +in particular Cisco's Nexus series of switches, drop such DHCP reply packets +with the broadcast bit in the flags field of the DHCP message header set. +Thi means that some operating systems, in particular Microsoft Windows Vista, +can have problems getting DHCP to work in such environments. If you enable +this flag, the DHCP server will never set the broadcast flags in the replies +it sends, even if the client set the broadcast flag. This flag overrides +the never-broadcast flag if both are set. diff --git a/examples/historical/patches/dhcpd-never-broadcast.diff b/examples/historical/patches/dhcpd-never-broadcast.diff new file mode 100644 index 0000000..ac6d24d --- /dev/null +++ b/examples/historical/patches/dhcpd-never-broadcast.diff @@ -0,0 +1,88 @@ +diff -ur isc-dhcp-4.1.1-P1/includes/dhcpd.h isc-dhcp-4.1.1-P1.patched//includes/dhcpd.h +--- isc-dhcp-4.1.1-P1/includes/dhcpd.h 2012-04-04 16:49:44.000000000 +0200 ++++ isc-dhcp-4.1.1-P1.patched//includes/dhcpd.h 2012-04-04 14:56:43.000000000 +0200 +@@ -626,6 +626,7 @@ + #define SV_LIMIT_PREFS_PER_IA 57 + #define SV_DELAYED_ACK 58 + #define SV_MAX_ACK_DELAY 59 ++#define SV_NEVER_BROADCAST 60 + + #if !defined (DEFAULT_PING_TIMEOUT) + # define DEFAULT_PING_TIMEOUT 1 +diff -ur isc-dhcp-4.1.1-P1/server/bootp.c isc-dhcp-4.1.1-P1.patched//server/bootp.c +--- isc-dhcp-4.1.1-P1/server/bootp.c 2009-07-25 00:04:52.000000000 +0200 ++++ isc-dhcp-4.1.1-P1.patched//server/bootp.c 2012-04-04 14:55:21.000000000 +0200 +@@ -283,6 +283,15 @@ + &lease -> scope, oc, MDL)) + raw.flags |= htons (BOOTP_BROADCAST); + ++ /* The inverse. */ ++ if ((oc = lookup_option (&server_universe, ++ options, SV_NEVER_BROADCAST)) && ++ evaluate_boolean_option_cache (&ignorep, packet, lease, ++ (struct client_state *)0, ++ packet -> options, options, ++ &lease -> scope, oc, MDL)) ++ raw.flags &= htons (~BOOTP_BROADCAST); ++ + /* Figure out the address of the next server. */ + memset (&d1, 0, sizeof d1); + oc = lookup_option (&server_universe, options, SV_NEXT_SERVER); +diff -ur isc-dhcp-4.1.1-P1/server/dhcp.c isc-dhcp-4.1.1-P1.patched//server/dhcp.c +--- isc-dhcp-4.1.1-P1/server/dhcp.c 2012-04-04 16:48:46.000000000 +0200 ++++ isc-dhcp-4.1.1-P1.patched//server/dhcp.c 2012-04-04 14:55:45.000000000 +0200 +@@ -2482,6 +2482,15 @@ + &lease -> scope, oc, MDL)) + state -> bootp_flags |= htons (BOOTP_BROADCAST); + ++ /* The inverse. */ ++ if ((oc = lookup_option (&server_universe, state -> options, ++ SV_NEVER_BROADCAST)) && ++ evaluate_boolean_option_cache (&ignorep, packet, lease, ++ (struct client_state *)0, ++ packet -> options, state -> options, ++ &lease -> scope, oc, MDL)) ++ state -> bootp_flags &= htons (~BOOTP_BROADCAST); ++ + /* Get the Maximum Message Size option from the packet, if one + was sent. */ + oc = lookup_option (&dhcp_universe, packet -> options, +diff -ur isc-dhcp-4.1.1-P1/server/dhcpd.conf.5 isc-dhcp-4.1.1-P1.patched//server/dhcpd.conf.5 +--- isc-dhcp-4.1.1-P1/server/dhcpd.conf.5 2012-04-04 16:48:46.000000000 +0200 ++++ isc-dhcp-4.1.1-P1.patched//server/dhcpd.conf.5 2012-04-04 16:45:44.000000000 +0200 +@@ -1914,6 +1914,24 @@ + .RE + .PP + The ++.I never-broadcast ++statement ++.RS 0.25i ++.PP ++.B never-broadcast \fIflag\fR\fB;\fR ++.PP ++When using DHCP in routed networks, the router has to participate in rewriting ++and sending DHCP replies on to the user. Unfortunately, some devices, ++in particular Cisco's Nexus series of switches, drop such DHCP reply packets ++with the broadcast bit in the flags field of the DHCP message header set. ++Thi means that some operating systems, in particular Microsoft Windows Vista, ++can have problems getting DHCP to work in such environments. If you enable ++this flag, the DHCP server will never set the broadcast flags in the replies ++it sends, even if the client set the broadcast flag. This flag overrides ++the never-broadcast flag if both are set. ++.RE ++.PP ++The + .I always-reply-rfc1048 + statement + .RS 0.25i +diff -ur isc-dhcp-4.1.1-P1/server/stables.c isc-dhcp-4.1.1-P1.patched//server/stables.c +--- isc-dhcp-4.1.1-P1/server/stables.c 2012-04-04 16:49:44.000000000 +0200 ++++ isc-dhcp-4.1.1-P1.patched//server/stables.c 2012-04-04 14:56:43.000000000 +0200 +@@ -203,6 +203,7 @@ + { "always-reply-rfc1048", "f", &server_universe, 20, 1 }, + { "site-option-space", "X", &server_universe, 21, 1 }, + { "always-broadcast", "f", &server_universe, 22, 1 }, ++ { "never-broadcast", "f", &server_universe, 60, 1 }, + { "ddns-domainname", "t", &server_universe, 23, 1 }, + { "ddns-hostname", "t", &server_universe, 24, 1 }, + { "ddns-rev-domainname", "t", &server_universe, 25, 1 }, diff --git a/examples/historical/patches/listen_all.git.patch b/examples/historical/patches/listen_all.git.patch new file mode 100644 index 0000000..41e1c87 --- /dev/null +++ b/examples/historical/patches/listen_all.git.patch @@ -0,0 +1,28 @@ +diff --git a/src/network/io.c b/src/network/io.c +index 7cc9764..08a0b56 100644 +--- a/src/network/io.c ++++ b/src/network/io.c +@@ -87,14 +87,15 @@ int net_Socket (vlc_object_t *p_this, int family, int socktype, + + setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof (int)); + +-#ifdef IPV6_V6ONLY +- /* +- * Accepts only IPv6 connections on IPv6 sockets. +- * If possible, we should open two sockets, but it is not always possible. +- */ +- if (family == AF_INET6) +- setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){ 1 }, sizeof (int)); +-#endif ++ // sesse fix monday night ++// #ifdef IPV6_V6ONLY ++// /* ++// * Accepts only IPv6 connections on IPv6 sockets. ++// * If possible, we should open two sockets, but it is not always possible. ++// */ ++// if (family == AF_INET6) ++// setsockopt (fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){ 1 }, sizeof (int)); ++// #endif + + #if defined (WIN32) + # ifndef IPV6_PROTECTION_LEVEL diff --git a/examples/historical/patches/vlc-git-sesse.patch b/examples/historical/patches/vlc-git-sesse.patch new file mode 100644 index 0000000..a38b378 --- /dev/null +++ b/examples/historical/patches/vlc-git-sesse.patch @@ -0,0 +1,131 @@ +diff --git a/modules/access_output/http.c b/modules/access_output/http.c +index 61095f5..18ffc9a 100644 +--- a/modules/access_output/http.c ++++ b/modules/access_output/http.c +@@ -72,9 +72,17 @@ vlc_module_begin () + PASS_TEXT, PASS_LONGTEXT, true ) + add_string( SOUT_CFG_PREFIX "mime", "", + MIME_TEXT, MIME_LONGTEXT, true ) ++ add_integer( SOUT_CFG_PREFIX "mark-start", "", ++ "lol", "Fancy option", -1 ) ++ add_integer( SOUT_CFG_PREFIX "mark-end", "", ++ "rotfl", "Should maybe also be set", -1 ) + set_callbacks( Open, Close ) + vlc_module_end () + ++// globals ++extern vlc_mutex_t mark_lock; ++extern int *mark_used; ++extern int mark_start, mark_end; + + /***************************************************************************** + * Exported prototypes +@@ -178,6 +186,21 @@ static int Open( vlc_object_t *p_this ) + return VLC_EGENERIC; + } + ++ fprintf(stderr, "tjobing\n"); ++ if (mark_used == NULL) { ++ mark_start = var_InheritInteger( p_access, SOUT_CFG_PREFIX "mark-start"); ++ mark_end = var_InheritInteger( p_access, SOUT_CFG_PREFIX "mark-end"); ++ fprintf(stderr, "jabla: %d -> %d\n", mark_start, mark_end); ++ ++ if (mark_start >= 0 && mark_end > mark_start) { ++ vlc_mutex_init(&mark_lock); ++ mark_used = (int *)malloc((mark_end - mark_start) * sizeof(int)); ++ for (int i = 0; i < mark_end - mark_start; ++i) { ++ mark_used[i] = 0; ++ } ++ } ++ } ++ + psz_user = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "user" ); + psz_pwd = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "pwd" ); + if( p_access->psz_access && !strcmp( p_access->psz_access, "mmsh" ) ) +diff --git a/src/libvlccore.sym b/src/libvlccore.sym +index 25d83c5..335edda 100644 +--- a/src/libvlccore.sym ++++ b/src/libvlccore.sym +@@ -631,3 +631,7 @@ xml_ReaderDelete + xml_ReaderReset + vlc_keycode2str + vlc_str2keycode ++mark_end ++mark_lock ++mark_start ++mark_used +diff --git a/src/network/httpd.c b/src/network/httpd.c +index f76c47c..d7897bb 100644 +--- a/src/network/httpd.c ++++ b/src/network/httpd.c +@@ -67,6 +67,50 @@ + + static void httpd_ClientClean( httpd_client_t *cl ); + ++VLC_API vlc_mutex_t mark_lock; ++VLC_API int *mark_used = NULL; ++VLC_API int mark_start = -1; ++VLC_API int mark_end = -1; ++ ++void mark_socket(int fd) ++{ ++ vlc_mutex_lock(&mark_lock); ++ int best_mark = mark_start; ++ int best_mark_val = mark_used[0]; ++ ++ for (int i = 1; i < mark_end - mark_start; ++i) { ++ if (mark_used[i] < best_mark_val) { ++ best_mark = mark_start + i; ++ best_mark_val = mark_used[i]; ++ } ++ } ++ fprintf( stderr, "PICKED MARK %d WITH OLD USAGE %d\n", best_mark, best_mark_val); ++ if (setsockopt (fd, SOL_SOCKET, SO_MARK, &best_mark, sizeof(best_mark)) == -1) { ++ perror("setsockopt(SO_MARK)"); ++ } else { ++ ++mark_used[best_mark - mark_start]; ++ } ++ vlc_mutex_unlock(&mark_lock); ++} ++ ++void unmark_socket(int fd) ++{ ++ int mark; ++ socklen_t mark_len = sizeof(mark); ++ if (getsockopt (fd, SOL_SOCKET, SO_MARK, &mark, &mark_len) == -1) { ++ perror("getsockopt(SO_MARK)"); ++ return; ++ } ++ if (mark < mark_start || mark >= mark_end) { ++ fprintf("UNKNOWN MARK %d\n", mark); ++ } ++ ++ vlc_mutex_lock(&mark_lock); ++ --mark_used[mark - mark_start]; ++ fprintf(stderr, "UNMARKED MARK %d WITH NEW USAGE %d\n", mark, mark_used[mark - mark_start]); ++ vlc_mutex_unlock(&mark_lock); ++} ++ + /* each host run in his own thread */ + struct httpd_host_t + { +@@ -1295,6 +1339,7 @@ static void httpd_ClientClean( httpd_client_t *cl ) + { + if( cl->p_tls != NULL ) + vlc_tls_SessionDelete( cl->p_tls ); ++ unmark_socket( cl->fd ); + net_Close( cl->fd ); + cl->fd = -1; + } +@@ -2309,6 +2354,11 @@ static void* httpd_HostThread( void *data ) + setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, + &(int){ 1 }, sizeof(int)); + ++ // find a free mark ++ if (mark_used != NULL) { ++ mark_socket(fd); ++ } ++ + vlc_tls_t *p_tls; + + if( host->p_tls != NULL ) diff --git a/examples/historical/patches/vlc-mark.patch b/examples/historical/patches/vlc-mark.patch new file mode 100644 index 0000000..877b78c --- /dev/null +++ b/examples/historical/patches/vlc-mark.patch @@ -0,0 +1,136 @@ +diff -ur vlc-2.0.5/modules/access_output/http.c vlc-2.0.5.patchde/modules/access_output/http.c +--- vlc-2.0.5/modules/access_output/http.c 2011-12-22 11:38:28.000000000 +0100 ++++ vlc-2.0.5.patchde/modules/access_output/http.c 2013-02-07 01:23:10.966721881 +0100 +@@ -89,9 +89,17 @@ + add_bool( SOUT_CFG_PREFIX "bonjour", false, + BONJOUR_TEXT, BONJOUR_LONGTEXT, true); + #endif ++ add_integer( SOUT_CFG_PREFIX "mark-start", "", ++ "lol", "Fancy option", -1 ) ++ add_integer( SOUT_CFG_PREFIX "mark-end", "", ++ "rotfl", "Should maybe also be set", -1 ) + set_callbacks( Open, Close ) + vlc_module_end () + ++// globals ++extern vlc_mutex_t mark_lock; ++extern int *mark_used; ++extern int mark_start, mark_end; + + /***************************************************************************** + * Exported prototypes +@@ -199,6 +207,21 @@ + return VLC_EGENERIC; + } + ++ fprintf(stderr, "tjobing\n"); ++ if (mark_used == NULL) { ++ mark_start = var_InheritInteger( p_access, SOUT_CFG_PREFIX "mark-start"); ++ mark_end = var_InheritInteger( p_access, SOUT_CFG_PREFIX "mark-end"); ++ fprintf(stderr, "jabla: %d -> %d\n", mark_start, mark_end); ++ ++ if (mark_start >= 0 && mark_end > mark_start) { ++ vlc_mutex_init(&mark_lock); ++ mark_used = (int *)malloc((mark_end - mark_start) * sizeof(int)); ++ for (int i = 0; i < mark_end - mark_start; ++i) { ++ mark_used[i] = 0; ++ } ++ } ++ } ++ + psz_user = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "user" ); + psz_pwd = var_GetNonEmptyString( p_access, SOUT_CFG_PREFIX "pwd" ); + if( p_access->psz_access && !strcmp( p_access->psz_access, "mmsh" ) ) +diff -ur vlc-2.0.5/src/libvlccore.sym vlc-2.0.5.patchde/src/libvlccore.sym +--- vlc-2.0.5/src/libvlccore.sym 2012-05-15 14:41:19.000000000 +0200 ++++ vlc-2.0.5.patchde/src/libvlccore.sym 2013-02-07 01:16:16.917330547 +0100 +@@ -673,3 +673,7 @@ + xml_ReaderReset + vlc_keycode2str + vlc_str2keycode ++mark_end ++mark_lock ++mark_start ++mark_used +diff -ur vlc-2.0.5/src/network/httpd.c vlc-2.0.5.patchde/src/network/httpd.c +--- vlc-2.0.5/src/network/httpd.c 2012-09-04 00:14:53.000000000 +0200 ++++ vlc-2.0.5.patchde/src/network/httpd.c 2013-02-07 01:35:50.777081814 +0100 +@@ -69,6 +69,50 @@ + + static void httpd_ClientClean( httpd_client_t *cl ); + ++VLC_API vlc_mutex_t mark_lock; ++VLC_API int *mark_used = NULL; ++VLC_API int mark_start = -1; ++VLC_API int mark_end = -1; ++ ++void mark_socket(int fd) ++{ ++ vlc_mutex_lock(&mark_lock); ++ int best_mark = mark_start; ++ int best_mark_val = mark_used[0]; ++ ++ for (int i = 1; i < mark_end - mark_start; ++i) { ++ if (mark_used[i] < best_mark_val) { ++ best_mark = mark_start + i; ++ best_mark_val = mark_used[i]; ++ } ++ } ++ fprintf( stderr, "PICKED MARK %d WITH OLD USAGE %d\n", best_mark, best_mark_val); ++ if (setsockopt (fd, SOL_SOCKET, SO_MARK, &best_mark, sizeof(best_mark)) == -1) { ++ perror("setsockopt(SO_MARK)"); ++ } else { ++ ++mark_used[best_mark - mark_start]; ++ } ++ vlc_mutex_unlock(&mark_lock); ++} ++ ++void unmark_socket(int fd) ++{ ++ int mark; ++ socklen_t mark_len = sizeof(mark); ++ if (getsockopt (fd, SOL_SOCKET, SO_MARK, &mark, &mark_len) == -1) { ++ perror("getsockopt(SO_MARK)"); ++ return; ++ } ++ if (mark < mark_start || mark >= mark_end) { ++ fprintf("UNKNOWN MARK %d\n", mark); ++ } ++ ++ vlc_mutex_lock(&mark_lock); ++ --mark_used[mark - mark_start]; ++ fprintf(stderr, "UNMARKED MARK %d WITH NEW USAGE %d\n", mark, mark_used[mark - mark_start]); ++ vlc_mutex_unlock(&mark_lock); ++} ++ + /* each host run in his own thread */ + struct httpd_host_t + { +@@ -1412,6 +1456,7 @@ + { + if( cl->p_tls != NULL ) + vlc_tls_ServerSessionDelete( cl->p_tls ); ++ unmark_socket( cl->fd ); + net_Close( cl->fd ); + cl->fd = -1; + } +@@ -2461,6 +2506,11 @@ + setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, + &(int){ 1 }, sizeof(int)); + ++ // find a free mark ++ if (mark_used != NULL) { ++ mark_socket(fd); ++ } ++ + vlc_tls_t *p_tls; + + if( host->p_tls != NULL ) +@@ -2471,6 +2521,7 @@ + case -1: + msg_Err( host, "Rejecting TLS connection" ); + /* p_tls is destroyed implicitly */ ++ unmark_socket( fd ); + net_Close( fd ); + fd = -1; + p_tls = NULL; diff --git a/examples/historical/stream-stuff/encode/kliniskarbeidsflate/reflect-krosus.sh b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/reflect-krosus.sh new file mode 100755 index 0000000..a40500c --- /dev/null +++ b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/reflect-krosus.sh @@ -0,0 +1,4 @@ +#!/bin/sh +while :; do vlc -vvv udp://@:9017 --network-caching 2000 --no-sout-audio --sout '#std{access=udp,mux=ts,dst=151.216.125.4:4016}' --intf dummy --ttl 60 vlc://quit; + sleep 5 +done diff --git a/examples/historical/stream-stuff/encode/kliniskarbeidsflate/reflect.sh b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/reflect.sh new file mode 100755 index 0000000..7419433 --- /dev/null +++ b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/reflect.sh @@ -0,0 +1,4 @@ +#!/bin/sh +while :; do vlc -vvv rtsp://151.216.106.2:554/live1.sdp --network-caching 2000 --no-sout-audio --sout '#std{access=udp,mux=ts,dst=127.0.0.1:9017}' --intf dummy --ttl 60 vlc://quit; + sleep 5 +done diff --git a/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-event-sd.sh b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-event-sd.sh new file mode 100755 index 0000000..fb5c055 --- /dev/null +++ b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-event-sd.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +while :; do +cvlc -vv udp://@:4014 --network-caching 2000 --sout-x264-preset fast --sout-x264-tune film --sout-transcode-threads 22 --no-sout-x264-interlaced --sout-x264-keyint 50 --sout-x264-lookahead 100 \ +--sout '#transcode{height=576,vcodec=h264,vb=2000,acodec=mp4a,aenc=fdkaac,ab=128}:std{access=udp,mux=ts,dst=151.216.125.4:4014}' +sleep 1 +done diff --git a/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-fugle-flash.sh b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-fugle-flash.sh new file mode 100755 index 0000000..a924de2 --- /dev/null +++ b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-fugle-flash.sh @@ -0,0 +1,7 @@ +#!/bin/sh +while :; do +cvlc -vv --network-caching 3000 --sout-x264-preset fast --sout-transcode-threads 10 --sout-x264-tune film --no-sout-x264-interlaced --sout-x264-lookahead 50 --sout-x264-vbv-maxrate 800 --sout-x264-vbv-bufsize 800 --sout-x264-keyint 50 -v http://stream.tg13.gathering.org:3015 vlc://quit \ +--sout '#transcode{height=480,fps=25,vcodec=h264,vb=800,acodec=aac,ab=128,deinterlace}:std{access=udp,mux=ffmpeg{mux=flv},dst=151.216.125.4:4020}' + sleep 1 +done + diff --git a/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-noc-fisheye-flash.sh b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-noc-fisheye-flash.sh new file mode 100755 index 0000000..3491232 --- /dev/null +++ b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-noc-fisheye-flash.sh @@ -0,0 +1,6 @@ +#!/bin/sh +while :; do +cvlc -vv --network-caching 5000 --sout-x264-preset fast --sout-transcode-threads 16 --sout-x264-tune film --no-sout-x264-interlaced --sout-x264-lookahead 50 --sout-x264-vbv-maxrate 800 --sout-x264-vbv-bufsize 800 --sout-x264-keyint 50 -v http://stream.tg13.gathering.org:3018 vlc://quit \ +--sout '#transcode{width=768,height=768,vcodec=h264,vb=800}:std{access=udp,mux=ts,dst=151.216.125.4:4019}' + sleep 1 +done diff --git a/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-south.sh b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-south.sh new file mode 100755 index 0000000..d5a83e4 --- /dev/null +++ b/examples/historical/stream-stuff/encode/kliniskarbeidsflate/transcode-south.sh @@ -0,0 +1,9 @@ +#!/bin/sh +while :; do cvlc -vv udp://@:9017 \ + --sout-ts-shaping=1000 --sout-ts-use-key-frames --sout-ts-dts-delay=500 --sout-transcode-fps 0 --no-sout-transcode-audio-sync --network-caching 2000 \ + --no-sout-x264-interlaced --sout-x264-preset veryfast --sout-x264-tune film \ + --sout-transcode-threads 3 --sout-x264-keyint 25 --no-sout-audio \ + --sout '#duplicate{dst="transcode{vcodec=h264,height=720,vb=3000}:std{access=udp,mux=ts,dst=151.216.125.4:4017}",dst="std{access=udp,mux=ts,dst=151.216.125.4:4016}"}' \ + --intf dummy --ttl 20 vlc://quit; + sleep 1 +done diff --git a/examples/historical/stream-stuff/encode/politietno/foo-withoutreflect.sh b/examples/historical/stream-stuff/encode/politietno/foo-withoutreflect.sh new file mode 100755 index 0000000..21bcda6 --- /dev/null +++ b/examples/historical/stream-stuff/encode/politietno/foo-withoutreflect.sh @@ -0,0 +1,6 @@ +#!/bin/sh +/home/techserver/vlc/vlc -I dummy -vvvv --decklink-audio-connection embedded --live-caching 3000 --decklink-aspect-ratio 16:9 --decklink-mode hp50 \ + --sout-x264-preset slow --sout-x264-tune film --sout-transcode-threads 23 --no-sout-x264-interlaced \ + --sout-x264-keyint 50 --sout-x264-lookahead 100 --sout-x264-vbv-maxrate 5000 --sout-x264-vbv-bufsize 5000 \ + -v decklink:// vlc://quit \ + --sout '#transcode{vcodec=h264,vb=3000,acodec=mp4a,aenc=fdkaac,ab=256}:std{access=udp,mux=ts,dst=151.216.124.80:9094}' diff --git a/examples/historical/stream-stuff/encode/politietno/foo.sh b/examples/historical/stream-stuff/encode/politietno/foo.sh new file mode 100755 index 0000000..dfdfc03 --- /dev/null +++ b/examples/historical/stream-stuff/encode/politietno/foo.sh @@ -0,0 +1,6 @@ +#!/bin/sh +/home/techserver/vlc/vlc -I dummy -vvvv --decklink-audio-connection embedded --live-caching 3000 --decklink-aspect-ratio 16:9 --decklink-mode hp50 \ + --sout-x264-preset slow --sout-x264-tune film --sout-transcode-threads 23 --no-sout-x264-interlaced \ + --sout-x264-keyint 50 --sout-x264-lookahead 100 --sout-x264-vbv-maxrate 5000 --sout-x264-vbv-bufsize 5000 \ + -v decklink:// vlc://quit \ + --sout '#transcode{vcodec=h264,vb=3000,acodec=mp4a,aenc=fdkaac,ab=256}:std{access=udp,mux=ts,dst=151.216.125.4:4013}' diff --git a/examples/historical/stream-stuff/encode/politietno/svineri.sh b/examples/historical/stream-stuff/encode/politietno/svineri.sh new file mode 100755 index 0000000..ac09601 --- /dev/null +++ b/examples/historical/stream-stuff/encode/politietno/svineri.sh @@ -0,0 +1,24 @@ +~/decklink-sdk/Linux/Samples/bmdtools/bmdcapture $( + echo '-C 0' # Decklink card number + echo '-m 11' # Input format mode (ID 8 = 1080i/25) + echo '-V 4' # Video input (4 = SDI) + echo '-A 2' # Audio input (2 = Embedded) + echo '-c 2' # Number of audio channels + echo '-M 10' # Memory limit, in GB, for the output buffer (it leaks slightly...) + echo '-F nut -f pipe:1' # Output format and file name +) | \ +ffmpeg $( + echo '-y -re -i -' # Input from pipe + echo '-v verbose' # Verbosity level +# echo '-filter:v format=yuv420p,yadif=1:0:0' # Video format conversion and deinterlacing + echo '-filter:v scale=480x270' + echo '-c:v libx264' # Video encoder to use + echo '-tune film -preset slow' # Video encoder options + echo '-x264opts keyint=50:rc-lookahead=0' # x264-specific options +# echo '-b:v 1M' # Video bitrate + echo '-c:a libfaac' # Audio encoder to use + echo '-b:a 192k' # Audio bitrate + echo '-threads auto' # Number of threads to use + echo '-f mpegts udp://151.216.125.4:4013' # Output format and file name +) + diff --git a/examples/historical/stream-stuff/encode/politietno/transcode-duplicate.sh b/examples/historical/stream-stuff/encode/politietno/transcode-duplicate.sh new file mode 100755 index 0000000..591e529 --- /dev/null +++ b/examples/historical/stream-stuff/encode/politietno/transcode-duplicate.sh @@ -0,0 +1,7 @@ +#!/bin/sh +while :; do +cvlc -vv --decklink-audio-connection embedded --live-caching 2000 --decklink-aspect-ratio 16:9 --decklink-mode hp50 \ + --sout-x264-preset fast --sout-x264-tune film --sout-transcode-threads 24 --no-sout-x264-interlaced --sout-x264-keyint 50 --sout-x264-lookahead 100 --sout-x264-vbv-maxrate 4000 --sout-x264-vbv-bufsize 4000 decklink:// vlc://quit \ + --sout '#duplicate{dst="transcode{vcodec=h264,vb=6000,acodec=mp4a,aenc=fdkaac,ab=256}:std{access=udp,mux=ts,dst=151.216.125.4:4013}",dst="transcode{height=576,vcodec=h264,vb=2000,acodec=mp4a,aenc=fdkaac,ab=128}:std{access=udp,mux=ts,dst=151.216.125.4:4014}"}' +sleep 1 +done diff --git a/examples/historical/stream-stuff/encode/politietno/transcode-duplicate2.sh b/examples/historical/stream-stuff/encode/politietno/transcode-duplicate2.sh new file mode 100755 index 0000000..6b85d1d --- /dev/null +++ b/examples/historical/stream-stuff/encode/politietno/transcode-duplicate2.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# event signal: +# transcode hd and move to reflector +# mirror signal to encoder2 (kliniskarbeidsflate) and transcode sd -> reflector +while :; do +cvlc -vv --decklink-audio-connection embedded --live-caching 2000 --decklink-aspect-ratio 16:9 --decklink-mode hp50 \ + --sout-x264-preset fast --sout-x264-tune film --sout-transcode-threads 22 --no-sout-x264-interlaced --sout-x264-keyint 50 --sout-x264-lookahead 100 decklink:// vlc://quit \ + --sout '#duplicate{dst="transcode{vcodec=h264,vb=6000,acodec=mp4a,aenc=fdkaac,ab=256}:std{access=udp,mux=ts,dst=151.216.125.4:4013}",dst="std{access=udp,mux=ts,dst=151.216.125.9:4014}"}' +sleep 1 +done diff --git a/examples/historical/stream-stuff/encode/politietno/transcode.sh b/examples/historical/stream-stuff/encode/politietno/transcode.sh new file mode 100755 index 0000000..a4feda9 --- /dev/null +++ b/examples/historical/stream-stuff/encode/politietno/transcode.sh @@ -0,0 +1,6 @@ +#!/bin/sh +cvlc -I dummy -vvvv --decklink-audio-connection embedded --live-caching 2000 --decklink-aspect-ratio 16:9 --decklink-mode hp50 \ + --sout-x264-preset slow --sout-x264-tune film --sout-transcode-threads 23 --no-sout-x264-interlaced \ + --sout-x264-keyint 50 --sout-x264-lookahead 100 --sout-x264-vbv-maxrate 6000 --sout-x264-vbv-bufsize 6000 \ + -v decklink:// vlc://quit \ + --sout '#transcode{vcodec=h264,vb=6000,acodec=mp4a,aenc=fdkaac,ab=256}:std{access=udp,mux=ts,dst=151.216.125.4:4013}' diff --git a/examples/historical/stream-stuff/encode/politietno/vid.sh b/examples/historical/stream-stuff/encode/politietno/vid.sh new file mode 100755 index 0000000..8c5bcba --- /dev/null +++ b/examples/historical/stream-stuff/encode/politietno/vid.sh @@ -0,0 +1,7 @@ +#!/bin/sh +# VLC for box connected to broadcast-equipment Blackmagic/Decklink: Audio and Video from SDI Transcodes HD and sends via UDP to reflector - Marius / Tech:Server +while :; do cvlc -vv --no-decklink-tenbits --decklink-audio-connection embedded --live-caching 1800 --decklink-aspect-ratio 16:9 --decklink-mode hp50 \ + --sout-x264-preset medium --sout-x264-tune film --sout-transcode-threads 15 --no-sout-x264-interlaced --sout-x264-keyint 100 --sout-x264-lookahead 50 --sout-x264-vbv-maxrate 7000 --sout-x264-vbv-bufsize 7000 -v decklink:// vlc://quit \ + --sout '#transcode{vcodec=h264,vb=3000,acodec=mp3,ab=256}:std{access=udp,mux=ts,dst=151.216.125.4:4013}' + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/count-retrofit.sh b/examples/historical/stream-stuff/reflect/count-retrofit.sh new file mode 100755 index 0000000..1ff8c30 --- /dev/null +++ b/examples/historical/stream-stuff/reflect/count-retrofit.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +while :; do + date=$(date +"%Y-%m-%d-%H:%M:%S") + #( lsof -n | grep vlc ; ssh root@gaffeltruck.tg12.gathering.org 'lsof -n | grep vlc' ) > /var/log/stream-count/$date + sudo lsof -n | grep vlc > /var/log/stream-count/$date + for PORT in 3013 3014 3015 3016 3017 3018 3019 5013 5015 5019; do + for PROTO in IPv4 IPv6; do + if [ "$PROTO" = "IPv4" ]; then + GREPFOR='151\.216' + else + GREPFOR='2a02:ed02:' + fi + + # 151.216.x.x / 2a02:ed02::/32 -> TG13 + cat /var/log/stream-count/$date | grep EST | egrep $GREPFOR | egrep "(151\.216\..*|2a02:ed02:.*):$PORT->" | cut -d'>' -f2 | sed 's/:[0-9]\+ (ESTABLISHED)//' | sort -u | grep -vEc -e "\[2a02:ed02:|151\.216\." | while read foo; do echo "$date $PORT $PROTO external $foo"; done | tee -a better_datacube.log + cat /var/log/stream-count/$date | grep EST | egrep $GREPFOR | egrep "(151\.216\..*|2a02:ed02:.*):$PORT->" | cut -d'>' -f2 | sed 's/:[0-9]\+ (ESTABLISHED)//' | sort -u | grep -Ec -e "\[2a02:ed02:|151\.216\." | while read foo; do echo "$date $PORT $PROTO internal $foo"; done | tee -a better_datacube.log + done + done + sleep 60 +done; + diff --git a/examples/historical/stream-stuff/reflect/count.sh b/examples/historical/stream-stuff/reflect/count.sh new file mode 100755 index 0000000..e1fa38c --- /dev/null +++ b/examples/historical/stream-stuff/reflect/count.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +while :; do + date=$(date +"%Y-%m-%d-%H:%M:%S") + #( lsof -n | grep vlc ; ssh root@gaffeltruck.tg12.gathering.org 'lsof -n | grep vlc' ) > /var/log/stream-count/$date + sudo lsof -n | grep vlc > /var/log/stream-count/$date + for PORT in 3013 3014 3015 3016 3017 3018 3019 5013 5015 5019; do + for PROTO in IPv4 IPv6; do + if [ "$PROTO" = "IPv4" ]; then + GREPFOR='151\.216' + else + GREPFOR='2a02:ed02:' + fi + + # 151.216.x.x / 2a02:ed02::/32 -> TG13 + cat /var/log/stream-count/$date | grep EST | egrep $GREPFOR | egrep "(151\.216\..*|2a02:ed02:.*):$PORT->" | cut -d'>' -f2 | sed 's/:[0-9]\+ (ESTABLISHED)//' | sort -u | grep -vEc -e "\[2a02:ed02:|151\.216\." | while read foo; do echo "$date $PORT $PROTO external $foo"; done | tee -a count_datacube.log + cat /var/log/stream-count/$date | grep EST | egrep $GREPFOR | egrep "(151\.216\..*|2a02:ed02:.*):$PORT->" | cut -d'>' -f2 | sed 's/:[0-9]\+ (ESTABLISHED)//' | sort -u | grep -Ec -e "\[2a02:ed02:|151\.216\." | while read foo; do echo "$date $PORT $PROTO internal $foo"; done | tee -a count_datacube.log + done + done + sleep 60 +done; + diff --git a/examples/historical/stream-stuff/reflect/htb.sh b/examples/historical/stream-stuff/reflect/htb.sh new file mode 100755 index 0000000..c6107ea --- /dev/null +++ b/examples/historical/stream-stuff/reflect/htb.sh @@ -0,0 +1,79 @@ +#!/bin/bash +it () { + iptables $@ + ip6tables $@ +} + +setup_htb() { + FROM=$1 + TO=$2 + RATEMBIT=$3 + FIFOLIMIT=$(( RATEMBIT * 1048576 / 8 )) # about one second + echo $FROM..$TO ${RATEMBIT}Mbit fifolimit=$FIFOLIMIT >&2 + + for i in $( seq $FROM $TO ); do + # slots need to be in hex, crazy enough + slot=$( printf %x $(( i + 1 )) ) + + # no burst! perfectly even sending at the given rate + echo class add dev eth0 parent 8000: classid 8000:$slot htb rate ${RATEMBIT}Mbit burst 0 mtu 576 + + # every class needs a child qdisc, plug in a plain fifo + # 8000kbit = 512 000 + echo qdisc add dev eth0 parent 8000:$slot handle $slot: bfifo limit $FIFOLIMIT + #echo qdisc add dev eth0 parent 8000:$slot handle $slot: fq_codel limit 1000 + done +} + +ethtool -K eth0 gso off tso off + +# iptables stuff +it -t mangle -F OUTPUT +it -t mangle -A OUTPUT -p tcp -m multiport ! --sport 3013,3014,3015,3016,3017,3018,5013,5015,5016,5018 -j MARK --set-mark 65000 +it -t mangle -A OUTPUT ! -p tcp -j MARK --set-mark 65000 + +( + # reset tc + echo qdisc del dev eth0 root + + # @Sesse Rockj: https://www.google.com/search?q=6000+kbit%2Fsec+*+0.5+seconds+in+byte + # @Sesse ViD: også trenger du flere sett med køer, for 2mbit-strømmer burde shapes annerledes enn 5mbit-strømmer :-P + + # root qdisc should be htb + echo qdisc add dev eth0 root handle 8000: htb r2q 100 + + # all non-vlc traffic (fwmark 5) goes into the default class + echo class add dev eth0 parent 8000: classid 8000:1 htb rate 10Gbit burst 8192 mtu 1514 + echo filter add dev eth0 parent 8000: handle 65000 pref 10 fw classid 8000:1 + + # setup_htb 1 799 6 # Main stream hq 3mbps + # setup_htb 800 1000 15 # Fuglecam raw 7-8mbps + # # setup_htb 10000 11999 15 # South raw ?? + # # setup_htb 12000 13999 1 # South transcoded, 500 kbits + # # setup_htb 14000 15999 25 # NOC Fisheye 15mbps ish + # # setup_htb 20000 21999 2 # Flashstrøm 1mbps + + # setup_htb 1 4999 10 # Main stream hq 6mbps + # setup_htb 5000 7999 5 # Main stream sd 2mbit + # setup_htb 8000 9999 15 # Fuglecam raw 7-8mbps + # setup_htb 10000 11999 15 # South raw ?? + # setup_htb 12000 13999 1 # South transcoded, 500 kbits + # setup_htb 14000 15999 25 # NOC Fisheye 15mbps ish + # setup_htb 16000 18999 2 # Flashstrøm fugleberget 1mbps + # setup_htb 19000 21999 2 # Flashstrøm event 1mbps + # setup_htb 22000 24999 2 # Flashstrøm south 1mbps + # setup_htb 25000 27999 2 # Flashstrøm noc 1mbps + setup_htb 1 4999 10 # Main stream hq 6mbps + setup_htb 5000 5999 5 # Main stream sd 2mbit + setup_htb 8000 9999 15 # Fuglecam raw 7-8mbps + setup_htb 10000 11999 15 # South raw ?? + setup_htb 12000 13999 1 # South transcoded, 500 kbits + setup_htb 14000 15999 25 # NOC Fisheye 15mbps ish + setup_htb 16000 18999 2 # Flashstrøm fugleberget 1mbps + setup_htb 19000 21999 2 # Flashstrøm event 1mbps + setup_htb 22000 24999 2 # Flashstrøm south 1mbps + setup_htb 25000 25999 2 # Flashstrøm noc 1mbps + + # decide between the classes by mark + echo filter add dev eth0 parent 8000: handle 2 pref 20 flow map key mark baseclass 8000:2 +) | tc -b diff --git a/examples/historical/stream-stuff/reflect/old/reflectsouth.sh b/examples/historical/stream-stuff/reflect/old/reflectsouth.sh new file mode 100755 index 0000000..39504e5 --- /dev/null +++ b/examples/historical/stream-stuff/reflect/old/reflectsouth.sh @@ -0,0 +1,5 @@ +#!/bin/sh +while :; do +vlc --intf dummy -v http://pannekake.samfundet.no:9094 vlc://quit --sout '#duplicate{dst=std{access=http,mux=ts,dst=:3014},dst=std{access=udp,mux=ts,dst=233.191.12.2:2014}' --intf dummy --ttl 20 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/old/reflectsouth720p.sh b/examples/historical/stream-stuff/reflect/old/reflectsouth720p.sh new file mode 100755 index 0000000..355cf8e --- /dev/null +++ b/examples/historical/stream-stuff/reflect/old/reflectsouth720p.sh @@ -0,0 +1,6 @@ +#!/bin/sh +while :; do +cvlc --intf dummy -v "#transcode{vcodec=h264,width=320,height=180,acodec=aac,ab=128,vb=500}:rtp{port=4555,sdp=rtsp://151.216.106.2:4555/stream.sdp,mp4a-latm}" +vlc --intf dummy -v http://pannekake.samfundet.no:9093 vlc://quit --sout '#std{access=http,mux=ts,dst=:5014}' --intf dummy --ttl 30 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/reflect-event-lol.sh b/examples/historical/stream-stuff/reflect/reflect-event-lol.sh new file mode 100755 index 0000000..74dbea6 --- /dev/null +++ b/examples/historical/stream-stuff/reflect/reflect-event-lol.sh @@ -0,0 +1,7 @@ +#!/bin/sh +while :; do +sudo cvlc --intf dummy -v --sout-http-mark-start 0 --sout-http-mark-end 4999 udp://@:4013 vlc://quit --sout \ +'#duplicate{dst=std{access=http,mux=ts,dst=[::]:3013}",dst=std{access=udp,mux=ts,dst=[ff7e:a40:2a02:ed02:ffff::13]:2013},dst=std{access=livehttp{seglen=5,delsegs=true,numsegs=5,index=/srv/stream.tg13.gathering.org/ios/event.m3u8,index-url=http://stream.tg13.gathering.org/ios/event-########.ts},mux=ts{use-key-frames},dst=/srv/stream.tg13.gathering.org/ios/event-########.ts}}}' \ +--intf dummy --ttl 60 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/reflect-event-sd.sh b/examples/historical/stream-stuff/reflect/reflect-event-sd.sh new file mode 100755 index 0000000..aa38018 --- /dev/null +++ b/examples/historical/stream-stuff/reflect/reflect-event-sd.sh @@ -0,0 +1,5 @@ +#!/bin/sh +while :; do +sudo cvlc --intf dummy -v --sout-http-mark-start 5000 --sout-http-mark-end 7999 udp://@:4014 vlc://quit --sout '#duplicate{dst=std{access=http,mux=ts,dst=[::]:3014},dst=std{access=udp,mux=ts,dst=[ff7e:a40:2a02:ed02:ffff::14]:2014}' --intf dummy --ttl 60 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/reflect-event.sh b/examples/historical/stream-stuff/reflect/reflect-event.sh new file mode 100755 index 0000000..3ab8c42 --- /dev/null +++ b/examples/historical/stream-stuff/reflect/reflect-event.sh @@ -0,0 +1,7 @@ +#!/bin/sh +while :; do +sudo cvlc --intf dummy -v --sout-http-mark-start 0 --sout-http-mark-end 4999 udp://@:4013 vlc://quit --sout \ +'#duplicate{dst=std{access=http,mux=ts,dst=[::]:3013}",dst=std{access=udp,mux=ts,dst=[ff7e:a40:2a02:ed02:ffff::13]:2013},dst=std{access=livehttp{seglen=5,delsegs=true,numsegs=5,index=/srv/stream.tg13.gathering.org/ios/stream.m3u8,index-url=http://stream.tg13.gathering.org/ios/stream-########.ts},mux=ts{use-key-frames},dst=/srv/stream.tg13.gathering.org/ios/stream-########.ts}}}' \ +--intf dummy --ttl 60 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/reflect-fugle-flash.sh b/examples/historical/stream-stuff/reflect/reflect-fugle-flash.sh new file mode 100755 index 0000000..5de38bb --- /dev/null +++ b/examples/historical/stream-stuff/reflect/reflect-fugle-flash.sh @@ -0,0 +1,6 @@ +#!/bin/sh +while :; do +sudo cvlc -vv --sout-http-mark-start 16000 --sout-http-mark-end 18999 --network-caching 3000 --sout-x264-preset fast --sout-transcode-threads 10 --sout-x264-tune film --no-sout-x264-interlaced --sout-x264-lookahead 50 --sout-x264-vbv-maxrate 800 --sout-x264-vbv-bufsize 800 --sout-x264-keyint 50 -v udp://@:4020 vlc://quit \ +--sout '#std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=[::]:5015/stream.flv}' + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/reflect-fuglecam.sh b/examples/historical/stream-stuff/reflect/reflect-fuglecam.sh new file mode 100755 index 0000000..c9a8917 --- /dev/null +++ b/examples/historical/stream-stuff/reflect/reflect-fuglecam.sh @@ -0,0 +1,5 @@ +#!/bin/bash +while :; do +sudo vlc -vvv --intf dummy -v --sout-http-mark-start 8000 --sout-http-mark-end 9999 udp://@:4015 vlc://quit --sout '#duplicate{dst=std{access=http,mux=ts,dst=[::]:3015},dst=std{access=udp,mux=ts,dst=[ff7e:a40:2a02:ed02:ffff::15]:2015}' --intf dummy --ttl 60 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/reflect-nicfisheye-flash.sh b/examples/historical/stream-stuff/reflect/reflect-nicfisheye-flash.sh new file mode 100755 index 0000000..dd4da84 --- /dev/null +++ b/examples/historical/stream-stuff/reflect/reflect-nicfisheye-flash.sh @@ -0,0 +1,5 @@ +#!/bin/bash +while :; do +sudo vlc -vvv --intf dummy -v --sout-http-mark-start 25000 --sout-http-mark-end 27999 udp://@:4018 vlc://quit --sout '#duplicate{dst=std{access=http,mux=ts,dst=[::]:3018},dst=std{access=udp,mux=ts,dst=[ff7e:a40:2a02:ed02:ffff::18]:2018}' --intf dummy --ttl 60 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/reflect-noc-transcodes.sh b/examples/historical/stream-stuff/reflect/reflect-noc-transcodes.sh new file mode 100755 index 0000000..3a1fe4e --- /dev/null +++ b/examples/historical/stream-stuff/reflect/reflect-noc-transcodes.sh @@ -0,0 +1,5 @@ +#!/bin/sh +while :; do +sudo cvlc -vvv --intf dummy -v --sout-http-mark-start 25000 --sout-http-mark-end 27999 udp://@:4019 vlc://quit --sout '#duplicate{dst="std{access=http{mime=video/x-flv},dst=[::]:5019/stream.flv}",dst="std{access=http,mux=ts,dst=[::]:3019}",dst="std{access=udp,mux=ts,dst=[ff7e:a40:2a02:ed02:ffff::19]:2019}"}' --intf dummy --ttl 60 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/reflect-nocfisheye.sh b/examples/historical/stream-stuff/reflect/reflect-nocfisheye.sh new file mode 100755 index 0000000..6a003f4 --- /dev/null +++ b/examples/historical/stream-stuff/reflect/reflect-nocfisheye.sh @@ -0,0 +1,5 @@ +#!/bin/sh +while :; do +sudo cvlc -vvv --intf dummy -v --sout-http-mark-start 14000 --sout-http-mark-end 15999 --network-caching 2000 rtsp://151.216.124.79/live.sdp vlc://quit --sout '#duplicate{dst=std{access=http,mux=ts,dst=[::]:3018},dst=std{access=udp,mux=ts,dst=[ff7e:a40:2a02:ed02:ffff::18]:2018}' --intf dummy --ttl 60 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/reflect-south-raw.sh b/examples/historical/stream-stuff/reflect/reflect-south-raw.sh new file mode 100755 index 0000000..720e94c --- /dev/null +++ b/examples/historical/stream-stuff/reflect/reflect-south-raw.sh @@ -0,0 +1,5 @@ +#!/bin/sh +while :; do +sudo cvlc -vvv --intf dummy -v --sout-http-mark-start 10000 --sout-http-mark-end 11999 udp://@151.216.125.4:4016 vlc://quit --sout '#duplicate{dst=std{access=http,mux=ts,dst=[::]:3016},dst=std{access=udp,mux=ts,dst=[ff7e:a40:2a02:ed02:ffff::16]:2016}' --intf dummy --ttl 60 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/reflect-south-transcode.sh b/examples/historical/stream-stuff/reflect/reflect-south-transcode.sh new file mode 100755 index 0000000..65798dc --- /dev/null +++ b/examples/historical/stream-stuff/reflect/reflect-south-transcode.sh @@ -0,0 +1,5 @@ +#!/bin/sh +while :; do +vlc -vvv --intf dummy -v --sout-http-mark-start 12000 --sout-http-mark-end 13999 udp://@:4017 vlc://quit --sout '#duplicate{dst=std{access=http,mux=ts,dst=[::]:3017},dst=std{access=udp,mux=ts,dst=[ff7e:a40:2a02:ed02:ffff::17]:2017}' --intf dummy --ttl 60 + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/transcode-event-flash.sh b/examples/historical/stream-stuff/reflect/transcode-event-flash.sh new file mode 100755 index 0000000..34f546f --- /dev/null +++ b/examples/historical/stream-stuff/reflect/transcode-event-flash.sh @@ -0,0 +1,6 @@ +#!/bin/sh +while :; do +sudo cvlc -vv --sout-http-mark-start 19000 --sout-http-mark-end 21999 --network-caching 5000 --sout-x264-preset fast --sout-transcode-threads 10 --sout-x264-tune film --no-sout-x264-interlaced --sout-x264-lookahead 50 --sout-x264-vbv-maxrate 800 --sout-x264-vbv-bufsize 800 --sout-x264-keyint 50 -v http://stream.tg13.gathering.org:3013 vlc://quit \ +--sout '#transcode{height=480,fps=25,vcodec=h264,vb=800,acodec=aac,ab=128}:std{access=http{mime=video/x-flv},dst=[::]:5013/stream.flv}' + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/transcode-fugle-flash.sh b/examples/historical/stream-stuff/reflect/transcode-fugle-flash.sh new file mode 100755 index 0000000..110b8b8 --- /dev/null +++ b/examples/historical/stream-stuff/reflect/transcode-fugle-flash.sh @@ -0,0 +1,6 @@ +#!/bin/sh +while :; do +sudo cvlc -vv --sout-http-mark-start 16000 --sout-http-mark-end 18999 --network-caching 3000 --sout-x264-preset fast --sout-transcode-threads 10 --sout-x264-tune film --no-sout-x264-interlaced --sout-x264-lookahead 50 --sout-x264-vbv-maxrate 800 --sout-x264-vbv-bufsize 800 --sout-x264-keyint 50 -v http://stream.tg13.gathering.org:3015 vlc://quit \ +--sout '#transcode{height=480,fps=25,vcodec=h264,vb=800,acodec=aac,ab=128,deinterlace}:std{access=http{mime=video/x-flv},dst=[::]:5015/stream.flv}' + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/transcode-nocfisheye-flash.sh b/examples/historical/stream-stuff/reflect/transcode-nocfisheye-flash.sh new file mode 100755 index 0000000..19f89ad --- /dev/null +++ b/examples/historical/stream-stuff/reflect/transcode-nocfisheye-flash.sh @@ -0,0 +1,6 @@ +#!/bin/sh +while :; do +sudo cvlc -vv --sout-http-mark-start 25000 --sout-http-mark-end 27999 --network-caching 5000 --sout-x264-preset fast --sout-transcode-threads 10 --sout-x264-tune film --no-sout-x264-interlaced --sout-x264-lookahead 50 --sout-x264-vbv-maxrate 800 --sout-x264-vbv-bufsize 800 --sout-x264-keyint 50 -v http://stream.tg13.gathering.org:3018 vlc://quit \ +--sout '#transcode{height=480,fps=25,vcodec=h264,vb=800,acodec=aac,ab=128}:std{access=http{mime=video/x-flv},dst=[::]:5018/stream.flv}' + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/transcode-south-flash.sh b/examples/historical/stream-stuff/reflect/transcode-south-flash.sh new file mode 100755 index 0000000..6bf2cb8 --- /dev/null +++ b/examples/historical/stream-stuff/reflect/transcode-south-flash.sh @@ -0,0 +1,6 @@ +#!/bin/sh +while :; do +sudo cvlc -vv --sout-http-mark-start 22000 --sout-http-mark-end 24999 --network-caching 5000 --sout-x264-preset fast --sout-transcode-threads 10 --sout-x264-tune film --no-sout-x264-interlaced --sout-x264-lookahead 50 --sout-x264-vbv-maxrate 800 --sout-x264-vbv-bufsize 800 --sout-x264-keyint 50 -v http://stream.tg13.gathering.org:3016 vlc://quit \ +--sout '#transcode{height=480,fps=25,vcodec=h264,vb=800,acodec=aac,ab=128}:std{access=http{mime=video/x-flv},dst=[::]:5016/stream.flv}' + sleep 1 +done diff --git a/examples/historical/stream-stuff/reflect/usage.txt b/examples/historical/stream-stuff/reflect/usage.txt new file mode 100644 index 0000000..8b90bee --- /dev/null +++ b/examples/historical/stream-stuff/reflect/usage.txt @@ -0,0 +1,3 @@ +event-sd - ./reflect-event-sd.sh +event - ./reflect-event-lol.sh +event-flash - ./transcode-event-flash.sh diff --git a/examples/historical/stream-stuff/transcode/count.sh b/examples/historical/stream-stuff/transcode/count.sh new file mode 100755 index 0000000..22f6aa1 --- /dev/null +++ b/examples/historical/stream-stuff/transcode/count.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +while :; do + date=$(date +"%Y-%m-%d-%H:%M:%S") + ( lsof -n | grep vlc ; ssh root@gaffeltruck.tg12.gathering.org 'lsof -n | grep vlc' ) > /var/log/stream-count/$date + for PORT in 3013 5013 3014 5014 3015; do + for PROTO in IPv4 IPv6; do + # 176.110.x.x / 2a01:798:76a:125:: -> TG12 + # 176.31.230.19 / 2001:41d0:2:f700::2 -> OVH box + cat /var/log/stream-count/$date | grep EST | egrep $PROTO | egrep "(176\.31\.230\.19|2001:41d0:2:f700::.*):$PORT->" | cut -d'>' -f2 | sed 's/:[0-9]\+ (ESTABLISHED)//' | sort -u | grep -vEc 'fisk' | while read foo; do echo "$date $PORT $PROTO foreign $foo"; done | tee -a count_datacube.log + cat /var/log/stream-count/$date | grep EST | egrep $PROTO | egrep "(176\.110\..*|2a01:798:76a:125::.*):$PORT->" | cut -d'>' -f2 | sed 's/:[0-9]\+ (ESTABLISHED)//' | sort -u | grep -vEc -e "\[2a01:798:76a:|176\.110\." | while read foo; do echo "$date $PORT $PROTO external $foo"; done | tee -a count_datacube.log + cat /var/log/stream-count/$date | grep EST | egrep $PROTO | egrep "(176\.110\..*|2a01:798:76a:125::.*):$PORT->" | cut -d'>' -f2 | sed 's/:[0-9]\+ (ESTABLISHED)//' | sort -u | grep -Ec -e "\[2a01:798:76a:|176\.110\." | while read foo; do echo "$date $PORT $PROTO internal $foo"; done | tee -a count_datacube.log + done + done + sleep 60 +done; + diff --git a/examples/historical/stream-stuff/transcode/flash.sh b/examples/historical/stream-stuff/transcode/flash.sh new file mode 100755 index 0000000..3c42a8c --- /dev/null +++ b/examples/historical/stream-stuff/transcode/flash.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# udp://@:5013 +while :; do +vlc --intf dummy -vvv http://vivace.tg12.gathering.org:5013/stream.flv vlc://quit --network-caching 2000 --sout-mux-caching 3000 --sout "#std{access=http{mime=video/x-flv},dst=:5013/stream.flv}" + sleep 1 +done diff --git a/examples/historical/stream-stuff/transcode/flashtest.sh b/examples/historical/stream-stuff/transcode/flashtest.sh new file mode 100755 index 0000000..83ea48d --- /dev/null +++ b/examples/historical/stream-stuff/transcode/flashtest.sh @@ -0,0 +1,5 @@ +#!/bin/sh +while :; do + vlc --intf dummy -vvv http://stream.tg12.gathering.org:3013 vlc://quit --udp-caching 1000 --sout-x264-tune film --sout-x264-keyint 25 --sout-x264-preset veryfast --sout "#transcode{width=980,height=550,vcodec=h264,vb=1000,acodec=aac,ab=128}:std{access=http{mime=video/x-flv},dst=:5013/stream.flv}" + sleep 1 +done diff --git a/examples/historical/stream-stuff/transcode/ios-sd.sh b/examples/historical/stream-stuff/transcode/ios-sd.sh new file mode 100755 index 0000000..28a907a --- /dev/null +++ b/examples/historical/stream-stuff/transcode/ios-sd.sh @@ -0,0 +1,7 @@ +#!/bin/sh +while :; do +vlc -I dummy --live-caching 0 http://vivace.tg12.gathering.org:5013/stream.flv --sout-x264-profile baseline --sout-x264-preset veryfast --sout-x264-aud --sout-x264-keyint 30 --sout-x264-ref 1 vlc://quit --sout='#std{access=livehttp{seglen=10,delsegs=true,numsegs=5,index=/srv/stream.tg12.gathering.org/ios/sd.m3u8,index-url=http://stream.tg12.gathering.org/ios/sd-########.ts},mux=ts{use-key-frames},dst=/srv/stream.tg12.gathering.org/ios/sd-########.ts}' + sleep 2 +done + +# --sout-x264-level 30 diff --git a/examples/historical/stream-stuff/transcode/ios-south.sh b/examples/historical/stream-stuff/transcode/ios-south.sh new file mode 100755 index 0000000..ac06968 --- /dev/null +++ b/examples/historical/stream-stuff/transcode/ios-south.sh @@ -0,0 +1,7 @@ +#!/bin/sh +while :; do +vlc -I dummy --live-caching 0 udp://@:5114 vlc://quit --sout='#std{access=livehttp{seglen=10,delsegs=true,numsegs=5,index=/srv/stream.tg12.gathering.org/ios/south.m3u8,index-url=http://stream.tg12.gathering.org/ios/south-########.ts},mux=ts{use-key-frames},dst=/srv/stream.tg12.gathering.org/ios/south-########.ts}' + sleep 2 +done + +# --sout-x264-level 30 |