[17c2f7b] | 1 | #!/usr/bin/perl |
---|
| 2 | |
---|
| 3 | use strict; |
---|
| 4 | use IO::File; |
---|
| 5 | use IO::Pipe; |
---|
| 6 | |
---|
| 7 | my $IFCONFIG = "/sbin/ifconfig"; |
---|
| 8 | my $ZEBRA= "/usr/lib/quagga/zebra"; |
---|
| 9 | my $OSPFD= "/usr/lib/quagga/ospfd"; |
---|
| 10 | |
---|
| 11 | my $ospffn = "/usr/local/federation/etc/ospfd.conf"; |
---|
| 12 | my $zebrafn = "/usr/local/federation/etc/zebra.conf"; |
---|
| 13 | my @live_ones; |
---|
| 14 | my @bits_in_quad; |
---|
| 15 | my %ainfo; |
---|
| 16 | |
---|
| 17 | sub quad_to_int { |
---|
| 18 | my($ip) = @_; |
---|
| 19 | my @q = split(/\./, $ip); |
---|
| 20 | return ($q[0] << 24) + ($q[1] << 16) + ($q[2] << 8) + $q[3]; |
---|
| 21 | } |
---|
| 22 | |
---|
| 23 | sub int_to_quad { |
---|
| 24 | my($i) = @_; |
---|
| 25 | return sprintf("%d.%d.%d.%d", ($i >> 24) & 0xff, ($i>>16) & 0xff, |
---|
| 26 | ($i >>8) & 0xff, $i & 0xff); |
---|
| 27 | } |
---|
| 28 | |
---|
| 29 | sub nbits { |
---|
| 30 | my($b) = @_; |
---|
| 31 | return 0 if $b == 0; |
---|
| 32 | my $r = 1; |
---|
| 33 | for (my $i = 1 ; $i < $b; $i++) { |
---|
| 34 | $r <<= 1; |
---|
| 35 | $r += 1; |
---|
| 36 | } |
---|
| 37 | for (my $i = $b; $i< 32; $i ++) { |
---|
| 38 | $r <<= 1; |
---|
| 39 | $r &= 0xfffffffe; |
---|
| 40 | } |
---|
| 41 | return $r; |
---|
| 42 | } |
---|
| 43 | |
---|
| 44 | sub netslash { |
---|
| 45 | my($ip, $slash) = @_; |
---|
| 46 | return int_to_quad(quad_to_int($ip) & nbits($slash)); |
---|
| 47 | } |
---|
| 48 | |
---|
| 49 | for (my $i =0; $i < 256; $i++) { |
---|
| 50 | $bits_in_quad[$i] = 0; |
---|
| 51 | } |
---|
| 52 | my $m = 0xff; |
---|
| 53 | for (my $i = 8; $i > 0; $i--) { |
---|
| 54 | $bits_in_quad[$m] = $i; |
---|
| 55 | $m <<= 1; |
---|
| 56 | $m &= 0xfe; |
---|
| 57 | } |
---|
| 58 | |
---|
| 59 | |
---|
| 60 | if ( !-x $OSPFD) { |
---|
| 61 | if (-x "/usr/bin/apt-get" ) { |
---|
| 62 | system("/usr/bin/apt-get", "-y", "install", "quagga"); |
---|
| 63 | } |
---|
| 64 | elsif (-x "/usr/bin/yum") { |
---|
| 65 | system("/usr/bin/yum", "-y", "install", "quagga"); |
---|
| 66 | } |
---|
| 67 | } |
---|
| 68 | |
---|
| 69 | chomp (my $cif = `/usr/local/etc/emulab/control_interface`); |
---|
| 70 | chomp (my $hostname = `hostname`); |
---|
| 71 | $hostname =~ s/\..*//; |
---|
| 72 | |
---|
| 73 | my $ifp = new IO::Pipe(); |
---|
| 74 | $ifp->reader("$IFCONFIG"); |
---|
| 75 | my $current = undef; |
---|
| 76 | while (<$ifp>) { |
---|
| 77 | /^(\S+)/ && do { |
---|
| 78 | my $ifname = $1; |
---|
| 79 | if ($ifname ne $cif && $ifname !~ "^lo" ) { |
---|
| 80 | push(@live_ones, $ifname); |
---|
| 81 | $current = $ifname; |
---|
| 82 | } |
---|
| 83 | else { $current = undef; } |
---|
| 84 | print "$ifname $current\n"; |
---|
| 85 | }; |
---|
| 86 | /inet addr:\s*(\S+)\s*\S*\s*mask:\s*(\S+)/i && do { |
---|
| 87 | next unless $current; |
---|
| 88 | print "$current $1 $2\n"; |
---|
| 89 | my $slash = 0; |
---|
| 90 | foreach my $quad (split(/\./, $2)) { |
---|
| 91 | if ($bits_in_quad[$quad] != 0 ) { $slash += $bits_in_quad[$quad];} |
---|
| 92 | else { last;} |
---|
| 93 | } |
---|
| 94 | $ainfo{$current} = [ $1, $slash ]; |
---|
| 95 | print $current, " ", @{$ainfo{$current}}, "\n"; |
---|
| 96 | } |
---|
| 97 | } |
---|
| 98 | $ifp->close(); |
---|
| 99 | |
---|
| 100 | my $f = new IO::File(">$zebrafn") || die "Can't open $zebrafn: $!\n"; |
---|
| 101 | print $f "hostname $hostname\n"; |
---|
| 102 | foreach my $i (@live_ones) { |
---|
| 103 | print $f "interface $i\n"; |
---|
| 104 | } |
---|
| 105 | $f->close(); |
---|
| 106 | my $f = new IO::File(">$ospffn") || die "Can't open $ospffn: $!\n"; |
---|
| 107 | print $f "hostname $hostname\n"; |
---|
| 108 | print $f "router ospf\n"; |
---|
| 109 | foreach my $i (@live_ones) { |
---|
| 110 | print $f " network "; |
---|
| 111 | print $f netslash($ainfo{$i}->[0], $ainfo{$i}->[1]),"/",$ainfo{$i}->[1]," area 0.0.0.2\n"; |
---|
| 112 | } |
---|
| 113 | $f->close(); |
---|
| 114 | foreach my $fn ($zebrafn, $ospffn) { |
---|
| 115 | system("chmod 644 $fn"); |
---|
| 116 | } |
---|
| 117 | $f = new IO::File(">/proc/sys/net/ipv4/ip_forward") || |
---|
| 118 | die "Can't open sys forwarding file:$!\n"; |
---|
| 119 | print $f "1\n"; |
---|
| 120 | $f->close(); |
---|
| 121 | system("$ZEBRA -d -f $zebrafn"); |
---|
| 122 | system("$OSPFD -d -f $ospffn"); |
---|
| 123 | |
---|