How to get local routing(BGP) info for South Africa

I recently went on a mission to discover, which subnets are “local” to South African networks, whether by ISP peering arrangements, or direct connection. I wanted this information, so that I could setup my home linux router to use Telkom’s ADSL connection for local traffic, and to use Sentech’s MyWireless connection for international traffic. Reason: Sentech pings aren’t really good for local gaming, but international speeds are great.

BGP (Border Gateway Protocol) 

All route information is published, and synchronized between ISP peers, via the BGP protocol, which is a dynamic routing protocol.

Unfortunately, it’s not as simple as install something like Zebra (a routing daemon for linux that does BGP, set it up on a Linux machine, receiving a BGP feend and have it make clever routing decisions.

No ISP will let you connect to their routers’ BGP port. Easily, or without a fight, or without paying them money for transit. This kind of public routing information, is unfortunately only available to the end-user via a series of public route-servers, and there aren’t any that I know that will allow you to receive the feed via BGP either.

So, I looked at alternative methods. I went from writing scripts to dig through the ripe, arin, and radb databases, to turning to lists of IP ranges arrange by geographic location. All the time, using whois queries to resolve the AS (AutonomousSystem) numbers, and then querying them for their official public routes. The problem is, that these routing databases aren’t always up to date, and that it’s quite difficult to figure out which AS numbers are actually local ISPs.

AS Numbers

An AS number is a  unique number, assigned by ARIN, or RIPE, that defines a BGP routing “area” or an ISP. Internet Solutions’ AS number is 3471. To see the details in the registry for an AS, go to http://www.radb.net/cgi-bin/radb/whois.cgi?obj=AS3741

To see the routes published by this AS, go to http://www.radb.net/cgi-bin/radb/whois.cgi?obj=!gAS3741

There is a set of RESERVED AS numbers, similar to “reserved” IP ranges that is supposed to be used for people that don’t have AS’s to obtain BGP information, or used for private or interior routing. Again, good luck in finding someone that’s prepared to configure a feed for you using a private AS, on a dynamic IP such as ADSL.

In the end, Gregory Massel, of http://www.ispmap.org.za/ fame, helped me to get hold of directly accessible BGP route information, courtesy of telnet://route-server.is.co.za, a public service by Internet Solutions. SAIX also runs a route-server at telnet://tpr-route-server.saix.net/
I wrote a small script that would telnet to this router, and dump the BGP routing table. This table contains local subnets, which is exactly what I was after.

From here on, it’s pretty simple to modify the script to add routes on my linux machine for these subnets on a specific interface. The net result in my scenario: ADSL gets used for local traffic, and Sentech for international.

Example script:

#!/usr/bin/perl

use Net::Telnet;

$prompt = '/public-route-server>/';
$server="route-server.is.co.za";

print "Connecting to $servern";
my $session = Net::Telnet->new(Host => $server,Prompt => $prompt,Timeout=>30);
unlink("t.log");
$session->dump_log("t.log");

$session->waitfor($prompt);

#turn off paging
$session->cmd("terminal length 0");

#get list of local routes
print "Retrieving BGP routes\n";
my @output = $session->cmd("show ip bgp\n");
print @output;
print "Route list received\n";
$session->close;
Author: roelf on November 19, 2006
Category: Internet
Tags: , , ,
4 responses to “How to get local routing(BGP) info for South Africa”
  1. rodch says:

    Hi,
    Thanks for this.

    BTW. Some of the \n nl chars in your perl script lost their \.(As seen by me in FFox)

    To reduce the size, I tried running the list through a couple of cidr subnet aggregators, which fail variously.

    I am cisco-illiterate, Any idea what a subnet like 196.3.161.0 , (without mask bits) means? One aggregator tries 196.3.161.0/32 another barfs with “line too long”

    A quick ping scan tells me there are live hosts within the 196.3.161.0/24 space.

    • roelf says:

      Hi Rod. A subnet without a mask means that it’s a “standard” class prefix. E.g. you can assume /24 for the 196.3.161.0 subnet, or /8 for a 21.23.0.0 subnet. It’s a bit schizophrenic I must admit.

  2. xarion says:

    Awesome, I found that the server now reports a: “local-route-server” prompt so for whoever wants to use the script just needs to change $prompt = ‘/public-route-server>/’; to $prompt = ‘/local-route-server>/’; How do I spew out just the address not all the other columns?

  3. Jaco says:

    Mod on Script:
    1) Use Saix server
    2) Display only destination subnet
    3) Add standard prefix where required

    #!/usr/bin/perl

    use Net::Telnet;

    $prompt=’/tpr-route-server>/’;

    $server=”tpr-route-server.saix.net”;

    $saix_cmd=”show ip bgp community 5713:56225\n”;

    print “Connecting to $server\n”;
    my $session = Net::Telnet->new(Host => $server,Prompt => $prompt,Timeout=>30);
    unlink(“t.log”);
    $session->dump_log(“t.log”);
    $session->login(“saix”, “saix”);

    #turn off paging
    $session->cmd(“terminal length 0”);

    #get list of local routes
    print “Retrieving BGP routes\n”;
    my @output = $session->cmd($saix_cmd);
    foreach (@output) {
    @fields = split(/\s+/);
    $fields[1] =~ s/^i//;
    @parts = split(/\./, $fields[1]);
    if ($parts[3] =~ /\//) {
    print $fields[1] . “\n”;
    } elsif ($parts[0] < 128) {
    print $fields[1] . "/8\n";
    } elsif ($parts[0] < 192) {
    print $fields[1] . "/16\n";
    } elsif ($parts[0] close;

Leave a Reply for roelf

You must be logged in to post a comment.

Last articles