From: Eirik Nygaard Date: Tue, 3 Apr 2007 13:37:55 +0000 (+0200) Subject: Merge with main branch. X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=a78ca3c9628b209500205ad77b333bd656175f34;hp=e8f023b0cb85cb14c3c68dac55bbeb3b080d9f20;p=nms Merge with main branch. --- diff --git a/.bzrignore b/.bzrignore new file mode 100644 index 0000000..aff8099 --- /dev/null +++ b/.bzrignore @@ -0,0 +1,5 @@ +*-config +mbd-ports +patchlist.txt +switches.txt +planning/planning diff --git a/config/make-dhcpd.pl b/config/make-dhcpd.pl index b31820d..3da7111 100755 --- a/config/make-dhcpd.pl +++ b/config/make-dhcpd.pl @@ -1,63 +1,54 @@ #! /usr/bin/perl -w use strict; -# les inn nettnavn -my %netnames = (); -my %netmasks = (); +my $date = `date --rfc-2822`; +chomp $date; + my @nets = (); open NAMES, "switches.txt" or die "switches.txt: $!"; while () { chomp; - /194\.0\.(\d+\.\d+)\s+(\d+)\s+(\S+)/ or next; - $netmasks{$1} = $2; - $netnames{$1} = $3; - push @nets, $1; + /87\.76\.(\d+\.\d+)\s+(\d+)\s+(\S+)/ or next; + push @nets, { + net => $1, + netmask => $2, + name => $3 + }; } print <<"EOF"; -# Autogenerated by make-dhcpd.pl. Do not edit manually! +# Autogenerated by make-dhcpd.pl at $date. Do not edit manually! -option domain-name "tg06.gathering.org"; -option domain-name-servers 194.0.254.2; +option domain-name "tg07.gathering.org"; +option domain-name-servers 87.76.254.2, 87.76.255.2; -# ddns-update-style none; -ddns-update-style interim; +# Netboot FTW +next-server 87.76.255.18; +filename "/pxelinux.0"; -# extra logging for option 82 -if exists agent.circuit-id -{ - log ( - info, - concat ( - "option-82 info for ", binary-to-ascii (16, 8, ":", hardware), - ": interface ", binary-to-ascii (10, 8, "/", suffix ( option agent.circuit-id, 2)), - ", VLAN ", binary-to-ascii (10, 16, "", substring( option agent.circuit-id, 2, 2)), - ", switch '", substring( option agent.remote-id, 2, 6), - "', port-name '", substring ( option agent.circuit-id, 2, extract-int ( substring ( option agent.circuit-id, 3, 1 ), 8 ) ), - "'" - ) - ); -} +ddns-update-style interim; +omapi-port 7911; # dnssec-keygen -a HMAC-MD5 -b 128 -n HOST DHCP_UPDATER key DHCP_UPDATER { algorithm HMAC-MD5.SIG-ALG.REG.INT; - secret 5Yz1azvh7mE0IRGffTvtKg==; + secret F388UOhaIIKHRH9TDE5PTA==; } default-lease-time 14400; max-lease-time 28800; # Tele-nett -subnet 194.0.254.0 netmask 255.255.255.0 { +subnet 87.76.254.0 netmask 255.255.255.0 { } # Server-nett -subnet 194.0.255.0 netmask 255.255.255.0 { +subnet 87.76.255.0 netmask 255.255.255.0 { + range 87.76.255.240 87.76.255.254; } -zone 0.194.in-addr.arpa. { +zone 76.87.in-addr.arpa. { primary 127.0.0.1; key DHCP_UPDATER; } @@ -65,97 +56,44 @@ zone 0.194.in-addr.arpa. { EOF for my $net (@nets) { - my $domain = $netnames{$net}; + my $domain = $net->{name}; my ($netmask, $numpc); - if ($netmasks{$net} == 24) { + if ($net->{netmask} == 24) { $netmask = "255.255.255.0"; $numpc = 256; - } elsif ($netmasks{$net} == 25) { + } elsif ($net->{netmask} == 25) { $netmask = "255.255.255.128"; $numpc = 128; - } elsif ($netmasks{$net} == 26) { + } elsif ($net->{netmask} == 26) { $netmask = "255.255.255.192"; $numpc = 64; } else { - die "Unknown netmask /$netmasks{$net}"; + die "Unknown netmask /" . $net->{netmask}; } - $net =~ /(\d+)\.(\d+)/ or die "Unknown net $net"; + $net->{net} =~ /(\d+)\.(\d+)/ or die "Unknown net $net"; my ($majorsubnet,$minorsubnet) = ($1,$2); - - my $gw = "194.0.$majorsubnet." . ($minorsubnet + 1); - my $rangestart = "194.0.$majorsubnet." . ($minorsubnet + 10); - my $rangeend = "194.0.$majorsubnet." . ($minorsubnet + $numpc - 2); - - if ($domain =~ /^split:(.*)/) { - my @domains = split /,/, $1; - for my $d (@domains) { - print <<"EOF"; -zone $d.tg06.gathering.org. { - primary 127.0.0.1; - key DHCP_UPDATER; -} -EOF - } - print <<"EOF"; -subnet 194.0.$net netmask $netmask { - authoritative; - option routers $gw; -EOF - my $numpc_sub = int($numpc / scalar(@domains)); - for my $d (@domains) { - print <<"EOF"; - class "$d" { - match if substring ( option agent.circuit-id, 2, extract-int ( substring ( option agent.circuit-id, 3, 1 ), 8 ) ) = "$d"; - } -EOF - } - - my $i = 0; - for my $d (@domains) { - my $rangestart = "194.0.$majorsubnet." . ($minorsubnet + $i * $numpc_sub + 10); - my $rangeend = "194.0.$majorsubnet." . ($minorsubnet + $i * $numpc_sub + $numpc_sub - 2); - - print <<"EOF"; - pool { - allow members of "$d"; - range $rangestart $rangeend; - option domain-name "$d.tg06.gathering.org tg06.gathering.org"; - ddns-domainname "$d.tg06.gathering.org"; - ignore client-updates; - } -EOF - ++$i; - } - } else { - print <<"EOF"; -zone $domain.tg06.gathering.org. { + # FIXME: Should use Net::CIDR + my $gw = "87.76.$majorsubnet." . ($minorsubnet + 1); + my $rangestart = "87.76.$majorsubnet." . ($minorsubnet + 10); + my $rangeend = "87.76.$majorsubnet." . ($minorsubnet + $numpc - 2); + + print <<"EOF"; +zone $domain.tg07.gathering.org. { primary 127.0.0.1; key DHCP_UPDATER; } -subnet 194.0.$net netmask $netmask { +subnet 87.76.$net->{net} netmask $netmask { authoritative; option routers $gw; range $rangestart $rangeend; - option domain-name "$domain.tg06.gathering.org tg06.gathering.org"; - ddns-domainname "$domain.tg06.gathering.org"; + option domain-name "$domain.tg07.gathering.org"; + ddns-domainname "$domain.tg07.gathering.org"; ignore client-updates; +} EOF - - # hack for sesse =) - if ($net eq '250.0') { - print <<"EOF"; - host trofast { - hardware ethernet 00:0e:0c:36:a7:66; - filename "/pxelinux.0"; - next-server 194.0.255.25; - } -EOF - } - } - - print "}\n"; } + diff --git a/config/make-missing-zones.pl b/config/make-missing-zones.pl index b809398..0ac4931 100755 --- a/config/make-missing-zones.pl +++ b/config/make-missing-zones.pl @@ -1,46 +1,43 @@ #! /usr/bin/perl -w use strict; -# les inn nettnavn -my %netnames = (); +my $date = `date --rfc-2822`; +chomp $date; + +my @nets = (); open NAMES, "switches.txt" or die "switches.txt: $!"; while () { chomp; - /194\.0\.(\d+\.\d+)\s+(\S+)\s+(\S+)/ or next; - $netnames{$1} = $3; -} -close NAMES; + /87\.76\.(\d+\.\d+)\s+(\d+)\s+(\S+)/ or next; + push @nets, { + net => $1, + netmask => $2, + name => $3 + }; +} -for my $net (keys %netnames) { - my $domain = $netnames{$net}; - my @domains; - if ($domain =~ /^split:(.*)/) { - @domains = split /,/, $1; - } else { - @domains = ($domain); - } +for my $net (@nets) { + my $d = $net->{name}; - for my $d (@domains) { - -f "/etc/bind/dynamic/$d.tg06.gathering.org" and next; + -f "/etc/bind/dynamic/$d.tg07.gathering.org" and next; - print "/etc/bind/dynamic/$d.tg06.gathering.org\n"; - open ZONE, ">/etc/bind/dynamic/$d.tg06.gathering.org" - or die "/etc/bind/dynamic/$d.tg06.gathering.org"; + print "/etc/bind/dynamic/$d.tg07.gathering.org\n"; + open ZONE, ">/etc/bind/dynamic/$d.tg07.gathering.org" + or die "/etc/bind/dynamic/$d.tg07.gathering.org"; - print ZONE <<"EOF"; + print ZONE <<"EOF"; ; autogenerated and updated from dhcpd -- DO NOT TOUCH! \$TTL 3600 -@ IN SOA fortran.tg06.gathering.org. postmaster.fortran.tg06.gathering.org. ( +@ IN SOA sysrq.tg07.gathering.org. abuse.gathering.org. ( 3 ; serial 3600 ; refresh 1800 ; retry 608400 ; expire 3600 ) ; minimum and default TTL - IN NS fortran.tg06.gathering.org. - IN NS lisp.tg06.gathering.org. + IN NS sysrq.tg07.gathering.org. + IN NS insert.tg07.gathering.org. EOF - } } diff --git a/config/make-named-secondary.pl b/config/make-named-secondary.pl index 38fda02..a9b3c12 100755 --- a/config/make-named-secondary.pl +++ b/config/make-named-secondary.pl @@ -1,27 +1,29 @@ #! /usr/bin/perl -w use strict; -# les inn nettnavn -my %netnames = (); -my %netmasks = (); +my $date = `date --rfc-2822`; +chomp $date; + my @nets = (); open NAMES, "switches.txt" -or die "switches.txt: $!"; + or die "switches.txt: $!"; while () { chomp; - /194\.0\.(\d+\.\d+)\s+(\d+)\s+(\S+)/ or next; - $netmasks{$1} = $2; - $netnames{$1} = $3; - push @nets, $1; -} + /87\.76\.(\d+\.\d+)\s+(\d+)\s+(\S+)/ or next; + push @nets, { + net => $1, + netmask => $2, + name => $3 + }; +} print <<"EOF"; -// Autogenerated by make-named-secondary.pl. Do not edit manually! +// Autogenerated by make-named-secondary.pl at $date. Do not edit manually! options { directory "/etc/bind"; allow-query { any; }; - allow-transfer { 194.19.3.20; 194.0.255.2; }; + allow-transfer { 194.19.3.20; }; auth-nxdomain no; recursion yes; @@ -37,29 +39,54 @@ zone "0.0.127.in-addr.arpa" { notify no; }; -zone "tg06.gathering.org" { +zone "tg07.gathering.org" { + type slave; + notify no; + masters { 87.76.254.2; }; + file "tg07.gathering.org"; +}; + +// linknett +zone "174.76.87.in-addr.arpa" { + type slave; + notify no; + masters { 87.76.254.2; }; + file "174.76.87.in-addr.arpa"; + allow-transfer { 193.0.0.0/22; }; +}; + +// nett-subnett +zone "239.76.87.in-addr.arpa" { type slave; notify no; - masters { 194.0.254.2; }; - file "tg06.gathering.org"; + masters { 87.76.254.2; }; + file "239.76.87.in-addr.arpa"; + allow-transfer { 193.0.0.0/22; }; }; // serversubnett -zone "255.0.194.in-addr.arpa" { +zone "254.76.87.in-addr.arpa" { type slave; notify no; - masters { 194.0.254.2; }; - file "255.0.194.in-addr.arpa"; - allow-transfer { 194.0.255.2; 193.0.0.0/22; }; + masters { 87.76.254.2; }; + file "254.76.87.in-addr.arpa"; + allow-transfer { 193.0.0.0/22; }; +}; +zone "255.76.87.in-addr.arpa" { + type slave; + notify no; + masters { 87.76.254.2; }; + file "255.76.87.in-addr.arpa"; + allow-transfer { 193.0.0.0/22; }; }; -zone "0.194.in-addr.arpa" { +zone "76.87.in-addr.arpa" { type slave; notify no; - masters { 194.0.254.2; }; + masters { 87.76.254.2; }; allow-update { key DHCP_UPDATER; }; - file "dynamic/0.194.in-addr.arpa"; - allow-transfer { 194.19.3.20; 194.0.255.2; 193.0.0.0/22; }; + file "dynamic/76.87.in-addr.arpa"; + allow-transfer { 194.19.3.20; 193.0.0.0/22; }; }; key DHCP_UPDATER { @@ -70,24 +97,16 @@ key DHCP_UPDATER { EOF for my $net (@nets) { - my $domain = $netnames{$net}; - my @domains; - if ($domain =~ /^split:(.*)/) { - @domains = split /,/, $1; - } else { - @domains = ($domain); - } - - for my $d (@domains) { - print <<"EOF"; -zone "$d.tg06.gathering.org" { + my $d = $net->{name}; + + print <<"EOF"; +zone "$d.tg07.gathering.org" { type slave; notify no; - masters { 194.0.254.2; }; + masters { 87.76.254.2; }; allow-update { key DHCP_UPDATER; }; - file "dynamic/$d.tg06.gathering.org"; - allow-transfer { 194.19.3.20; 194.0.255.2; }; + file "dynamic/$d.tg07.gathering.org"; + allow-transfer { 194.19.3.20; }; }; EOF - } } diff --git a/config/make-named.pl b/config/make-named.pl index 2099b64..d2bbf02 100755 --- a/config/make-named.pl +++ b/config/make-named.pl @@ -1,27 +1,29 @@ #! /usr/bin/perl -w use strict; -# les inn nettnavn -my %netnames = (); -my %netmasks = (); +my $date = `date --rfc-2822`; +chomp $date; + my @nets = (); open NAMES, "switches.txt" -or die "switches.txt: $!"; + or die "switches.txt: $!"; while () { chomp; - /194\.0\.(\d+\.\d+)\s+(\d+)\s+(\S+)/ or next; - $netmasks{$1} = $2; - $netnames{$1} = $3; - push @nets, $1; -} + /87\.76\.(\d+\.\d+)\s+(\d+)\s+(\S+)/ or next; + push @nets, { + net => $1, + netmask => $2, + name => $3 + }; +} print <<"EOF"; -// Autogenerated by make-named.pl. Do not edit manually! +// Autogenerated by make-named.pl at $date. Do not edit manually! options { directory "/etc/bind"; allow-query { any; }; - allow-transfer { 194.19.3.20; 194.0.255.2; }; + allow-transfer { 194.19.3.20; 87.76.255.2; }; auth-nxdomain no; recursion yes; @@ -37,54 +39,67 @@ zone "0.0.127.in-addr.arpa" { notify no; }; -zone "tg06.gathering.org" { +zone "tg07.gathering.org" { type master; - file "tg06.gathering.org"; + file "tg07.gathering.org"; notify yes; - allow-transfer { 194.0.255.2; }; + allow-transfer { 87.76.255.2; }; }; -// serversubnett -zone "255.0.194.in-addr.arpa" { +// linknett +zone "174.76.87.in-addr.arpa" { type master; - file "255.0.194.in-addr.arpa"; + file "174.76.87.in-addr.arpa"; notify yes; - allow-transfer { 194.0.255.2; 193.0.0.0/22; }; + allow-transfer { 87.76.255.2; 193.0.0.0/22; }; }; -zone "0.194.in-addr.arpa" { +// net-subnett +zone "239.76.87.in-addr.arpa" { type master; - allow-update { key DHCP_UPDATER; }; + file "239.76.87.in-addr.arpa"; + notify yes; + allow-transfer { 87.76.255.2; 193.0.0.0/22; }; +}; + +// serversubnett +zone "254.76.87.in-addr.arpa" { + type master; + file "254.76.87.in-addr.arpa"; notify yes; - file "dynamic/0.194.in-addr.arpa"; - allow-transfer { 194.19.3.20; 194.0.255.2; 193.0.0.0/22; }; + allow-transfer { 87.76.255.2; 193.0.0.0/22; }; +}; +zone "255.76.87.in-addr.arpa" { + type master; + file "255.76.87.in-addr.arpa"; + notify yes; + allow-transfer { 87.76.255.2; 193.0.0.0/22; }; }; key DHCP_UPDATER { algorithm HMAC-MD5.SIG-ALG.REG.INT; - secret 5Yz1azvh7mE0IRGffTvtKg==; + secret F388UOhaIIKHRH9TDE5PTA==; +}; + +zone "76.87.in-addr.arpa" { + type master; + allow-update { key DHCP_UPDATER; }; + notify yes; + file "dynamic/76.87.in-addr.arpa"; + allow-transfer { 194.19.3.20; 87.76.255.2; 193.0.0.0/22; }; }; EOF for my $net (@nets) { - my $domain = $netnames{$net}; - my @domains; - if ($domain =~ /^split:(.*)/) { - @domains = split /,/, $1; - } else { - @domains = ($domain); - } - - for my $d (@domains) { - print <<"EOF"; -zone "$d.tg06.gathering.org" { + my $domain = $net->{name}; + print <<"EOF"; +zone "$domain.tg07.gathering.org" { type master; allow-update { key DHCP_UPDATER; }; notify yes; - file "dynamic/$d.tg06.gathering.org"; - allow-transfer { 194.19.3.20; 194.0.255.2; }; + file "dynamic/$domain.tg07.gathering.org"; + allow-transfer { 194.19.3.20; 87.76.255.2; }; }; EOF - } } diff --git a/config/make-port-config.pl b/config/make-port-config.pl new file mode 100755 index 0000000..ee75cab --- /dev/null +++ b/config/make-port-config.pl @@ -0,0 +1,68 @@ +#! /usr/bin/perl +open PATCHLIST, ") { + chomp; + my ($name, $distro, $port) = split / /; + + $name =~ /e(\d+)-(\d+)/; + my ($row, $switch) = ($1, $2); + + my $ip; + if ($switch == 1) { + $ip = "87.76." . ($row) . ".1"; + } elsif ($switch == 2) { + $ip = "87.76." . ($row) . ".65"; + } elsif ($switch == 3) { + $ip = "87.76." . ($row) . ".129"; + } elsif ($switch == 4) { + $ip = "87.76." . ($row + 1) . ".1"; + } elsif ($switch == 5) { + $ip = "87.76." . ($row + 1) . ".65"; + } elsif ($switch == 6) { + $ip = "87.76." . ($row + 1) . ".129"; + } + + my $vlan = "$row$switch"; + + $distros{$distro} .= <<"EOF"; +vlan $vlan + name $name +! +default interface vlan $vlan +interface vlan $vlan + description $name + ip address $ip 255.255.255.192 + ip directed-broadcast 10 + ip helper-address 87.76.254.2 + no ip proxy-arp + ip access-group great-wall-of-tg in + ipv6 address 2001:16D8:FFFF:$vlan::1/64 + no shutdown +! + +default interface $port +interface $port + description $name + switchport mode access + switchport access vlan $vlan + + spanning-tree portfast + spanning-tree bpduguard enable + + ip igmp snooping + storm-control broadcast level 2 + no shutdown +! +EOF +} + +for my $distro (keys %distros) { + open DISTRO, ">$distro-config" + or die "$distro-config: $!"; + print DISTRO $distros{$distro}; + print DISTRO "end\n"; + close DISTRO; +} diff --git a/make-all-config.sh b/make-all-config.sh new file mode 100755 index 0000000..c186b28 --- /dev/null +++ b/make-all-config.sh @@ -0,0 +1,10 @@ +#! /bin/sh +./planning/planning +cat static-switches.txt >> switches.txt +./config/make-dhcpd.pl > /etc/dhcp3/dhcpd.conf +./config/make-named.pl > /etc/bind/named.conf +./config/make-named-secondary.pl | ssh root@insert 'cat > /etc/bind/named.conf' +./config/make-missing-zones.pl +(cd mbd && ./generate-helper-list.pl > ../mbd-ports) +./config/make-port-config.pl +scp mbd-ports *-config sesse@f1:/tftpboot/portcfg/ diff --git a/mbd/access_list.pl b/mbd/access_list.pl new file mode 100644 index 0000000..2d2dfce --- /dev/null +++ b/mbd/access_list.pl @@ -0,0 +1,106 @@ + +package Config; + +our @access_list = ( + # half-life - untested (packet dump only) + { + ports => [ 27015 ], + sizes => [ 16 ] + }, + + # cs 1.6 - verified + # (funker muligens for _alle_ source-spill inkl. hl2/cs:s) + { + ports => [ 4242, "26900..26905", "27015..27020" ], + sizes => [ 25 ] + }, + + # doom 3 - verified + { + ports => [ "27666..27673" ], + sizes => [ 14 ] + }, + + # quake 1 - verified + { + ports => [ 26000 ], + sizes => [ 12 ] + }, + + # q3a - tested with demo only + # rtcw: enemy territory - untested (packet dump only) + { + ports => [ "27960..27969" ], + sizes => [ 15 ] + }, + + # bf2 - tested with demo only + # bf2142 reportedly uses same engine + { + ports => [ "29900..29950" ], + sizes => [ 8 ] + }, + + # bf1942 - unverified (packet dump only) + { + ports => [ "22000..22010" ], + sizes => [ 8 ] + }, + + # quake 4 - tested with demo only, MUST select "internet" + { + ports => [ 27950, 28004 ], + sizes => [ 14 ] + }, + + # quake 2 - untested (packet dump only) + { + ports => [ 27910 ], + sizes => [ 11 ] + }, + + # warcraft 3 - untested (packet dump only) + { + ports => [ "6112..6119" ], + sizes => [ 16, 48 ] + }, + + # ut2003/ut2004 - untested (packet dump only) + { + ports => [ 10777 ], + sizes => [ 5 ] + }, + + # soldat - untested (packet dump only) + { + ports => [ 23073 ], + sizes => [ 8 ] + }, + + # starcraft - untested (packet dump only) + { + ports => [ 6111, 6112 ], + sizes => [ 8, 20 ] + }, + + # trackmania nations - untested (packet dump only) + { + ports => [ "2350..2370" ], + sizes => [ 42 ] + }, + + # company of heroes - untested (packet dump only) + { + ports => [ 9100 ], + sizes => [ 39 ] + }, + + # command & conquer 3 - untested (packet dump only, reported to have some kind + # of chat functionality) + { + ports => [ "8086..8093" ], + sizes => [ 476 ] + }, + + # unreal tournament, port 9777? +) diff --git a/mbd/generate-helper-list.pl b/mbd/generate-helper-list.pl new file mode 100755 index 0000000..fd89475 --- /dev/null +++ b/mbd/generate-helper-list.pl @@ -0,0 +1,15 @@ +#! /usr/bin/perl +use strict; +use warnings; +require './access_list.pl'; +require './nets.pl'; +require './mbd.pm'; + +my @ports = mbd::find_all_ports(); + +print "no ip forward-protocol udp 137\n"; +print "no ip forward-protocol udp 138\n"; + +for my $port (@ports) { + print "ip forward-protocol udp $port\n"; +} diff --git a/mbd/mbd.pl b/mbd/mbd.pl new file mode 100644 index 0000000..e5c2879 --- /dev/null +++ b/mbd/mbd.pl @@ -0,0 +1,90 @@ +#! /usr/bin/perl +use strict; +use warnings; +use Socket; +use Net::CIDR; +use Net::RawIP; +require './access_list.pl'; +require './nets.pl'; +require './mbd.pm'; + +sub fhbits { + my $bits = 0; + for my $fh (@_) { + vec($bits, fileno($fh), 1) = 1; + } + return $bits; +} + +my @ports = mbd::find_all_ports(); + +# Open a socket for each port +my @socks = (); +my $udp = getprotobyname("udp"); +for my $p (@ports) { + my $sock; + socket($sock, PF_INET, SOCK_DGRAM, $udp); + bind($sock, sockaddr_in($p, INADDR_ANY)); + push @socks, $sock; +} + +my $sendsock = Net::RawIP->new({udp => {}}); + +print "Listening on " . scalar @ports . " ports.\n"; + +# Main loop +while (1) { + my $rin = fhbits(@socks); + my $rout; + + my $nfound = select($rout=$rin, undef, undef, undef); + for my $sock (@socks) { + next unless (vec($rout, fileno($sock), 1) == 1); + + my $data; + my $addr = recv($sock, $data, 8192, 0); # jumbo broadcast! :-P + my ($sport, $saddr) = sockaddr_in($addr); + my ($dport, $daddr) = sockaddr_in(getsockname($sock)); + my $size = length($data); + + # We don't get the packet's destination address, but I guess this should do... + # Check against the ACL. + my $pass = 0; + for my $rule (@Config::access_list) { + if (mbd::match_ranges($dport, $rule->{'ports'}) && + mbd::match_ranges($size, $rule->{'sizes'})) { + $pass = 1; + } + } + + if (!$pass) { + print "$dport, $size bytes => filtered\n"; + } + + next unless $pass; + + for my $net (@Config::networks) { + next if (Net::CIDR::cidrlookup(inet_ntoa($saddr), $net)); + + my ($range) = Net::CIDR::cidr2range($net); + $range =~ /-(.*?)$/; + my $broadcast = $1; + + print inet_ntoa($saddr), ", $dport, $size bytes => $broadcast\n"; + + $sendsock->set({ + ip => { + saddr => inet_ntoa($saddr), + daddr => $broadcast + }, + udp => { + source => $sport, + dest => $dport, + data => $data + } + }); + $sendsock->send; + } + } +} + diff --git a/mbd/mbd.pm b/mbd/mbd.pm new file mode 100644 index 0000000..b844e5b --- /dev/null +++ b/mbd/mbd.pm @@ -0,0 +1,50 @@ +#! /usr/bin/perl +use strict; +use warnings; +use Socket; +use Net::CIDR; +use Net::RawIP; +require './access_list.pl'; +require './nets.pl'; + +package mbd; + +sub expand_range { + my $range = shift; + + if ($range =~ /^(\d+)\.\.(\d+)$/) { + return $1..$2; + } else { + return $range; + } +} + +sub match_ranges { + my ($elem, $ranges) = @_; + + for my $range (@$ranges) { + if ($range =~ /^(\d+)\.\.(\d+)$/) { + return 1 if ($elem >= $1 && $elem <= $2); + } else { + return 1 if ($elem == $range); + } + } + + return 0; +} + +sub find_all_ports { + # Find what ports we need to listen on + my %port_hash = (); + for my $e (@Config::access_list) { + for my $r (@{$e->{'ports'}}) { + for my $p (expand_range($r)) { + $port_hash{$p} = 1; + } + } + } + my @ports = sort { $a <=> $b } keys %port_hash; + return @ports; +} + +1; diff --git a/mbd/nets.pl b/mbd/nets.pl new file mode 100644 index 0000000..55bec01 --- /dev/null +++ b/mbd/nets.pl @@ -0,0 +1,9 @@ + +package Config; + +our @networks = ( + "10.0.10.0/24", + "10.0.11.0/24" +); + +1; diff --git a/planning/planning.cpp b/planning/planning.cpp old mode 100644 new mode 100755 index 73ea0f1..0917a4e --- a/planning/planning.cpp +++ b/planning/planning.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #define NUM_DISTRO 5 #define SWITCHES_PER_ROW 6 @@ -20,9 +21,13 @@ struct sw { }; int distro_placements[NUM_DISTRO] = { 5, 12, 19, 26, 33 + // 3, 7, 12, 19, 26, 31, 35 }; unsigned horiz_cost[SWITCHES_PER_ROW] = { - 346, 250, 154, 104, 200, 296 + // one seat is 80cm wide. first switch is after 6 seats, then 18, then + // 30. gap is 5m extra (the distribution switches are on the eastern + // side). + 290, 194, 98, 48, 144, 240 }; // memoization table @@ -46,49 +51,83 @@ struct key { }; struct value { unsigned char distro; - unsigned cost, this_cost; + unsigned cost, this_cost, this_distance; }; std::map cache; unsigned cache_hits = 0; std::vector switches; +std::map num_ports_used; -unsigned distance(sw from_where, unsigned distro) +unsigned find_distance(sw from_where, unsigned distro) { - // FIXME: calculate gaps as well - unsigned base_cost = 41 * abs(from_where.row - distro_placements[distro]) + horiz_cost[from_where.num]; + // 3.7m from row to row (2.5m gap + 1.2m boards) + unsigned base_cost = 37 * abs(from_where.row - distro_placements[distro]) + horiz_cost[from_where.num]; + // 4m, 5m, 4m gaps (1.5m, 2.5m, 1.5m extra) if ((from_where.row <= 9) == (distro_placements[distro] >= 10)) - base_cost += 25; + base_cost += 15; if ((from_where.row <= 17) == (distro_placements[distro] >= 18)) base_cost += 25; if ((from_where.row <= 25) == (distro_placements[distro] >= 26)) - base_cost += 25; - if ((from_where.row <= 34) == (distro_placements[distro] >= 35)) - base_cost += 25; + base_cost += 15; -#if TRUNCATE_METRIC - if (base_cost > 600) + // add 5.6m slack. + return base_cost + 56; +} + +unsigned cable_select(unsigned distance) +{ + + if (distance > 600) return 1000; - if (base_cost > 500) + if (distance > 500) return FIFTYPLUSTEN; - if (base_cost > 400) + if (distance > 400) return 500; - if (base_cost > 300) + if (distance > 300) return THIRTYPLUSTEN; - if (base_cost > 200) + if (distance > 200) return 300; - if (base_cost > 100) + if (distance > 100) return TENPLUSTEN; return 100; +} + +unsigned find_slack(unsigned distance) +{ + switch (cable_select(distance)) { + case 1000: + return 1000 - distance; + case FIFTYPLUSTEN: + return 600 - distance; + case 500: + return 500 - distance; + case THIRTYPLUSTEN: + return 400 - distance; + case 300: + return 300 - distance; + case TENPLUSTEN: + return 200 - distance; + case 100: + return 100 - distance; + } +} + +unsigned find_cost(unsigned distance) +{ + //return find_slack(distance); + +#if TRUNCATE_METRIC + return cable_select(distance); #else - return base_cost; -// return ((base_cost + 90) / 100) * 100; + return distance; +// return ((distance + 90) / 100) * 100; #endif } unsigned find_optimal_cost(key &k) { - unsigned best_cost = 999999990, best_this_cost = 0; + unsigned best_cost = 999999990, best_this_cost = 0, best_this_distance = 0; int best = -1; unsigned char db = k.distro_bound; unsigned char dbh = k.distro_bound_hard; @@ -106,7 +145,8 @@ unsigned find_optimal_cost(key &k) if (k.ports_left[i] == 0) continue; - unsigned cost = distance(switches[k.sw_ind], i); + unsigned distance = find_distance(switches[k.sw_ind], i); + unsigned cost = find_cost(distance); --(k.ports_left[i]); ++(k.sw_ind); @@ -123,24 +163,68 @@ unsigned find_optimal_cost(key &k) if (best == -1 || cost < best_cost) { best = i; best_cost = cost; - best_this_cost = distance(switches[k.sw_ind], i); + best_this_distance = distance; + best_this_cost = find_cost(distance); } } k.distro_bound = db; k.distro_bound_hard = dbh; - value v = { best, best_cost, best_this_cost }; + value v = { best, best_cost, best_this_cost, best_this_distance }; cache[k] = v; return best_cost; } + +std::string port_name(unsigned distro, unsigned portnum) +{ + char buf[16]; + + if (distro == 0) { + if (portnum < 23) { + sprintf(buf, "d01-1 g0/%u", portnum); + } else { + sprintf(buf, "d01-2 g0/%u", portnum - 22); + } + } else if (distro == 1) { + sprintf(buf, "d02 g1/0/%u", portnum); + } else if (distro == 2) { + sprintf(buf, "d03 g1/%u", portnum); + } else if (distro == 3) { + sprintf(buf, "d04 g1/0/%u", portnum); + } else if (distro == 4) { + if (portnum < 23) { + sprintf(buf, "d05-1 g0/%u", portnum); + } else { + sprintf(buf, "d05-2 g0/%u", portnum - 22); + } + } else { + sprintf(buf, "d%02u 1/0/%u", distro + 1, portnum); + } + + return buf; +} -int main() +int main(int argc, char **argv) { struct key start; + FILE *patchlist = fopen("patchlist.txt", "w"); + FILE *switchlist = fopen("switches.txt", "w"); #if TRUNCATE_METRIC std::map cable_count; #endif + unsigned total_slack = 0; + +#if 0 + // used for placement optimization + distro_placements[0] = atoi(argv[1]); + distro_placements[1] = atoi(argv[2]); + distro_placements[2] = atoi(argv[3]); + distro_placements[3] = atoi(argv[4]); + distro_placements[4] = atoi(argv[5]); + distro_placements[5] = atoi(argv[6]); + distro_placements[6] = atoi(argv[7]); +#endif switches.push_back(sw(1, 3)); switches.push_back(sw(1, 4)); @@ -149,34 +233,54 @@ int main() switches.push_back(sw(2, 4)); switches.push_back(sw(2, 5)); - for (unsigned i = 3; i < 35; ++i) + for (unsigned i = 3; i <= 15; ++i) + for (unsigned j = 0; j < SWITCHES_PER_ROW; ++j) + switches.push_back(sw(i, j)); + + switches.push_back(sw(16, 0)); + switches.push_back(sw(16, 1)); + switches.push_back(sw(16, 2)); + switches.push_back(sw(16, 4)); + switches.push_back(sw(16, 5)); + + switches.push_back(sw(17, 0)); + switches.push_back(sw(17, 1)); + switches.push_back(sw(17, 2)); + switches.push_back(sw(17, 4)); + switches.push_back(sw(17, 5)); + + for (unsigned i = 18; i <= 34; ++i) for (unsigned j = 0; j < SWITCHES_PER_ROW; ++j) switches.push_back(sw(i, j)); - switches.push_back(sw(35, 1)); - switches.push_back(sw(35, 2)); switches.push_back(sw(35, 3)); switches.push_back(sw(35, 4)); + switches.push_back(sw(35, 5)); - switches.push_back(sw(36, 1)); - switches.push_back(sw(36, 2)); switches.push_back(sw(36, 3)); switches.push_back(sw(36, 4)); - - switches.push_back(sw(37, 1)); - switches.push_back(sw(37, 2)); - switches.push_back(sw(37, 3)); - switches.push_back(sw(37, 4)); + switches.push_back(sw(36, 5)); start.sw_ind = 0; start.distro_bound = 0; start.distro_bound_hard = 0; - start.ports_left[0] = 40; - start.ports_left[1] = 40; - start.ports_left[2] = 50; - start.ports_left[3] = 40; - start.ports_left[4] = 40; + start.ports_left[0] = 44; + start.ports_left[1] = 42; + start.ports_left[2] = 37; + start.ports_left[3] = 42; + start.ports_left[4] = 44; +#if 0 + // split distro + start.ports_left[0] = 22; + start.ports_left[1] = 22; + start.ports_left[2] = 42; + start.ports_left[3] = 37; + start.ports_left[4] = 42; + start.ports_left[5] = 22; + start.ports_left[6] = 22; +#endif + printf("Finding optimal layout for %u switches\n", switches.size()); find_optimal_cost(start); printf("%u cache nodes, %u cache hits.\n", cache.size(), cache_hits); @@ -197,7 +301,7 @@ int main() k.distro_bound_hard = k.distro_bound; if (last_row != switches[k.sw_ind].row) { - printf("\n"); + printf("\n%2u-%2u ", switches[k.sw_ind].row * 2 - 1, switches[k.sw_ind].row * 2 + 0 ); last_num = -1; } for (int j = last_num; j + 1 < switches[k.sw_ind].num; ++j) { @@ -207,16 +311,18 @@ int main() printf("[%um%u ", v.distro + 33, v.distro); #if TRUNCATE_METRIC - if (v.this_cost == FIFTYPLUSTEN) + if (cable_select(v.this_distance) == FIFTYPLUSTEN) printf("(50+10) "); - else if (v.this_cost == THIRTYPLUSTEN) + else if (cable_select(v.this_distance) == THIRTYPLUSTEN) printf("(30+10) "); - else if (v.this_cost == TENPLUSTEN) + else if (cable_select(v.this_distance) == TENPLUSTEN) printf("(10+10) "); else - printf("(%-3u ) ", v.this_cost / 10); - cable_count[v.this_cost]++; + printf("(%-3u ) ", cable_select(v.this_distance) / 10); + total_slack += find_slack(v.this_distance); + cable_count[cable_select(v.this_distance)]++; #else + total_slack += find_slack(v.this_distance); printf("(%3.1f) ", v.this_cost / 10.0); #endif @@ -225,9 +331,58 @@ int main() ++(k.sw_ind); --k.ports_left[v.distro]; + + fprintf(patchlist, "e%u-%u %s\n", last_row * 2 - 1, last_num + 1, + port_name(v.distro, ++num_ports_used[v.distro]).c_str()); + + switch (last_num + 1) { + case 1: + fprintf(switchlist, "87.76.%u.0 26 e%u-%u\n", + last_row * 2 - 1, last_row * 2 - 1, last_num + 1); + break; + case 2: + fprintf(switchlist, "87.76.%u.64 26 e%u-%u\n", + last_row * 2 - 1, last_row * 2 - 1, last_num + 1); + break; + case 3: + fprintf(switchlist, "87.76.%u.128 26 e%u-%u\n", + last_row * 2 - 1, last_row * 2 - 1, last_num + 1); + break; + case 4: + fprintf(switchlist, "87.76.%u.0 26 e%u-%u\n", + last_row * 2, last_row * 2 - 1, last_num + 1); + break; + case 5: + fprintf(switchlist, "87.76.%u.64 26 e%u-%u\n", + last_row * 2, last_row * 2 - 1, last_num + 1); + break; + case 6: + fprintf(switchlist, "87.76.%u.128 26 e%u-%u\n", + last_row * 2, last_row * 2 - 1, last_num + 1); + break; + } } printf("\n"); - for (std::map::iterator i = cable_count.begin(); i != cable_count.end(); ++i) - printf("%u => %u\n", i->first, i->second); +#if TRUNCATE_METRIC + cable_count[100] += cable_count[TENPLUSTEN]; + cable_count[100] += cable_count[TENPLUSTEN]; + + cable_count[100] += cable_count[THIRTYPLUSTEN]; + cable_count[300] += cable_count[THIRTYPLUSTEN]; + + cable_count[100] += cable_count[FIFTYPLUSTEN]; + cable_count[500] += cable_count[FIFTYPLUSTEN]; + + printf("\n"); + printf("10m: %3u\n", cable_count[100]); + printf("30m: %3u\n", cable_count[300]); + printf("50m: %3u\n", cable_count[500]); + printf("Extensions: %u\n", cable_count[TENPLUSTEN] + cable_count[THIRTYPLUSTEN] + cable_count[FIFTYPLUSTEN]); + printf("\n"); + + unsigned total_cable = 100 * cable_count[100] + 300 * cable_count[300] + 500 * cable_count[500]; + printf("Total cable: %.1fm\n", total_cable / 10.0); + printf("Total slack: %.1fm (%.2f%%)\n", total_slack / 10.0, 100.0 * double(total_slack) / double(total_cable)); +#endif } diff --git a/static-switches.txt b/static-switches.txt new file mode 100644 index 0000000..2619cd7 --- /dev/null +++ b/static-switches.txt @@ -0,0 +1,23 @@ +87.76.32.0 26 e31-4 +87.76.119.0 24 hoa-gutta +87.76.120.0 24 crew +87.76.130.0 24 noc-wlan +87.76.131.0 24 public-wlan +87.76.200.0 24 vision +87.76.202.0 24 sponsor-vision +87.76.204.0 24 sponsor-tribune +87.76.205.0 24 infodesk-inngang +87.76.206.0 24 crewcare +87.76.207.0 24 auditorium +87.76.208.0 24 ute +87.76.209.0 24 infodesk +87.76.210.0 24 game-server +87.76.212.0 24 game-client +87.76.213.0 24 logistics +87.76.215.0 24 security +87.76.216.0 24 medic +87.76.220.0 24 fugleberget +87.76.222.0 24 democrew +87.76.223.0 24 cam +87.76.250.0 24 noc +87.76.252.0 24 presse