/[pxelator]/lib/PXElator/client.pm
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /lib/PXElator/client.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 399 - (hide annotations)
Tue Sep 8 18:09:01 2009 UTC (14 years, 7 months ago) by dpavlin
File size: 3750 byte(s)
use $server::new_clients tie

1 dpavlin 156 package client;
2    
3     use warnings;
4     use strict;
5     use autodie;
6    
7     use File::Slurp;
8 dpavlin 329 use Data::Dump qw/dump/;
9 dpavlin 395 use File::Path;
10 dpavlin 219
11     use server;
12 dpavlin 208 use format;
13 dpavlin 322 use ip;
14 dpavlin 330 use ping;
15 dpavlin 156
16 dpavlin 220 our $debug = $server::debug;
17    
18 dpavlin 219 sub mkbasedir {
19     my $path = shift;
20     $path =~ s{(^.*)/[^/]+$}{$1};
21     mkdir $path unless -d $path;
22     return $path;
23     }
24    
25 dpavlin 200 sub mac_path { $server::conf . '/mac/' . $_[0] }
26     sub ip_path { $server::conf . '/ip/' . join('/', @_) }
27 dpavlin 219 sub conf_value {
28     my $path = shift;
29     my $value;
30     if ( -l $path ) {
31     $value = readlink $path;
32     $value =~ s{.*/([^/]+)$}{$1};
33     } elsif ( -f $path ) {
34     $value = read_file $path;
35     } else {
36 dpavlin 244 warn "W: $path not file or symlink\n";
37 dpavlin 219 }
38     return $value;
39     }
40 dpavlin 200
41 dpavlin 156 sub conf {
42     my $ip = shift;
43     my $name = shift;
44     my ( $default, $value );
45     if ( $#_ == 0 ) {
46     $value = shift;
47     } elsif ( $#_ == 1 && $_[0] eq 'default' ) {
48     $default = $_[1]
49     }
50    
51 dpavlin 200 my $path = ip_path $ip;
52 dpavlin 156 mkdir $path unless -d $path;
53     $path .= '/' . $name;
54    
55     if ( defined $value ) {
56 dpavlin 219 mkbasedir $path;
57 dpavlin 156 write_file $path, $value;
58     warn "update $path = $value";
59     } elsif ( ! -e $path && defined $default ) {
60 dpavlin 219 mkbasedir $path;
61 dpavlin 156 write_file $path, $default;
62     warn "default $path = $default";
63     $value = $default;
64 dpavlin 219 } elsif ( -f $path ) {
65     $value = read_file $path;
66     } else {
67 dpavlin 220 warn "# $name missing $path\n" if $debug;
68 dpavlin 156 }
69     return $value;
70     }
71    
72 dpavlin 305 sub all_conf {
73     my $ip = shift;
74     my $path = ip_path $ip || return;
75     my $conf;
76     foreach my $file ( glob("$path/*") ) {
77     my $name = $file;
78     $name =~ s{^.+/([^/]+)$}{$1};
79     $conf->{ $name } = read_file $file;
80     }
81     return $conf;
82     }
83 dpavlin 200 sub next_ip($) {
84     my $mac = shift;
85 dpavlin 313 $mac = format::mac($mac);
86 dpavlin 168
87 dpavlin 399 if ( $server::new_clients-- ) {
88     warn "# clients left: $server::new_clients\n";
89 dpavlin 391 } else {
90     warn "W: no new clients accepted";
91     return '0.0.0.0';
92     }
93    
94 dpavlin 168 my $prefix = $server::ip;
95     $prefix =~ s{\.\d+$}{.};
96     my $addr = $server::ip_from || die;
97     my $ip = $prefix . $addr;
98    
99 dpavlin 330 while ( -e ip_path($ip) || ping::host($ip) ) {
100 dpavlin 168 $ip = $prefix . $addr++;
101     die "all addresses allocated!" if $addr == $server::ip_to;
102     warn "skip $ip\n";
103     }
104    
105     warn "next_ip $ip\n";
106 dpavlin 200
107 dpavlin 244 save_ip_mac( $ip, $mac );
108    
109     return $ip;
110     }
111    
112     sub save_ip_mac {
113     my ($ip,$mac) = @_;
114 dpavlin 313 $mac = format::mac($mac);
115 dpavlin 325 return if $mac eq '00:00:00:00:00:00';
116 dpavlin 244
117 dpavlin 254 mkdir ip_path($ip) unless -e ip_path($ip);
118 dpavlin 200
119 dpavlin 217 my $mac_path = mac_path($mac);
120 dpavlin 286 unlink $mac_path if -l $mac_path; # XXX audit?
121 dpavlin 217 symlink ip_path($ip), $mac_path;
122 dpavlin 323 write_file( ip_path($ip,'mac'), $mac );
123 dpavlin 168 }
124    
125 dpavlin 200 sub ip_from_mac($) {
126 dpavlin 194 my $mac = shift;
127 dpavlin 313 $mac = format::mac($mac);
128 dpavlin 194
129 dpavlin 200 my $mac_path = mac_path $mac;
130 dpavlin 194 return unless -e $mac_path;
131    
132     my $ip;
133    
134     if ( -f $mac_path ) {
135     $ip = read_file $mac_path;
136     unlink $mac_path;
137 dpavlin 200 symlink ip_path($ip), $mac_path;
138 dpavlin 194 warn "I: upgrade to mac symlink $mac_path\n";
139     } elsif ( -l $mac_path ) {
140 dpavlin 219 $ip = conf_value $mac_path;
141 dpavlin 194 } else {
142     die "$mac_path not file or symlink";
143     }
144    
145     return $ip;
146     }
147    
148 dpavlin 200 sub mac_from_ip($) {
149     my $ip = shift;
150 dpavlin 219 conf_value ip_path($ip, 'mac');
151 dpavlin 200 }
152    
153     sub change_ip($$) {
154     my ($old, $new) = @_;
155 dpavlin 323 return if $old eq $new;
156     my $mac = mac_from_ip($old) || die "no mac for $old";
157 dpavlin 200 rename ip_path($old), ip_path($new);
158     unlink mac_path($mac);
159     symlink ip_path($new), mac_path($mac);
160 dpavlin 323 return $new;
161 dpavlin 200 }
162    
163 dpavlin 322 sub all_ips {
164     sort { ip::to_int($a) cmp ip::to_int($b) }
165     map {
166     my $ip = $_;
167     $ip =~ s{^.+/ip/}{};
168     $ip;
169     } glob("$server::conf/ip/*")
170     }
171    
172 dpavlin 323 sub remove {
173     my $ip = shift;
174     unlink $_ foreach grep { -e $_ } ( glob "$server::conf/ip/$ip/*" );
175     if ( my $mac = mac_from_ip $ip ) {
176     unlink "$server::conf/mac/$mac";
177     }
178 dpavlin 395 rmtree "$server::conf/ip/$ip";
179 dpavlin 323 }
180    
181 dpavlin 329 sub arp_mac_dev {
182     my $arp = {
183     map {
184     my @c = split(/\s+/,$_);
185     if ( $#c == 5 ) {
186     client::save_ip_mac( $c[0], $c[3] );
187     ( uc $c[3] => $c[5] )
188     } else {
189     }
190     } read_file('/proc/net/arp')
191     };
192    
193     warn "# arp ",dump( $arp );
194     return $arp;
195     }
196    
197 dpavlin 156 1;

  ViewVC Help
Powered by ViewVC 1.1.26