#! /usr/local/bin/perl
# $Id: linksys_dhcp_fix.pl,v 1.11 2004/07/08 21:01:52 user Exp $
# Copyright (c) 2004 travis+web@subspacefield.org

=head1 NAME

linksys_dhcp_fix - renew Linksys BEFSR41 DHCP leases periodically

=head1 SYNOPSIS

linksys_dhcp_fix "My router passphrase"

=head1 DESCRIPTION

This program is a work-around for firmware bugs introduced into the
Linksys BEFSR41 firmware 1.45.11.  That firmware was itself supposed
to be a fix for a security hole (remote memory disclosure).

I suggest you run this every day from a cron job.

=head1 COPYRIGHT

Copyright 2004 travis+web@subspacefield.org

This program is released under the BSD copyright terms.

=cut

use strict;
use warnings;
$|++;

use HTML::Form;
require LWP;

die "You must supply a quoted passphrase as an argument.\n" unless $#ARGV == 0;
my $password = $ARGV[0];

my $ip = "192.168.1.1";

my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->env_proxy;
$ua->credentials("$ip:80", 'Linksys BEFSR41/BEFSR11/BEFSRU31', "", $password);

# Get main DHCP form page.
my $status = $ua->get("http://$ip/Status.htm");
die $status->status_line unless $status->is_success; # Bad passphrase?
# Parse it into a form object.
my $status_form = HTML::Form->parse($status);

my $response;
# Release and renew the DHCP lease.
# NOTE: I think when your lease has expired, a single release and renew
# only gets you an hour, so I renew twice which gets you a full day.
foreach ('0', '1', '1') {
    $status_form->value(dhcpAction => $_);
    $response = $ua->request($status_form->click);
    die $response->status_line unless $response->is_success;
}

exit 0;
