3 # isc2ippool Insert ISC DHCPD lease entries into SQL database (ippool).
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 # Copyright (C) 2012 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
25 use DateTime::Format::Strptime;
26 use DateTime::Format::DBI;
32 my $lease_file = '/var/db/dhcpd.leases';
33 my $sql_type = 'mysql';
34 my $sql_host = 'localhost';
35 my $sql_user = 'radius';
36 my $sql_pass = 'radpass';
37 my $sql_database = 'radius';
38 my $sql_table = 'radippool';
40 my $pool_key = 'Calling-Station-Id';
47 print STDERR @_, "\n";
53 printf(shift . "\n", @_);
58 my @this = split('/', $0);
60 $this[$#this] [options] <pool>
63 -leases <lease file> - The lease file to parse (defaults to '$lease_file')
64 -pool-key <attribute> - The attribute used to identify the user (defaults to '$pool_key')
65 -no-update - Don't update existing lease entries
66 -type - SQL database type (defaults to '$sql_type')
67 -table - SQL table (defaults to '$sql_table')
68 -h | -host - SQL host to connect to
70 -p | -pass - SQL password
72 -help - This help text
79 'leases=s' => \$lease_file,
80 'pool-key=s' => \$pool_key,
81 'no-update' => \$insert_only,
82 'type=s' => \$sql_type,
83 'table=s' => \$sql_table,
84 'h|host=s' => \$sql_host,
85 'u|user=s' => \$sql_user,
86 'p|pass=s' => \$sql_pass,
89 ) or error('Failed parsing options');
92 # Poolname must be provided, and we need at least some arguments...
94 help if !scalar @ARGV or ($pool_name = $ARGV[$#ARGV]) =~ /^-/;
97 error("Lease file ($lease_file) doesn\'t exist or isn't readable");
99 my $leases = Text::DHCPLeases->new(file => $lease_file) or
100 error("Failed parsing leases file (or lease file empty)");
102 my $handle = DBI->connect(
103 "DBI:$sql_type:database=$sql_database;host=$sql_host",
104 $sql_user, $sql_pass, {RaiseError => 1}
107 my $dt_isc = DateTime::Format::Strptime->new(pattern => '%Y/%m/%d %H:%M:%S');
108 my $dt_sql = DateTime::Format::DBI->new($handle);
110 for my $lease ($leases->get_objects) {
111 next unless ($lease->binding_state && $lease->binding_state eq 'active');
115 $query = $handle->prepare("
116 SELECT expiry_time, framedipaddress FROM $sql_table
118 AND callingstationid = ?;"
121 $query->bind_param(1, $pool_name);
122 $query->bind_param(2, $lease->mac_address);
126 @result = $query->fetchrow_array();
131 my $ends_isc = $dt_isc->parse_datetime($lease->ends =~ m{^(?:[0-9]+) (.+)});
136 INSERT INTO $sql_table (
137 pool_name, framedipaddress,
138 calledstationid, callingstationid
139 expiry_time, pool_key)
140 VALUES (?, ?, ?, ?, ?, ?);"
144 , '00:00:00:00:00:00'
145 , $lease->mac_address
146 , $dt_sql->format_datetime($ends_isc)
153 notice("MAC:'%s' inserted with IP:'%s'.",
154 $lease->mac_address, $lease->ip_address);
159 my $ends_sql = $dt_sql->parse_datetime($result[0]);
161 if ($insert_only && (($result[1] ne $lease->ip_address) ||
162 (DateTime->compare($ends_sql, $ends_isc) < 0))) {
168 framedipaddress = ?, expiry_time = ?
170 AND callingstationid = ?;"
173 , $dt_sql->format_datetime($ends_isc)
175 , $lease->mac_address
181 notice("MAC:'%s' updated. ISC-TS: '%s', SQL-TS: '%s', ISC-IP: '%s', SQL-IP: '%s'.",
183 $dt_sql->format_datetime($ends_isc),
184 $dt_sql->format_datetime($ends_sql),
191 notice("MAC:'%s' skipped (no update %s). ",
192 $lease->mac_address, $insert_only ? 'allowed' : 'needed');