network upgrade!

I’ve been wanting to upgrade to business class Road Runner for some time, but haven’t had the chance to do so until now. There’s a lot of reasons behind my wanting to do this, some of them are:

    • static IP addresses are only available via Road Runner’s business class offering

 

    • while download speeds are the same or less than residential, upload speed is significantly higher (on paper)

 

    • the residential cable modem I have only works at 10M half duplex for the ‘client’ side interface, which means while i run a gig-e or 100M full network in my home, I’m throttled to that at my uplink.

So, I put the call in, got the quote, signed it, and sent it back.
2 days later and I have a shiny new modem. But even better, I have this:

Bandwidth Thoughput from MyHouse to Various Places

 

rochester, ny (http://rochester.speedtest.frontiernet.net/)
   down - 7.013 Mbps
   up - 1.415 Mbps


los angeles, california (http://lax.speedtest.dslextreme.com/speed.php)
   down - 4.505 Mbps
   up - 1.385 Mbps


san francisco, california (http://helpme.att.net/dsl/speedtest/)
   down - 8.782 Mbps
   up - 1.460 Mbps


dallas, texas (http://www.gospeedtest.com/index.html)
   down - 4.075 Mbps
   up - 0.854 Mbps

ASNCheck Script

While working on a project today I decided that it would be handy to have a script that could take an AS number (from stdin or from a list of them) and check the health status of it (via things like DNSBL for example), specifically gathering information that could lead one to determine the relative infection/compromise level.

Ideally, such a script would be able to alternatively take an IP address, determine the AS for it and then report on both the IP provided as well as the overall “health” of the AS associated with it.

Well, some of that I managed to whip out tonight, though not all.

I’ll keep working on this, but I think it’s useful enough now to warrant posting (I normally do *not* make code public in this raw a state, so take note that there are very likely bugs in this).

That said, here’s ‘asncheck.py’.
In its current state, it just returns a list of IP addresses from a given AS which are in the dShield current watchlist.

#! /usr/bin/env python
# ------------------------------------------------
# asncheck:
# retrieves the current dshield watchlist for
# a given AS, returning just the IP addresses. 
# sample url:
# https://secure.dshield.org/asdetailsascii.html?as=123
# ------------------------------------------------
# written by:
# jason ross (algorythm@gmail.com)
# ------------------------------------------------
import sys

def main():
   # here beginneth the script
   opts = parmsdealer()

   if (opts.verbose == 1):
      print "nRetrieving information for AS Number " + opts.asn + ":n"
    
   if (opts.infile):
      try:
         filedata = open(opts.infile, 'rU')
      except IOError:
         print "unable to open input file '" + opts.infile + "'n"
         sys.exit(1)
      except:
          print "Unexpected error:", sys.exc_info()[0]
          sys.exit(1)
      else:
         for line in filedata:
            print line
            asn = line.split(opts.delim, 3)[int(opts.col)]
    
   if (opts.asn):
      asn = opts.asn

   dshield(asn, opts.verbose)

   #print '{0}.{1}.{2}.{3}'.format(oct1.zfill(3),oct2.zfill(3),oct3.zfill(3),oct4.zfill(3))


def parmsdealer():
   import sys
   from optparse import OptionParser
   version="nasncheck: version 0.1nauthor: jason ross <algorythm@gmail.com>n"
   usage="nn%prog [OPTIONS]n"
   parser = OptionParser(usage=usage, version=version)
   
   # set up command line arguments
   parser.set_defaults(col=0)
   parser.set_defaults(delim="|")
   parser.set_defaults(verbose=0)
    
   parser.add_option("-v", "--verbose", dest="verbose",
                     action="store_true", help="turn on/off verbosity (default: off)")
   parser.add_option("-a", "--asn", dest="asn",
                     action="store", help="specify the AS to retrieve data for (just the number, or with 'AS' prepended)")
   parser.add_option("-f", "--infile", dest="infile",
                     action="store", help="get the AS from the specified file (can be a list)")
   parser.add_option("-c", "--col", dest="col",
                     action="store", help="[required with -f] specifies which column in an input file contains the AS (default is to use the first column: '0')")
   parser.add_option("-d", "--delim", dest="delim",
                     action="store", help="[required with -f] specifies the delimiter to use when parsing the input file (default is to use the ASCII pipe character (0x7c):  '|')")
                     
   # process command line arguments
   (options, args) = parser.parse_args()
   
   # exit if we're missing options
   if (not options.asn and not options.infile):
      print "n" + sys.argv[0] + ": missing parameter(s)n"
      parser.print_help()
      print "n"
      sys.exit(1)
    
   # exit if we've got conflicting options
   if (options.asn and options.infile):
      print "n" + sys.argv[0] + ": can't set both an asn and an input file (there can be only one!)n"
      parser.print_help()
      print "n"
      sys.exit(1)

   return options


def dshield(asn, verbose):
   import socket
   import urllib
   import urllib2
   import re
    
   # urllib2 calls socket, so we can set the timeout here
   timeout = 5
   socket.setdefaulttimeout(timeout)

   baseuri = 'https://secure.dshield.org/asdetailsascii.html'

   params = {}
   params['as'] = asn
   encparams = urllib.urlencode(params)

   requri = baseuri + '?' + encparams
   req = urllib2.Request(requri)

   if (verbose == 1):
      print "opening " + requri + "n"

   try:
      res = urllib2.urlopen(req)
   except urllib2.URLError, e:
      if hasattr(e, "code"):
         print "site borked! HTTP error: " 
         print e.code
      elif hasattr(e, "reason"):
         print "server borked! reason: "
         print e.reason
   else:
      data = res.readlines()
#      print data
      for line in data:
         if ( re.match(r"[0-9]", line) ):
            ip = line.split()
            print ip[0]
      

if __name__ == "__main__":
   main()

ARP Ping Using Scapy

here’s a quick script i whipped up a while ago.
it uses scapy to perform an ARP ping of a network, and provides a CSV report of any MAC addresses it finds, along with the associated IP’s.

It requires tcpdump to be installed and in the $PATH, as well as root privs to run.

#!/usr/bin/env python
# note that this script requires tcpdump to be installed
# additionally, it requires root privs to run.
# ----
# Portions of this code can be attributed to the book
# Python for Unix and Linux System Administration
# by Noah Gift and Jeremy M. Jones. 
# Copyright 2008 Noah Gift and Jeremy M. Jones
# ISBN-13: 978-0-596-51582-9
# ----

import sys
if len(sys.argv) != 2:
    print "Usage: pingarp n  eg: pingarp 192.168.1.0/24"
    sys.exit(1)

from scapy import srp,Ether,ARP,conf
conf.verb=0
ans,unans=srp(Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst=sys.argv[1]),
              timeout=2)

print r"MAC,IP"
for snd,rcv in ans:
    print rcv.sprintf(r"%Ether.src%,%ARP.psrc%")

here’s sample output:

$ sudo ./pingarp 192.168.11.0/24
MAC,IP
00:16:01:8b:54:4a,192.168.11.1
00:13:ce:e9:6e:95,192.168.11.3
00:40:ca:8a:72:48,192.168.11.6