#!/usr/bin/perl -w
#Script for adding subnet configuration information into DHCP PostgreSQL database
#Writen by Chebotarev Roman (09.11.2008)

use strict;
use DBI;

if( scalar(@ARGV) < 9)
{
    print "Usage: $0 Default-GW GIAddr DNS-1 DNS-2 NetMask Server-ID Domain-Name Lease-Time Client-Subnet\n";
    exit;
}

sub ip_to_int
{
	my @octs = split(/\./, $_[0]);
	my $int_id = $octs[0] << 24;
	$int_id += $octs[1] << 16;
	$int_id += $octs[2] << 8;
	$int_id += $octs[3];
	return $int_id;
}

my $db_name = 'dhcp';
my $user = 'radius';
my $passwd = '';

my $default_gw = $ARGV[0];
my $giaddr = $ARGV[1];
my $dns1 = $ARGV[2];
my $dns2 = $ARGV[3];
my $netmask = $ARGV[4];
my $server_id = $ARGV[5];
my $domain_name = $ARGV[6];
my $lease_time = $ARGV[7];
my $interface_id = ip_to_int($giaddr);
my $int_subnet = ip_to_int($ARGV[8]);
my %attributes = (  'Default-GW' => $default_gw, 
                    'GIAddr' => $giaddr, 
                    'DNS-1' => $dns1, 
                    'DNS-2' => $dns2, 
                    'If-ID' => $interface_id,
                    'NetMask' => $netmask, 
                    'Server-ID' => $server_id, 
                    'Domain-Name' => $domain_name, 
                    'Lease-Time' => $lease_time,
					'Routes' => option_249($default_gw),
					'Renewing-Time' => int($lease_time * 0.875),
					'Rebinding-Time' => int($lease_time * 0.9)
					);
my ($query, $sth, $rv);
my ($ip, $inp, $outp);
my $attribute;


sub option_249 
{
	my @subnets = qw#10.0.0.0/8 172.16.0.0/12 192.168.0.0/16#;
	my $router = $_[0];
	my $out_str = '';
    my ($b0, $b1, $b2, $b3) = split(/\./, $router);
	my ($subnet, $mask);
    $out_str = sprintf('%02x', $b0);
    $out_str .= sprintf('%02x', $b1);
    $out_str .= sprintf('%02x', $b2);
    $out_str .= sprintf('%02x', $b3);
    foreach my $route (@subnets) 
	{
		($subnet, $mask) = split('/', $route);
		($b0, $b1, $b2, $b3) = split(/\./, $subnet);
		$out_str .= sprintf('%02x', $mask);
		$out_str .= sprintf('%02x', $b0);
		$out_str .= sprintf('%02x', $b1) if($mask > 8);
		$out_str .= sprintf('%02x', $b2) if($mask > 16);
		$out_str .= sprintf('%02x', $b3) if($mask > 24);
	}
	return $out_str;
}

#Start 
	my $db = DBI->connect("dbi:Pg:dbname=$db_name",$user,"", {PrintError => 0});

	if (defined($DBI::err)) 
	{
		print $DBI::errstr . "\n";
		exit($DBI::err);
	}

	foreach $attribute (keys(%attributes))
	{
		$query = "INSERT INTO if_table (interface_id, attribute, value, int_subnet)\    
								values($interface_id, '$attribute', '$attributes{$attribute}', $int_subnet)";
		print "QUERY: $query\n";
		$sth = $db->prepare($query);
		$rv = $sth->execute();
		if (!defined $rv) 
		{
			print "ERROR executing query '$query' : " . $db->errstr . "\n";
			last;
		}else {print "OK\n";}
	}
	$sth->finish();
	#Disconnect from DB
	$db->disconnect();
#End
