2dba6494 |
1 | #!/usr/bin/perl |
2 | |
f685ef8c |
3 | use Socket; |
4 | |
2dba6494 |
5 | #$sharedir= '/usr/local/share/userv/udptunnelconf'; |
6 | $sharedir= '/home/ian/things/userv-utils/udptunnelconf'; |
7 | $confdir= '/etc/udptunnel'; |
8 | |
9 | sub badusage () { die "usage: udptunnel-reconf [<directory>]\n"; } |
10 | $debug=0; |
11 | |
f685ef8c |
12 | sub fault ($) { die "$0: $_[0]\n"; } |
13 | |
2dba6494 |
14 | while ($ARGV[0] =~ m/^-/) { |
15 | $_= shift @ARGV; |
16 | last if m/^--$/; |
17 | if (m/^-d$/) { $debug++; next; } |
18 | badusage(); |
19 | } |
20 | |
21 | if (@ARGV) { $confdir= shift @ARGV; } |
f685ef8c |
22 | badusage() if @ARGV; |
2dba6494 |
23 | |
f685ef8c |
24 | chdir $confdir or fault("$confdir: $!"); |
2dba6494 |
25 | |
26 | sub run_m4 ($$$) { |
27 | my ($wanted, $site, $variable) = @_; |
28 | $x= "m4 -P -DWANTED=$wanted -DWHVARIABLE=V_$variable -DV_global=global ". |
29 | "-DV_site=$site ". |
30 | "-DV_defaults=$sharedir/defaults $sharedir/config.m4"; |
31 | print STDERR $x,"\n" if $debug>=2; |
f685ef8c |
32 | open X, "$x |" or die $!; |
2dba6494 |
33 | undef $/; |
34 | $m4out= <X>; |
35 | $/= "\n"; |
36 | close X; $? and exit -1; |
37 | $m4out =~ s/^\s+//; |
38 | $m4out =~ s/\n+/\n/g; |
39 | $m4out =~ s/\s+$//; |
40 | print STDERR "$wanted/$variable($site) -> \`$m4out'\n" if $debug>=1; |
f685ef8c |
41 | # $m4out='' if $wanted eq 'VARIABLE' && substr($m4out,0,2) eq 'V_'; |
2dba6494 |
42 | return $m4out; |
43 | } |
44 | |
45 | sub check_junk ($$) { |
46 | my ($emsg, $site) = @_; |
47 | $j= run_m4('JUNK',$site,''); |
48 | $j =~ s/^\# //g; |
f685ef8c |
49 | fault("$emsg: $j") if length $j; |
2dba6494 |
50 | } |
51 | |
f685ef8c |
52 | sub var_global ($) { return run_m4('VARIABLE','',$_[0]) } |
53 | sub var_site ($) { return run_m4('VARIABLE',$site,$_[0]) } |
54 | |
2dba6494 |
55 | check_junk("error in config",''); |
56 | |
57 | @actives= split /\s+/, run_m4('ACTIVES','',''); |
58 | @passives= split /\s+/, run_m4('PASSIVES','',''); |
59 | |
60 | foreach $site (@actives, @passives) { |
61 | check_junk("error in config for site $site",$site); |
62 | } |
63 | |
f685ef8c |
64 | $lgroup= var_global('lgroup'); |
65 | @lgroup= getgrnam($lgroup); |
66 | @lgroup or fault("invalid group $lgroup"); |
67 | $lgid= $lgroup[2]; |
68 | $forbid_remote= var_global('forbid_remote'); |
69 | @forbid_remote= (); |
70 | |
71 | sub parse_addr_mask ($) { |
72 | my ($r) = @_; |
73 | my ($mask,$iaddr); |
74 | if ($r =~ s,/(\d+)$,,) { $mask=$1; } else { $mask=32; } |
75 | fault("invalid mask length $1") if $mask<0 || $mask>32; |
76 | $mask= $mask ? ~0 << (32-$mask) : 0; |
77 | $iaddr= inet_aton($r); fault("invalid address $r") unless defined $iaddr; |
78 | $iaddr= (unpack "N",$iaddr)[0]; |
79 | return ($iaddr, $mask); |
80 | } |
81 | |
82 | foreach $r (split /[, \t]+/, $forbid_remote) { |
83 | push @forbid_remote, [ parse_addr_mask($r) ]; |
84 | } |
85 | |
86 | sub ipif_permit ($$$) { |
87 | my ($local,$net,$why) = @_; |
88 | my ($pmask,$piaddr,$fmask,$fiaddr); |
89 | if (!$local) { |
90 | ($piaddr,$pmask) = parse_addr_mask($net); |
91 | foreach $fref (@forbid_remote) { |
92 | ($fiaddr,$fmask) = @$fref; |
93 | $jmask= $fmask & $pmask; |
94 | #printf STDERR "%8lx %8lx %l8x %8lx", $pmask,$pmask |
95 | fault("local network $net claimed as remote ($why) by $site") |
96 | if (($fiaddr&$jmask) == ($piaddr&$jmask)); |
97 | } |
98 | } |
99 | $ipif_file .= "$lgid,$local$net, $lgroup, $why\n"; |
100 | } |
101 | |
102 | $glend= var_site('lend')."/32"; |
103 | if ($glend !~ m/^V_/) { |
104 | ipif_permit('=', "$glend", 'local endpoint'); |
105 | } |
106 | |
107 | foreach $site (@actives, @passives) { |
108 | $tlend= var_site('lend')."/32"; |
109 | if ($tlend != $glend) { |
110 | ipif_permit('=', $tlend.'/32', "$site - local endpoint"); |
111 | } |
112 | $trend= var_site('rend').'/32'; |
113 | $ix= 0; |
114 | $trnets= var_site('rnets'); |
115 | ipif_permit('', $trend, "$site - remote endpoint"); |
116 | if ($trnets ne '-') { |
117 | foreach $rnet (split /,/, $trnets) { |
118 | ipif_permit('', $rnet, "$site - remote network #$ix"); |
119 | $ix++; |
120 | } |
121 | } |
122 | } |
123 | |
124 | sub write_file ($$$$) { |
125 | my ($fn,$why,$head,$body) = @_; |
126 | length $fn or fault("location to write $why not specified"); |
127 | open F, ">$fn.new" or fault("create $fn.new: $!"); |
128 | print F $head."\n# AUTOGENERATED BY $0 - DO NOT EDIT\n".$body or die $!; |
129 | close F or die $!; |
130 | rename "$fn.new",$fn or die $!; |
131 | } |
132 | |
133 | write_file(var_global(ipifnetsfile),'ipifnetsfile','', $ipif_file); |
134 | |
135 | $active_file= ''; |
136 | $inittab= ''; |
137 | $ix= 0; |
138 | foreach $site (@actives) { |
139 | $active_file.= "$site\t".var_site('activesxinfo')."\n"; |
140 | $inittab.= sprintf("t%d", $ix++).':'.var_site('inittab_line')."\n"; |
141 | write_file(var_site('invoke_file'), 'invoke_file', |
142 | var_site('invoke_head'), |
143 | var_site('invoke_body')); |
144 | } |
145 | write_file(var_global('activesfile'),'activesfile', '',$active_file); |
146 | write_file(var_global('inittab_fragfile'),'inittab_fragfile', |
147 | "# You can cut and paste all or part of this into your inittab if you like.", |
148 | $inittab); |
149 | |
150 | $passive_file= ''; |
151 | foreach $site (@passives) { |
152 | $passive_file.= "$site\t".var_site('passivesxinfo')."\n"; |
153 | } |
154 | write_file(var_global('passivesfile'),'passivesfile', '',$passive_file); |
155 | |
156 | system var_global('postconfigure'); $? and exit -1; |
157 | |
158 | exit 0; |