ePMP update and default provisioning

This is one of the scripts we use on every radio that arrives into inventory.  It updates to 2.4.3 if it finds an earlier firmware. (which would be on the 10.1.1.254 default IP)  Then it updates to the "latest" firmware, as defined in the variables at the top of the script, and finally pushes a default config file to the radio based on whether it is 2.4GHz or 5.8GHz. (sets our password, community strings, WPA2 passphrase, timezone/NTP, etc)

We run it on an Ubuntu server, with (of course) the necessary Perl and SNMP packages installed.  I have it as /usr/bin/epmppreconf, executable of course.  I usually run it manually for each radio after it's plugged in and reachable, I used to have a version that waited for the radio to be reachable, did its thing, then waited for another - but that got complicated with two possible default IPs, so lately we just plug a radio in on the bench, rebox and label the previously-prepped unit, walk back to our workstations, hit cursor up and enter on the ssh session and run it again.  (if a radio doesn't have a green checkmark label on the box our guys are not allowed to touch it - that's the indicator that it's in inventory, updated, and defaulted for our network)

Note that the script as presented is configured for how our provisioning is set up - the server this runs on reaches the radios at 11.a.b.c.  From our workstations and servers, 11.anything goes to a provisioning router, which then NATs to 169.254.* and 10.* and 192.168.* IPs on the other side - handy, as long as we and the DoD don't actually need to reach one another... That same router has IPs on the radio side and NATs traffic going to 169.254.1.123 and 10.1.1.1 to return to the server, where the firmware and default files are accessible at the specified URLs.  (11.168.a.b gets netmapped to 192.168.a.b, 11.254.a.b gets netmapped to 169.254.a.b, and 11.a.b.c gets netmapped to 10.a.b.c - all our deployed radios are on 10.a.b.c scheme)

You'll need to ensure the machine this runs on and the one hosting the firmware and config files can reach the radios and vice-versa, and change the URLs and IPs defined at the top of the script to match your setup.  The simplest approach is to run this on a machine that is local to the radio it's provisioning, and put a 169.254.1.x and 10.1.1.x IP right on that machine.  (remember that out of the box the radio has no routes except to the defined default subnet)

You may also need to tweak the values in the "$hw==" comparisons - what I look for here are valid strings for ePMP radios in FCC region.

I also push the SNMP contact string to the radios.  Our network actually has two separate ISPs on it, so we use that field to distinguish WHOSE customer/radio we're monitoring once the radio is in service.  (you can just delete/comment every line with $contact in it if you don't need it)

Currently it prints a warning and exits if it sees a GPS-sync radio, and simply waits 4 minutes for updates to complete then checks that it's actually running the intended firmware.  I intend at some point to further develop the script to handle AP updates/defaults as well, and to actually monitor the update status so it knows when it's completed.  (or failed)

j

#!/usr/bin/perl

use Net::Ping;
use Term::ANSIColor;
use Net::SNMP;

$latest=“3.3”;
$latesturl=“http://169.254.1.123/fw/ePMP/ePMP-NonGPS_Synced-v3.3.tar.gz”;
$default24=“http://169.254.1.123/fw/ePMP/ePMP-SMDefault-2.4.bin”;
$default58=“http://169.254.1.123/fw/ePMP/ePMP-SMDefault-5.8.bin”;

$contact=“ESC-ePMP”;

$community=“private”;
$ip=“11.254.1.1”;
$legacy=“11.1.1.254”;
$legacyurl=“http://10.1.1.1/fw/ePMP/ePMP-NonGPS_Synced-v2.4.3.tar.gz”;

$band=0;

BEGINNING:
print “Preparing to upgrade ePMP1000 radio at $ip to v$latest.\n”;

#$p = Net::Ping->new();
#while (! $p->ping($ip,2))
#{}
#$p->close();
#sleep(1);

use Net::Ping;
my $p = Net::Ping->new();
my ($ret, $duration, $pip) = $p->ping($legacy,2);

if ($ret==1)
{
print “Unit is at legacy IP $legacy, gathering information.\n”;
my ($session, $error) = Net::SNMP->session(
-version => ‘snmpv2c’,
-hostname => $legacy,
-timeout => 4,
-retries => 2,
-maxmsgsize=>50000,
-community => $community,
-port => 161
);
if (!defined($session))
{
print “SNMP session ERROR scanning $ip: $error\n”;
exit 1;
}

my @varbindlist=['.1.3.6.1.4.1.17713.21.1.1.2.0','.1.3.6.1.4.1.17713.21.1.1.1.0'];
my $result = $session->get_request(
    -varbindlist => @varbindlist
);

if (!defined($result))
{
print "SNMP ERROR ($ip): $session->error\n";
$session->close;
exit 1;
}

my $hw=$result->{'.1.3.6.1.4.1.17713.21.1.1.2.0'};
if ($hw==0 || $hw==3 || $hw==10)
{
    print "This appears to be a GPS-synced radio, (hwinfo='$hw') I currently can't update it.\n";
    exit 1;
}

my $v=$result->{'.1.3.6.1.4.1.17713.21.1.1.1.0'};

if (index($v, “2.0”) != -1)

{

print "Running firmware $v, updating to 2.4.3 first, then $latest.\n";

my $result = $session->set_request( -varbindlist  => [ '.1.3.6.1.2.1.1.4.0',  OCTET_STRING, $contact ] );
    my $result = $session->set_request( -varbindlist  => [ '.1.3.6.1.4.1.17713.21.4.7.0',  OCTET_STRING, $legacyurl ] );
    my $result = $session->set_request( -varbindlist  => [ '.1.3.6.1.4.1.17713.21.4.4.0',  INTEGER, 1 ] );
print "Waiting 4 minutes for update to complete then proceeding...\n";
sleep 240;

}

$session->close;

}

