chiark / gitweb /
15d7615787554e5f0d7ff25a94a962c56ac5c4bd
[userv-utils.git] / ipif / alloc.pl
1 #!/usr/bin/perl
2
3 $etcdir= '/etc/userv/ipif';
4 chdir($etcdir) or die "$0: chdir $etcdir: $!\n";
5
6 $descallowd= '-][()+_\'":=;,./|';
7
8 sub usage () {
9     die <<END;
10 Allocates an RFC1918 address and records it
11 usage: userv ipif-alloc <group|gid> [<prefix>]/<size> <description>
12 <description> may contain alphanums, spaces and $descallowed
13 END
14 }
15
16 @ARGV==3 or usage();
17 ($group, $pfxsize, $desc) = @ARGV;
18
19 $super= 0;
20
21 open X, "config" or die "$0: open config: $!\n";
22 while (<X>) {
23     next if m/^\#/;
24     next if !m/\S/;
25     chomp; s/\s+$//;
26     if (m/^supergroup\s+(\w+)$/) {
27         $super= am_gid($1);
28     } elsif (m/^maxpergid\s+(\d+)$/) {
29         $maxpergid= $1;
30     } elsif (m,^range\s+([.0-9]+)/(\d+)$,) {
31         ($allow_p, $allow_m, $allow_l) = parse_range($1,$2);
32     } else {
33         die "$0: config:$.: unknown directive: $_\n";
34     }
35 }
36 close X or die "$0: read config: $!\n";
37
38 if ($pfxsize =~ m,^([.0-9]+)/(\d+)$,) {
39     ($want_p, $want_m, $want_l) = parse_range($1,$2);
40     if (!$super && !overlap($want_p,$want_m, $allow_p,$allow_m)) {
41         die "$0: permission denied (out of required range)\n";
42     }
43 } elsif ($pfxsize =~ m,^/(\d+)$,) {
44     undef $want_p;
45     undef $want_m;
46     $want_l= $1;
47 } else {
48     die "$0: bad request: $pfxsize\n";
49 }
50
51 $gid= get_gid($group);
52 if (!am_gid($gid)) {
53     die "$0: you are not gid $gid\n";
54 }
55
56 $op.= '';
57 $max_p= 0; $max_m= 0;
58
59 open Y, "auto-nets" or die "$0: open auto-nets: $!\n";
60 for (;;) {
61     $!= 0; chomp($_= <Y>);
62     length or die "$0: read auto-nets: $!\n";
63     last if m/^\#end/;
64     next if m/^\#/;
65     $op.= $_."\n";
66     m:^(\d+),([.0-9]+)/(\d+),.*: or die "$0: auto-nets:$.: syntax error: $_\n";
67     $this_gid= $1;
68     ($this_p, $this_m, $this_l) = parse_range($2,$3);
69     if (defined($want_p)) {
70         if (overlap($want_p,$want_m, $this_p,$this_m)) {
71             die "$0: overlaps with existing allocation (auto-nets:$.)\n";
72         }
73     } else {
74         if ($this_p > $max_p) {
75             ($this_p,$this_m) = ($max_p,$max_m);
76         }
77     }
78     
79     
80     next if $1 ne $gid;
81