while (! $p->ping($ip,2))
{
print “.”;
}
$p->close();
print “\n”;

my ($session, $error) = Net::SNMP->session(
-version => ‘snmpv2c’,
-hostname => $ip,
-timeout => 4,
-retries => 2,
-maxmsgsize=>50000,
-community => $community,
-port => 161
);
if (!defined($session))
{
print “SNMP session ERROR scanning $ip: $error\n”;
exit 1;
}

my @varbindlist=[’.1.3.6.1.4.1.17713.21.1.1.2.0’,’.1.3.6.1.4.1.17713.21.1.1.1.0’];
my $result = $session->get_request(
-varbindlist => @varbindlist
);

if (!defined($result))
{
print “SNMP ERROR ($ip): $session->error\n”;
$session->close;
exit 1;
}

my $hw=$result->{’.1.3.6.1.4.1.17713.21.1.1.2.0’};

if ($hw==3 || $hw==4 || $hw==5)
{
$band=2;
print “looks like a 2.4GHz radio.\n”;
}
elsif ($hw==0 || $hw==1 || $hw==2 || $hw==12)
{
$band=5;
print “looks like a 5GHz radio.\n”;
}
else
{
print “I don’t know what kind of radio this is, hwinfo reports $hw\n”;
exit 1;
}

print “This radio returns hwinfo=’$hw’ and band seems to be $band.\n”;

if ($hw==0 || $hw==3 || $hw==10)
{
print “This appears to be a GPS-synced radio, (hwinfo=’$hw’) I currently can’t update it.\n”;
exit 1;
}

my $result = $session->get_request(
-varbindlist => @varbindlist
);
if (!defined($result))
{
print “SNMP ERROR ($ip): $session->error\n”;
$session->close;
exit 1;
}
my $v=$result->{’.1.3.6.1.4.1.17713.21.1.1.1.0’};
if ($v!=$latest)
{
print “Running firmware $v, updating to $latest\n”;
my $result = $session->set_request( -varbindlist => [ ‘.1.3.6.1.2.1.1.4.0’, OCTET_STRING, $contact ] );
my $result = $session->set_request( -varbindlist => [ ‘.1.3.6.1.4.1.17713.21.4.7.0’, OCTET_STRING, $latesturl ] );
my $result = $session->set_request( -varbindlist => [ ‘.1.3.6.1.4.1.17713.21.4.4.0’, INTEGER, 1 ] );
print “Waiting 4 minutes for update to complete then proceeding…\n”;
sleep 240;
}

my $result = $session->get_request(
-varbindlist => @varbindlist
);
if (!defined($result))
{
print “SNMP ERROR ($ip): $session->error\n”;
$session->close;
exit 1;
}
my $v=$result->{’.1.3.6.1.4.1.17713.21.1.1.1.0’};
if ($v!=$latest)
{
print “Still running firmware $v, trying again to update to $latest\n”;
my $result = $session->set_request( -varbindlist => [ ‘.1.3.6.1.2.1.1.4.0’, OCTET_STRING, $contact ] );
my $result = $session->set_request( -varbindlist => [ ‘.1.3.6.1.4.1.17713.21.4.7.0’, OCTET_STRING, $latesturl ] );
my $result = $session->set_request( -varbindlist => [ ‘.1.3.6.1.4.1.17713.21.4.4.0’, INTEGER, 1 ] );
print “Waiting 5 minutes for update to complete then proceeding…\n”;
sleep 300;
}

my $result = $session->get_request(
-varbindlist => @varbindlist
);
if (!defined($result))
{
print “SNMP ERROR ($ip): $session->error\n”;
$session->close;
exit 1;
}
my $v=$result->{’.1.3.6.1.4.1.17713.21.1.1.1.0’};
if ($v==$latest)
{
print “running $latest firmware.\n”;
if ($band==2)
{
print “defaulting $ip with 2.4 default file ‘$default24’\n”;
my $result = $session->set_request( -varbindlist => [ ‘.1.3.6.1.4.1.17713.21.6.4.20.0’, OCTET_STRING, $default24 ] );
}
elsif ($band==5)
{
print “defaulting $ip with 5.8 default file ‘$default58’\n”;
my $result = $session->set_request( -varbindlist => [ ‘.1.3.6.1.4.1.17713.21.6.4.20.0’, OCTET_STRING, $default58 ] );
}
else
{
print “Can’t determine correct default file for $ip ($hw, $band) Not defaulting!\n”;
}
}
else
{
print “Failed to update radio to $latest! Aborting.\n”;

2 Likes

This is outstanding! Thanks