#!/usr/local/bin/python
import base64, getopt, urllib, httplib, os, re, sys, stat, string, time, telnetlib, socket, binascii

try:
  import syslog
except:  # for platforms without syslog that try to use --syslog option
  class fake_syslog:
    def openlog(self,foo):
      raise Exception("Syslog not supported on this platform")
    def syslog(self,foo):
      raise Exception("Syslog not supported on this platform")
  syslog = fake_syslog()

try:
  from pysnmp import session 
  from pysnmp import error 
except:  
  class fake_session:
    class session:
      def __init__(self, a, c):
        raise Exception("Pysnmp missing, see http://pysnmp.sourceforge.net/")
  session = fake_session()


Version = "0.157"

#
# ipcheck.py  
#
# Copyright GNU GENERAL PUBLIC LICENSE Version 2
# http://www.gnu.org/copyleft/gpl.html
#
# Author  : Kal <kal@users.sourceforge.net>
#
# Acknowledgements
# ================
# 
# dyndns crew             -a great service, reliable and professional
# Bobby Griggs            -ls_dyndns.py client 
# Vincent Zweije          -HTTP Date header idea for wuHHMM codes 
# Todd Rose               -Various suggestions and Linksys support 
# Yaron Minsky            -syslog patch and RT311 support
# Karen Chancellor        -RT311 tests
# Johannes Maslowski      -Draytek Vigor support
# Ulf Axelsson            -option -d fixes
# Del Hodge               -Netopia R9100 support
# Jan Bjorvik             -Cisco DSL support
# Robert Towster          -SMC barricade
# Onno Kortmann           -acctfile security suggestion
# Greg Bentz              -Linksys firmware 1.37, BSD Default route
# Erwin Burgstaller       -Cisco ISDN support
# Allen Eastwood          -HawkingTech support
# JP Szikora              -ZyXEL Prestige support
# Remi Zara               -NetBSD info
# Thomas Deselaers        -Debian package manpage
# Steve Warner            -SNMP support
# John Radimecky          -Watchguard SOHO support
# Mark Anderson           -router global var bug, time, testrun, docs
# Justin Kuo              -Nexland ISB2LAN
# Mark Lederer            -MacOS X
# Mark Aufflick           -Compex Netpassage 15
# Ken Frank               -UgatePlus, BSD 4.3 info
# Michel Bouissou         -Cayman DSL support
# Jan Carlson             -Gnet ADSL router model BB0040 support
# Tony Scicchitano        -BeOS local ip detection
# Bas Heijermans          -OS/2 tips and code
# Jeff Senn (jas)         -DLink DI701 w/PPPOE, Win32 Default Route
# Jim Richardson          -RT314 tests
# Andrew Gillham          -NetBSD route detection
# K Scott                 -Netgear logout page 
# Neal Probert            -custom dns bug
# Dave Burris             -sco openserver support
# Jerome Sautret          -Eicon modem support
# Daryl Boyd              -Nortel Instant Internet modem support
# John Ruttenberg         -Nexland Pro800Turbo support
# Tony Scicchitano        -New SMC Barricade with password
# Michael O'Quinn         -searching syslog option for IP
# Lucas Bruand            -Check datfile for "w" mode
# Jon Hart                -Pointing out 255 can be used in dotted quad
# Cedric Moreau           -Alcatel Speed Touch Pro
# Frank Adcock            -DLink DI804 patch
# Darren Tucker           -tracking down 404 handling error

#
# global constants
#
Updatehost = "members.dyndns.org"
Updatepage = "/nic/update"
Useragent = "ipcheck/" + Version

Touchage = 25                       # days after which to force an update

Linuxip = "/sbin/ifconfig"    
Win32ip = "ipconfig /all"      
Sunip = "/usr/sbin/ifconfig"	
BSDip = "/sbin/ifconfig"         
Macip = "/sbin/ifconfig"          
Beosip = "netstat"
Os2ip = "ifconfig"
scoip = "/etc/ifconfig"
Otherip = "/sbin/ifconfig"          

Linuxrt = "/sbin/route -n"
Win32rt = "route print"
Sunrt = "/bin/netstat -irn"
BSDrt = "/sbin/route -n get default"
Macrt = "/usr/sbin/netstat -r"
Beosrt = "netstat"
Os2rt = "netstat -r get default"
scort = "/usr/bin/netstat -nr"
Otherrt = "/sbin/route -n show"


# regular expression for address
Addressgrep = re.compile ('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')

def Usage():
  print
  print "Make sure you can write to the current directory for data"
  print "files and that you always run from the same directory."
  print "The first time you run the script, you will be asked to run"
  print "with the --makedat option in addition to any other options."
  print "This will create the data files for the hostnames and options "
  print "your specify on the command line.  You should only do this once."
  print "Subsequent runs should be made without the --makedat option."
  print
  print "For help with different options: python ipcheck.py -h"
  print "For supported devices listing  : python ipcheck.py --devices"
  print "For long detailed help text    : python ipcheck.py --help"
  print
  print "Example 1: the external IP is on eth0 of the current machine"
  print "python ipcheck.py -l -i eth0 username password hostnames"
  print
  print "Example 2: you are using the Linksys routing device"
  print "python ipcheck.py -l -L linksyspassword username password hostnames"
  print
  print "Example 3: you want to use web based ip detection"
  print "python ipcheck.py -l -r checkip.dyndns.org:8245 ..."
  print
  print "where ... is your dyndns username password and hostnames."
  print "Hostnames should be comma delimited if there are more than one."


def Options():
  print
  print "Usage  : ipcheck.py [options] Username Password Hostnames"
  print "or       ipcheck.py [options] --acctfile acct_info_file "
  print
  print "Options: -a address     manually specify the address "
  print "         -r URL         NAT router, use web IP detection "
  print "         -A text        scan syslog for an IP after text (Unix only) "
  print "         -F filename    guess the WAN IP from a firewall log "
  print "         -b             backup mx option ON (default OFF) " 
  print "         -c             custom dns option (default dynamic) "
  print "         -d dir         directory for data files (default current)"
  print "         -e script      execute script after a successful update "
  print "         -f             force update regardless of current state "
  print "         -g             NAT router, let dyndns guess your IP "
  print "                        (do not use this in a cronjob, try -r) "
  print "         -h             print this help text "
  print "         --help         print all available help text "
  print "         -i interface   interface for local address (default tun0) "
  print "         -j             disable https "
  print "         -l             log debugging text to ipcheck.log file "
  print "         --syslog       log debugging text to syslog (Unix only) "
  print "         -m mxhost      mx host (default NOCHG) "
  print "         -o             set dyndns offline mode "
  print "         -p             proxy bypass on port 8245 "
  print "         -q             quiet mode (unless there is an error) "
  print "         -s             static dns option (default dynamic) "
  print "         -t             test run, do not send the update "
  print "         -v             verbose mode "
  print "         -w             wildcard mode ON (default OFF) "
  print "         --makedat      create the ipcheck.dat file by dns lookup"
  print "         --devices      print router options (Linksys, Netgear, etc)"
  print "         -n ip   		the router IP address on the internal lan"
  print 
  print "For help with different options: python ipcheck.py -h"
  print "For supported devices listing  : python ipcheck.py --devices"
  print "For long detailed help text    : python ipcheck.py --help"
  print

def Devices():
  print
  print "The script will locate the address of your router automatically by "
  print "looking at the default route of the machine you are running on. "
  print "Then it will read the status page for the external IP address "
  print "and use that for updates.  You need to specify the admin password "
  print "with the appropriate option. "
  print
# remember -A already used above
  print "         -B password    New Barricade with password on port 88"
  print "         -C password    Cisco (667i) DSL router password "
  print "         -D password    Draytek (Vigor2000) NAT router password "
  print "         -E             Eicon Diva (no password needed) "
  print "         -G             UgatePlus (no password needed) "
# remember -F already used above
  print "         -H password    HawkingTech router password "
  print "         -I password    Cisco (700 series) ISDN router password "
  print "         -J password    ZyXEL prestige 642ME router password "
  print "         -K password    Compex NetPassage 15 "
  print "         -L password    Linksys (BEFSR41) NAT router password "
  print "         -M password    MacSense password "
  print "         -N password    Netgear (RT311) NAT router password "
  print "         -O password    Netopia (R9100) NAT router password "
  print "         -P port        Nexland Pro800Turbo, WAN port, "
  print "                        port=any to use first connected port; "
  print "                        port=[01] to use nth port (falls back to any);"
  print "                        port=-[01] to use nth port (no fall back)."
  print "         -Q pword,iface password and interface for Instant Internet "
  print "         -S             SMC Barricade (no password needed) "
  print "         -T password    Alcatel Speed Touch Pro password "
  print "         -V password    Eicon Diva (see -E for no password) "
  print "         -W password    Watchguard SOHO NAT firewall password "
  print "         -X             Nexland router (no password set) "
  print "         -Y password    Cayman DSL 3220H NAT router password "
  print "         -Z password    ZyXEL prestige 642R router password "
  print "         -4 password    Gnet model BB0040 ADSL router password "
  print "         -6 password    DLink DI704 password "
  print "         -7 password    DLink DI701 password "
  print "         -8 password    DLink DI804 password "
  print 
  print "You can change the default username for the above devices with: "
  print 
  print "         -U username    override the default NAT router username "
  print "                        leave this option out to use the default "
  print 
  print "For Cisco IOS devices and any others that understand SNMP, you "
  print "can also use --snmp to detect the external IP. "
  print 
  print "         --snmp snmp_agent,community,numeric_objectid "
  print 
  print "You will need the pysnmp module from http://pysnmp.sourceforge.net/ "
  print "You also need to know the agent, community and numeric objectid: "
  print "python ipcheck.py --snmp 172.62.254.254,public,.1.3.5.2.1.2.10.2.5.4 ..."
  print "where ... = username password hostnames "
  print

def HelpText():
  print
  print "Start ipcheck.py with no arguments to get some quick examples."
  print
  print "The script creates data files in the current working directory."
  print "Make sure you have write permission and that you run the script"
  print "from the same directory each time.  You can use the -d option"
  print "to specify an alternate directory for data files. "
  print
  print "The first time you run the script, you will be asked to run"
  print "with the --makedat option.  This will create the data files"
  print "and complete the update.  You should only do this once."
  print "Subsequent runs should be made without the --makedat option."
  print
  print "If -f is set, all hosts will be updated regardless of the "
  print "current error, wait or IP state.  You should never need this. "
  print
  print "You can place your username password and hostnames in a file "
  print "(all on the first line) and use the --acctfile option if you do "
  print "not wish your password to show up on a ps. "
  print
  print "The best way to run ipcheck is in the /etc/ppp/ip-up.local file "  
  print "or the BSD ppp.linkup file (you will need to sleep 30 before "
  print "running the script since ppp.linkup runs before the link is up.) "
  print "The script will also run from a cronjob.  Just make sure the "
  print "hostnames are the same in each execution.  You should make sure"
  print "it is using the same directory each time for data files.  The -d "
  print "option can be used to specify where data files go."
  print
  print "The file ipcheck.dat contains the IP address and hostnames "
  print "used in the last update.  If the ipcheck.dat file is older "
  print "than " + `Touchage` + " days, an update will be made to touch "
  print "the hostnames. "
  print 
  print "The file ipcheck.wait is created if dyndns requests a wait "
  print "before retrying.  This file will be automatically removed when "
  print "the wait is no longer in effect. "
  print
  print "The file ipcheck.err is created if the response is an error. "
  print "It will not try to update again until this error is resolved. "
  print "You must remove the file yourself once the problem is fixed. "
  print
  print "If your ISP has a badly behaved transparent proxy on port 80 " 
  print "traffic, you can try the -p option to use port 8245. "
  print
  print "If a http message is sent to dyndns.org, the response will be "
  print "saved in the ipcheck.html file." 
  print
  print "Custom domains can be specified with the -c option.  You must "
  print "first complete the create database step on the Dyndns web page. "
  print "Suppose you have the domain ipcheck.org defined as an A record "
  print "and your nodes aliased to ipcheck.org with CNAME records.  Use: "
  print "python ipcheck.py -c username password ipcheck.org "
  print
  print "Note that if you intended to maintain both a custom domain and " 
  print "a dyndns domain (ie. ipcheck.dyndns.org) you should be using "
  print "the -d option to keep the data files in separate directories. "
  print "The custom domains are not compatible with the offline, mx, "
  print "backmx and wildcard options.  Setup your database accordingly. "
  print
  print "The script can find your public IP address in one of several ways:"
  print 
  print "1) interface IP detection is the default method and appropriate"
  print "if the machine you are running on has an interface with the public"
  print "IP addressed assigned.  The script knows how to query various "
  print "operating systems for the address of an interface specified "
  print "with the -i option (default tun0).  Note on Win32 systems "
  print "specify the MAC address device after -i and on BeOS systems "
  print "specify the interface number after -i (eg. -i 1). "
  print 
  print "2) router IP detection is used if you have a routing device"
  print "such as a Netgear RT311.  Use the --devices option to get a"
  print "help on specific devices.  This method is used by the script"
  print "if you specify one of the device-related options."
  print 
  print "3) web IP detection may be used if your device is not supported"
  print "python ipcheck.py -r checkip.dyndns.org:8245 ... "
  print "where ... = username password hostnames "
  print "This method is used if you specify the -r option."
  print "IMPORTANT: Do not run web based IP detection more often "
  print "than once every 15 minutes.  It is costing dyndns bandwidth. "
  print
  print "4) you can explicitly set the desired IP address with -a"
  print
  print "5) when -g is used, the script will not send any IP address"
  print "at all (even ones detected by the previous options).  Only"
  print "the account information will be sent to the dyndns server."
  print "The dyndns server will assign the hostnames to the source"
  print "IP address of the request.  The assigned address is saved in"
  print "the ipcheck.dat file.  IMPORTANT: Do not run this from a cronjob"
  print "unless you know the address saved in the ipcheck.dat file "
  print "matches locally detected public IP to prevent unnecessary updates."
  print
  print "If your have an unsupported device and are willing to help with"
  print "some testing, email me. "
  print
  print "The ipcheck homepage can be found at:"
  print "http://ipcheck.sourceforge.net/"
  print
  print "Client development information can be found at:"
  print "http://support.dyndns.org/dyndns/clients/devel/"
  print
  print "Please include the ipcheck.log file if you email me with a problem. "
  print "kal@users.sourceforge.net"
  print

    
class Logger:
  #
  # open a new log file in the target dir if logging
  # a race condition if there are tons of scripts
  # starting at the same time and should really use locking
  # but that would be overkill for this app
  #
  def __init__(self, logname = "ipcheck.log", verbose = 0, logging = 0, use_syslog = 0):
    self.logname = logname
    self.verbose = verbose
    self.logging = logging
    self.syslog = use_syslog
    self.prefix = "ipcheck.py: "

    asctime = time.asctime(time.localtime(time.time()))

    if self.syslog == 1:
      syslog.openlog("ipcheck")
    if self.logging == 1:
      self.logfp = open(self.logname, "w")
      self.logfp.write(Useragent + "\n")
      self.logfp.write(self.prefix + asctime + "\n")
      self.logfp.write(self.prefix + "logging to " + self.logname + "\n")
      self.logfp.close()
    if self.verbose:
      print Useragent 
      print self.prefix + asctime 

  # normal logging message
  def logit(self, logline):
    if self.verbose:
      print self.prefix + logline
      if self.syslog:
        syslog.syslog(logline)
    if self.logging:
      self.logfp = open(self.logname, "a")
      self.logfp.write(self.prefix + logline + "\n")
      self.logfp.close()

  # logging message that gets printed even if not verbose
  def logexit(self, logline):
    print self.prefix + logline
    if self.logging:
      self.logfp = open(self.logname, "a")
      self.logfp.write(self.prefix + logline + "\n")
      self.logfp.close()
    if self.syslog:
      syslog.syslog(logline)


def DefaultRoute(logger, Tempfile):
  logger.logit("Searching default route on sys.platform = " + sys.platform)
  iphost = ""
  if sys.platform == "win32":
    logger.logit("WIN32 default route detection for router.")
    os.system (Win32rt + " > " + Tempfile)
    fp = open(Tempfile, "r")
    try:
     while 1:
      fileline = fp.readline()
      if not fileline:
        break
      # jas:
      # the code that was here did not work at all for the output
      # of 'route print' on my win98 box.
      # Here is a very simple version that works well...
      tst = string.split(fileline)
      if len(tst) > 2 and tst[0] == "0.0.0.0": 
        iphost = tst[2]
        break
    finally:
       fp.close()
  elif string.find(sys.platform, "linux") != -1:
    logger.logit("Linux default route detection for router.")
    os.system (Linuxrt + " > " + Tempfile)
    fp = open(Tempfile, "r")
    while 1:
      fileline = fp.readline()
      if not fileline:
        break
      p1 = string.find(fileline, "UG")
      if p1 != -1:
        ipmatch = Addressgrep.search(fileline)
        ip1 = ipmatch.group()
        p1 = string.find(fileline, ip1) + len(ip1)
        ipmatch = Addressgrep.search(fileline, p1)
        iphost = ipmatch.group()
        break
    fp.close()

  elif string.find(sys.platform, "sunos") != -1:
    logger.logit("Sunos default route detection for router.")
    os.system (Sunrt + " > " + Tempfile)
    fp = open(Tempfile, "r")
    while 1:
      fileline = fp.readline()
      if not fileline:
        break
      p1 = string.find(fileline, "default")
      if p1 != -1:
        ipmatch = Addressgrep.search(fileline, p1+8)
        iphost = ipmatch.group()
    fp.close()

  elif string.find(sys.platform, "Darwin") != -1:
    logger.logit("Darwin default route detection for router.")
    os.system (Macrt + " > " + Tempfile)
    fp = open(Tempfile, "r")
    while 1:
      fileline = fp.readline()
      if not fileline:
        break
      p1 = string.find(fileline, "default")
      if p1 != -1:
        ipmatch = Addressgrep.search(fileline, p1+8)
        iphost = ipmatch.group()
        break
    fp.close()

  elif string.find(sys.platform, "netbsd1") != -1:
    logger.logit("NetBSD default route detection for router.")
    os.system (BSDrt + " > " + Tempfile)
    fp = open(Tempfile, "r")
    while 1:
      fileline = fp.readline()
      if not fileline:
        break
      p1 = string.find(fileline, "gateway")
      if p1 != -1:
        ipmatch = Addressgrep.search(fileline, p1+8)
        iphost = ipmatch.group()
        break
    fp.close()

  elif string.find(sys.platform, "freebsd") != -1:
    logger.logit("Freebsd default route detection for router.")
    os.system (BSDrt + " > " + Tempfile)
    fp = open(Tempfile, "r")
    while 1:
      fileline = fp.readline()
      if not fileline:
        break
      p1 = string.find(fileline, "gateway")
      if p1 != -1:
        ipmatch = Addressgrep.search(fileline, p1+8)
        iphost = ipmatch.group()
        break
    fp.close()

  elif string.find(sys.platform, "os2") != -1:
    logger.logit("OS2 default route detection for router.")
    os.system (Os2rt + " > " + Tempfile)
    fp = open(Tempfile, "r")
    while 1:
      fileline = fp.readline()
      if not fileline:
        break
      p1 = string.find(fileline, "default")
      if p1 != -1:
        ipmatch = Addressgrep.search(fileline, p1+8)
        iphost = ipmatch.group()
        break
    fp.close()

  elif string.find(sys.platform, "sco_") != -1:
    logger.logit("SCO default route detection for router.")
    os.system (Scort + " > " + Tempfile)
    fp = open(Tempfile, "r")
    while 1:
      fileline = fp.readline()
      if not fileline:
        break
      p1 = string.find(fileline, "default")
      if p1 != -1:
        ipmatch = Addressgrep.search(fileline, p1+8)
        iphost = ipmatch.group()
        break
    fp.close()

  elif string.find(sys.platform, "beos") != -1:
    logger.logexit("BeOS default route detection via network settings file.")
    fp = open("/boot/home/config/settings/network", "r")
    while 1:
      fileline = fp.readline()
      if not fileline:
        break
      p1 = string.find(fileline, "ROUTER")
      if p1 != -1:
        ipmatch = Addressgrep.search(fileline, p1+8)
        iphost = ipmatch.group()
        break
    fp.close()

  else:
    logger.logit("Unknown platform default route detection for router.")
    os.system (Otherrt + " > " + Tempfile)
    fp = open(Tempfile, "r")
    while 1:
      fileline = fp.readline()
      if not fileline:
        break
      p1 = string.find(fileline, "default")
      if p1 != -1:
        ipmatch = Addressgrep.search(fileline, p1+8)
        iphost = ipmatch.group()
        break
    fp.close()

  return iphost


def BasicAuth(logger, iphost, page, user, passwd, outfile):

  ipdata = ""
  try:
    logger.logit("Basic authentication page: " + page)
    h1 = httplib.HTTP(iphost)
    h1.putrequest("GET", page)
    fakeagent = "Mozilla/4.76 [en] (X11; U; Linux 2.4.1-0.1.9 i586)"
    h1.putheader("USER-AGENT", fakeagent)
    authstring = base64.encodestring(user + ":" + passwd)
    authstring = string.replace(authstring, "\012", "")
    h1.putheader("AUTHORIZATION", "Basic " + authstring)
    h1.endheaders()
    errcode, errmsg, headers = h1.getreply()
    fp = h1.getfile()
    ipdata = fp.read()
    fp.close()
  except:
    logline = "Failed connecting to router at " + iphost
    logger.logexit(logline)
    logger.logexit("Exception: " + `sys.exc_info()[0]`)
    sys.exit(-1)

  # create an output file of the response
  fp = open(outfile, "w")
  fp.write(ipdata)
  fp.close()
  logger.logit(outfile + " file created")

  return ipdata



#
# taken directly from the examples directory in pysnmp distribution
# http://pysnmp.sourceforge.net/
#
# results of run are stored in retval and returned
#
class snmptable (session.session):
    """Retrieve a table from remote SNMP process
    """
    def __init__ (self, agent, community):
        """Explicitly call superclass's constructor as it gets overloaded
           by this class constructor and pass a few arguments alone.
        """   
        session.session.__init__ (self, agent, community)

    def run (self, objids):
        """Query SNMP agent for one or more Object IDs. The objid
           argument should be a list of strings where each string
           represents an Object ID in dotted numbers notation
           (e.g. ['.1.3.6.1.4.1.307.3.2.1.1.1.4.1']).
        """   

        # clear the retval
        retval = []

        # Convert string type Object ID's into numeric representation
        numeric_objids = map (self.str2nums, objids)

        # BER encode SNMP Object ID's to query
        encoded_objids = map (self.encode_oid, numeric_objids)

        # Since we are going to _query_ SNMP agent for Object ID's
        # associated value, there will be no variable values passed to
        # SNMP agent.
        encoded_values = []

        # Remember the beginning of the table
        head_encoded_objid = encoded_objids[0]
        
        # Traverse the agent's MIB
        while 1:
            # Build a complete SNMP message of type 'GETNEXTREQUEST', pass it
            # a list BER encoded Object ID's to query and an empty list of values
            # associated with these Object ID's (empty list as there is no point
            # to pass any variables values along the SNMP GETNEXT request)
            question = self.encode_request ('GETNEXTREQUEST', encoded_objids, encoded_values)

            # Try to send SNMP message to SNMP agent and receive a response.
            answer = self.send_and_receive (question)

            # Catch SNMP exceptions
            try:
                # As we get a response from SNMP agent, try to disassemble SNMP reply
                # and extract two lists of BER encoded SNMP Object ID's and 
                # associated values).
                (encoded_objids, encoded_values) = self.decode_response (answer)

            # SNMP agent reports 'no such name' when table is over
            except error.SNMPError, why:
                # If NoSuchName
                if why.status == 2:
                    # Return as we are done
                    return retval
                else:
                    raise error.SNMPError(why.status, why.index)

            # Stop at the end of the table
            if not self.oid_prefix_check (head_encoded_objid, encoded_objids[0]):
                # Return as we are done
                return retval
            
            # Decode BER encoded Object ID.
            objids = map (self.decode_value, encoded_objids)

            # Decode BER encoded values associated with Object ID's.
            values = map (self.decode_value, encoded_values)

            # Convert two lists into a list of tuples for easier printing
            results = map (None, objids, values)

            # Just print them out
            # for (objid, value) in results:
            #    print objid + ' ---> ' + str(value)
            retval = retval + results



def _main(argv):

  # 
  # ROUTER SUPPORT GLOBALS 
  # 
  # leave Linksys_host = "" to autodetect via the default route 
  # enter an ip here to skip the autodetect, this goes for all
  # the xxxx_host variables below
  # 
  routerIP = ""

  # 
  # Linksys router support details from bgriggs@pobox.com
  # 
  Linksys_host = ""
  Linksys_user = " "
  Linksys_page = "/Status.htm"
  
  Macsense_host = ""
  Macsense_user = " "
  Macsense_page = "/Status.htm"

  # 
  # Netgear router support 
  # 
  Netgear_host = ""
  Netgear_user = "admin"
  Netgear_page = "/mtenSysStatus.html"
  Netgear314_page1 = "/rpMten.html"
  Netgear314_page2 = "/mtenSysStatus.html"
  NetgearFR_page = "/auth.html"
  Netgear_logout = "/Logout.html"

  # 
  # DLink DI-804 router support 
  # 
  DI804_host = ""
  DI804_user = "admin"
  DI804_page = "/doc/m3.htm"
  DI804FR_page = "/auth.html"
  
  # 
  # DLink DI-704 router support 
  # 
  DI704_host = ""
  DI704_user = "root"
  DI704_page = "/cgi-bin/logi"
  DI704FR_page = "/menu.html"
  
  # 
  # Draytek Vigor2000 router support 
  # 
  Draytek_host = ""
  Draytek_user = "admin"
  Draytek_page = "/doc/digisdn.sht"
  
  # 
  # Netopia R9100 router support 
  # 
  Netopia_host = ""
  Netopia_user = ""
  Netopia_page = "/WanEvtLog"
  
  # 
  # Cisco routers (667 and 770) 
  # uses telnet with no user name
  # 
  Cisco_host = ""
  ISDNCisco_host = ""
  
  # 
  # SMC Barricade
  # 
  SMC_host = ""
  SMC_page = "/status.htm"
  #username and password are not needed 
  
  # 
  # HawkingTech router support 
  # 
  Hawking_host = ""
  Hawking_user = "admin"
  Hawking_page = "/Monitor.htm"
  
  # 
  # ZyXEL router support, uses telnet
  # 
  Zyxel_host = ""
  Zyxel_ME_host = ""
  
  # 
  # DI701 router support, uses telnet
  # 
  DI701_host = ""
  
  #
  # Watchguard SOHO firewall/router support
  #
  Watchguard_host = ""
  Watchguard_user = "admin"
  Watchguard_page = "/sysstat.htm"
  Watchguard_page2 = "/external.htm"
  
  # 
  # Nexland (but see Pro800Turbo, below)
  # 
  Nexland_host = ""
  Nexland_page = "/status.htm"
  #username and password are not needed 

  # 
  # Nexland Pro800Turbo
  # 
  Pro800Turbo_host = ""
  Pro800Turbo_page = "/status.html"
  Pro800Turbo_port = "any"
  Pro800Turbo_port_number = 0
  #username and password are not needed 

  # 
  # UgatePlus 
  # 
  Ugate_host = ""
  Ugate_page = "/st_dhcp.htm"
  #username and password are not needed 

  #
  # Eicon Diva 2430 SE ADSL Modem
  #
  Eicon_host = ""
  Eicon_page = "/Status.htm"
  #username and password are not needed

  # 
  # Eicon Diva with password 
  # 
  Veicon_host = ""
  Veicon_user = ""
  Veicon_page = "/login.htm"
  
  # Instant Internet router
  II_host = ""

  # 
  # Compex NetPassage 15
  # uses telnet with no username
  # 
  Compex_host = ""

  #
  # Cayman DSL 3220-H
  # uses telnet
  #
  Cayman_host = ""
  Cayman_user = "ipcheck"
  
  #
  # Gnet model BB0040 ADSL router
  # uses telnet
  #
  Gnet_host = ""
  Gnet_user = ""
  
  # 
  # Newer SMC Barricade with password on port 88
  # 
  Barricade_host = ""
  Barricade_user = "admin"
  Barricade_page = "/status.HTM"
  
  #
  # Alcatel Speed Touch Pro uses telnet
  #
  AlcatelSTP_host = ""
  # username is not needed

  #
  # default options
  #
  opt_address = ""
  opt_force = 0
  opt_logging = 0
  opt_syslog  = 0
  opt_verbose = 0
  opt_hostnames = ""
  opt_interface = "tun0"
  opt_username = ""
  opt_password = ""
  opt_static = 0
  opt_wildcard = 0
  opt_backupmx = 0
  opt_mxhost = "NOCHG"
  opt_proxy = 0
  opt_router = ""
  opt_guess = 0
  opt_quiet = 0
  opt_offline = 0
  opt_execute = ""
  opt_directory = ""
  opt_acctfile = ""
  opt_natuser = ""
  opt_Linksys_password = ""
  opt_Linksys_router = 0
  opt_Netgear_password = ""
  opt_Draytek_password = ""
  opt_Netopia_password = ""
  opt_Cisco_password = ""
  opt_SMC_router = 0
  opt_Nexland_router = 0
  opt_Pro800Turbo_router = 0
  opt_ISDNCisco_password = ""
  opt_Hawking_password = ""
  opt_Zyxel_password = ""
  opt_Zyxel_ME_password = ""
  opt_Watchguard_password = ""
  opt_DI704_password = ""
  opt_DI701_password = ""
  opt_DI804_password = ""
  opt_snmp_agent = ""
  opt_snmp_community = ""
  opt_snmp_objectid = ""
  opt_snmp_agent_prefix = ""
  opt_custom = 0
  opt_testrun = 0
  opt_makedat = 0
  opt_Compex_password = ""
  opt_Cayman_password = ""
  opt_Gnet_password = ""
  opt_Ugate_router = 0
  opt_II_password = ""
  opt_II_interface = ""
  opt_Eicon_router = 0
  opt_Veicon_password = ""
  opt_Barricade_password = ""
  opt_after_syslog = ""
  opt_firewall_log = ""
  opt_Macsense_password = ""
  opt_AlcatelSTP_password = ""
  opt_no_https = 0


  #
  # parse the command line options
  #
  if len(argv) == 1:
    Usage()
    sys.exit(0)
  
  try:
    # old version has errors
    #opts, args = getopt.getopt(argv[1:], "a:bcd:e:hi:flm:qpr:stvwgL:oN:U:D:O:C:SI:H:Z:W:XP:M:G:Y:4:7:EQ:V:B:A:F:P:J:K:", ["syslog", "acctfile=", "help", "devices", "snmp=", "makedat"])
    #
    loweropts = "a:bcd:e:fghi:jlm:n:opqr:stvw"
    upperopts = "A:B:C:D:EF:GH:I:J:K:L:M:N:O:P:Q:ST:V:W:XY:Z:4:6:7:8:"
    wordopts = ["syslog", "acctfile=", "help", "devices", "snmp=", "makedat"]
    opts, args = getopt.getopt(argv[1:], loweropts+upperopts, wordopts)
  except getopt.error, reason:
    print reason
    sys.exit(-1)

  #
  # PYTHON GURU NEEDED
  #
  # Is there any way in python to set argv to hide the command line?
  # ala the perl $0 = "orcus [accepting connections]";
  #
  # http://theoryx5.uwinnipeg.ca/CPAN/perl/pod/perlfaq8/Is_there_a_way_to_hide_perl_s_command_line_from_programs_such_as_ps_.html
  #

  #
  # check verbose, logging and detailed help options first
  # check directory to place logging file
  #
  for opt in opts:
    (lopt, ropt) = opt
    if lopt == "-l":
      opt_logging = 1
    elif lopt == "--syslog":
      opt_syslog = 1
    elif lopt == "-v":
      opt_verbose = 1
    elif lopt == "--devices":
      Devices()
      sys.exit(0)
    elif lopt == "--help":
      Usage()
      Options()
      Devices()
      HelpText()
      sys.exit(0)
    elif lopt == "-h":
      Options()
      sys.exit(0)
    elif lopt == "-d":
      if os.path.isdir(ropt):
        opt_directory = ropt
      else:
        print "bad directory option"
        sys.exit()

      # fix the dir name to end in slash
      if opt_directory[-1:] != "/":
        opt_directory = opt_directory + "/"

  #
  # create the logger object
  #
  if opt_directory == "":
    logger = Logger("ipcheck.log", opt_verbose, opt_logging, opt_syslog)
  else:
    logger = Logger(opt_directory + "ipcheck.log", opt_verbose, opt_logging, opt_syslog)
    logline = "opt_directory set to " + opt_directory
    logger.logit(logline)

  #
  # check acctfile option
  #
  for opt in opts:
    (lopt, ropt) = opt
    if lopt == "--acctfile":
      opt_acctfile = ropt
      logline = "opt_acctfile set to " + opt_acctfile
      logger.logit(logline)

  if len(args) != 3 and opt_acctfile == "":
    Usage()
    sys.exit(0)

  #
  # okay now parse rest of the options and log as needed
  #
  for opt in opts:
    (lopt, ropt) = opt
    if lopt == "-a":
      opt_address = ropt
      logline = "opt_address set to " + opt_address
      logger.logit(logline)
    elif lopt == "-i":
      opt_interface = ropt
      logline = "opt_interface set to " + opt_interface
      logger.logit(logline)
    elif lopt == "-f":
      opt_force = 1
      logline = "opt_force set " 
      logger.logit(logline)
    elif lopt == "-j":
      opt_no_https = 1
      logline = "opt_no_https set " 
      logger.logit(logline)
    elif lopt == "-w":
      opt_wildcard = 1
      logline = "opt_wildcard set " 
      logger.logit(logline)
    elif lopt == "-s":
      opt_static = 1
      logline = "opt_static set " 
      logger.logit(logline)
    elif lopt == "-c":
      opt_custom = 1
      logline = "opt_custom set " 
      logger.logit(logline)
    elif lopt == "-b":
      opt_backupmx = 1
      logline = "opt_backupmx set " 
      logger.logit(logline)
    elif lopt == "-p":
      opt_proxy = 1
      logline = "opt_proxy set " 
      logger.logit(logline)
    elif lopt == "-m":
      opt_mxhost = ropt
      logline = "opt_mxhost set to " + opt_mxhost
      logger.logit(logline)
    elif lopt == "-r":
      opt_router = ropt
      logline = "opt_router set to " + opt_router
      logger.logit(logline)
    elif lopt == "-g":
      opt_guess = 1
      logline = "opt_guess set " 
      logger.logit(logline)
    elif lopt == "-t":
      opt_testrun = 1
      logline = "opt_testrun set " 
      logger.logit(logline)
    elif lopt == "--makedat":
      opt_makedat = 1
      logline = "opt_makedat set " 
      logger.logit(logline)
    elif lopt == "-q":
      opt_quiet = 1
      logline = "opt_quiet set " 
      logger.logit(logline)
    elif lopt == "-o":
      opt_offline = 1
      logline = "opt_offline set " 
      logger.logit(logline)
    elif lopt == "-e":
      opt_execute = ropt
      logline = "opt_execute set to " + opt_execute
      logger.logit(logline)
    elif lopt == "-U":
      opt_natuser = ropt
      logline = "opt_natuser set to " + opt_natuser
      logger.logit(logline)

      Linksys_user = opt_natuser
      Macsense_user = opt_natuser
      Netgear_user = opt_natuser
      Draytek_user = opt_natuser
      Netopia_user = opt_natuser
      Hawking_user = opt_natuser
      Watchguard_user = opt_natuser
      Veicon_user = opt_natuser
      Cayman_user = opt_natuser
      Gnet_user = opt_natuser
      Barricade_user = opt_natuser
      DI804_user = opt_natuser

    elif lopt == "-M":
      opt_Macsense_password = ropt
      logline = "opt_Macsense_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-L":
      opt_Linksys_router = 1
      opt_Linksys_password = ropt
      logline = "opt_Linksys_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-N":
      opt_Netgear_password = ropt
      logline = "opt_Netgear_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-D":
      opt_Draytek_password = ropt
      logline = "opt_Draytek_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-O":
      opt_Netopia_password = ropt
      logline = "opt_Netopia_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-C":
      opt_Cisco_password = ropt
      logline = "opt_Cisco_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-S":
      opt_SMC_router = 1
      logline = "opt_SMC_router set " 
      logger.logit(logline)
    elif lopt == "-G":
      opt_Ugate_router = 1
      logline = "opt_Ugate_router set " 
      logger.logit(logline)
    elif lopt == "-E":
      opt_Eicon_router = 1
      logline = "opt_Eicon_router set "
      logger.logit(logline)
    elif lopt == "-V":
      opt_Veicon_password = ropt
      logline = "opt_Veicon_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-B":
      opt_Barricade_password = ropt
      logline = "opt_Barricade_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-Q":
      Qopts = string.split(ropt, ",")
      if len(Qopts) != 2:
        logline = "Bad -Q option: " + ropt
        logger.logexit(logline)
        sys.exit(-1)
      opt_II_password = Qopts[0]
      opt_II_interface = Qopts[1]
      logline = "opt_II_password = "
      for x in xrange(0, len(opt_II_password)):
        logline = logline + "*"
      logger.logit(logline)
      logline = "opt_II_interface = " + opt_II_interface
      logger.logit(logline)
    elif lopt == "-X":
      opt_Nexland_router = 1
      logline = "opt_Nexland_router set " 
      logger.logit(logline)
    elif lopt == "-P":
      opt_Pro800Turbo_router = 1
      ropt_save = ropt
      if ropt == 'any':
        Pro800Turbo_port = 'any'
      else:
        if ropt[0] == '-':
          Pro800Turbo_port = 'force'
          ropt = ropt[1:]
        else:
          Pro800Turbo_port = 'prefer'        
        try:
          ropt_int = string.atoi(ropt)
          if ropt_int < -1 or ropt_int > 1:
            raise ValueError("invalid port value %s" % (ropt_save))
          Pro800Turbo_port_number = ropt_int
        except:
          logline = "Bad -P option %s" % (ropt_save)
          logger.logit(logline)
          sys.exit(-1)
      logline = "opt_Pro800Turbo port %s %d" % (Pro800Turbo_port,
                                                Pro800Turbo_port_number)
      logger.logit(logline)
    elif lopt == "-I":
      opt_ISDNCisco_password = ropt
      logline = "opt_ISDNCisco_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-H":
      opt_Hawking_password = ropt
      logline = "opt_Hawking_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-J":
      opt_Zyxel_ME_password = ropt
      logline = "opt_Zyxel_ME_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-Z":
      opt_Zyxel_password = ropt
      logline = "opt_Zyxel_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-4":
      opt_Gnet_password = ropt
      logline = "opt_Gnet_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-6":
      opt_DI704_password = ropt
      logline = "opt_DI704_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-7":
      opt_DI701_password = ropt
      logline = "opt_DI701_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-8":
      opt_DI804_password = ropt
      logline = "opt_DI804_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-W":
      opt_Watchguard_password = ropt
      logline = "opt_Watchguard_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-K":
      opt_Compex_password = ropt
      logline = "opt_Compex_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-A":
      opt_after_syslog = ropt
      logline = "opt_after_syslog = " + ropt
      logger.logit(logline)
    elif lopt == "-F":
      opt_firewall_log = ropt
      logline = "opt_firewall_log = " + ropt
      logger.logit(logline)
    elif lopt == "-Y":
      opt_Cayman_password = ropt
      logline = "opt_Cayman_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-T":
      opt_AlcatelSTP_password = ropt
      logline = "opt_AlcatelSTP_password = "
      for x in xrange(0, len(ropt)):
        logline = logline + "*"
      logger.logit(logline)
    elif lopt == "-n":
	  routerIP = ropt
	  logline = "opt_router_ip = " + ropt
	  logger.logit(logline)

    elif lopt == "--snmp":

      snmpopts = string.split(ropt, ",")
      if len(snmpopts) != 3:
        logline = "Bad --snmp option: " + ropt
        logger.logexit(logline)
        sys.exit(-1)

      #
      # check snmp agent is an IP address
      #
      opt_snmp_agent = snmpopts[0]
      p1 = string.find(opt_snmp_agent, ".")
      p2 = string.find(opt_snmp_agent, ".", p1+1)
      p3 = string.find(opt_snmp_agent, ".", p2+1)
      p4 = string.find(opt_snmp_agent, ".", p3+1)
      if p1 == -1 or p2 == -1 or p3 == -1 or p4 != -1:
        logline = opt_snmp_agent + " bad snmp agent, IP address required"
        logger.logexit(logline)
        sys.exit(-1)
      opt_snmp_agent_prefix = opt_snmp_agent[:p2]
  
      #
      # community can be anything
      #
      opt_snmp_community = snmpopts[1]

      #
      # check the objectid is numeric
      #
      opt_snmp_objectid = snmpopts[2]
      #objid_s = string.split(opt_snmp_objectid, '.')
      #objid_s = filter(lambda x: len(x), objid_s)
      #try:
      #  objid_n = map(lambda x: string.atol(x), objid_s)
      #except:
      #  logline = opt_snmp_objectid + " bad snmp objectid, numeric id required"
      #  logger.logexit(logline)
      #  sys.exit(-1)

      logger.logit("opt_snmp_agent = " + opt_snmp_agent)
      logger.logit("opt_snmp_agent_prefix = " + opt_snmp_agent_prefix)
      logger.logit("opt_snmp_community = " + opt_snmp_community)
      logger.logit("opt_snmp_objectid = " + opt_snmp_objectid)


  #
  # store the command line arguments
  #
  if opt_acctfile != "":
    try:
      fp = open (opt_acctfile, "r")
      acctdata = fp.read()
      fp.close()
    except:
      logline = "Bad acctfile: " + opt_acctfile
      logger.logexit(logline)
      logger.logexit("Exception: " + `sys.exc_info()[0]`)
      sys.exit(-1)
    args = string.split(acctdata)
    if len(args) != 3:
      logline = "File does not contain 3 arguments: " + opt_acctfile
      logger.logexit(logline)
      sys.exit(-1)

  opt_username = args[0] 
  logline = "opt_username = " + opt_username
  logger.logit(logline)

  opt_password = args[1] 
  logline = "opt_password = " 
  for x in xrange(0, len(opt_password)):
    logline = logline + "*"
  logger.logit(logline)

  opt_hostnames = args[2] 
  logline = "opt_hostnames = " + opt_hostnames
  logger.logit(logline)
  hostnames = string.split(opt_hostnames, ",")
    
  #
  # taint check, make sure each hostname is a dotted fqdn
  #
  for host in hostnames:
    if string.find(host, ".") == -1:
      logline = "Bad hostname: " + host
      logger.logexit(logline)
      sys.exit(-1)

  #
  # check if hostname is a custom domain
  #
  domains = ["dyndns.org","homeip.net","ath.cx","mine.nu","shacknet.nu","merseine.nu","dnsalias.com","dnsalias.net","dnsalias.org","dyndns.tv","dyndns.ws","dyndns.info", "dyndns.biz", "homedns.org", "homeftp.net", "homeftp.org", "homelinux.com", "homelinux.net", "homelinux.org", "homeunix.com", "homeunix.net", "homeunix.org", "kicks-ass.net", "kicks-ass.org", "serveftp.net", "serveftp.org"]
  if opt_custom == 0:
    for host in hostnames:
      h = string.lower(host)
      known = 0
      for dom in domains:
        if string.find(h, dom) != -1:
          known = 1 
          break
      if known == 0:
        logline = "Unknown domain: " + host
        logger.logexit(logline)
        logger.logexit("You should be using -c for custom domains.")
        sys.exit(-1)




  #
  # taint check the mx host
  #
  if opt_mxhost != "":
    if string.find(opt_mxhost, "NOCHG") != -1:
      opt_mxhost = "NOCHG"
    elif string.find(opt_mxhost, ".") == -1:
      logline = "Bad mxhost: " + opt_mxhost
      logger.logexit(logline)
      sys.exit(-1)

  #
  # log the pwd
  #
  if os.environ.has_key("PWD"):
    logger.logit("PWD = " + os.environ["PWD"])

  #
  # create the full path names
  #
  Datfile = "ipcheck.dat"
  if opt_directory != "":
    Datfile = opt_directory + Datfile
    logger.logit("Datfile = " + Datfile)
  Errfile = "ipcheck.err"
  if opt_directory != "":
    Errfile = opt_directory + Errfile
    logger.logit("Errfile = " + Errfile)
  Waitfile = "ipcheck.wait"
  if opt_directory != "":
    Waitfile = opt_directory + Waitfile
    logger.logit("Waitfile = " + Waitfile)
  Htmlfile = "ipcheck.html"
  if opt_directory != "":
    Htmlfile = opt_directory + Htmlfile
    logger.logit("Htmlfile = " + Htmlfile)
  Tempfile = "ipcheck.tmp"
  if opt_directory != "":
    Tempfile = opt_directory + Tempfile
    logger.logit("Tempfile = " + Tempfile)
  

  #
  # determine the local machine's ip
  #
  localip = ""
  if opt_address != "":
    logger.logit("Manually setting localip with -a")
    localip = opt_address
  elif opt_after_syslog != "":
    logger.logit("Scanning /var/log/messages for last occurance of " + opt_after_syslog)
    fp = open("/var/log/messages", "r")
    ipdata = fp.read()
    fp.close()
    p1 = string.rfind(ipdata, opt_after_syslog)
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata[p1:])
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)
    fp.close()

  elif opt_firewall_log != "":
    logger.logit("Scanning " + opt_firewall_log)
    lines = []
    fp = open(opt_firewall_log, "r")
    while 1:
      l = fp.readline()
      if not l:
        break
      lines.append(l)
    fp.close()
    lcnt = len(lines)

    localip = ""
    ip = ""
    for x in xrange(lcnt-1, 0, -1):
      l = lines[x]
      if string.find(l, "NAT") == 0:
        ipmatch = Addressgrep.findall(l)
        if len(l) == 2:
          ip = l[1]
        else:
          ip = l[0]

        if string.find(ip, "127.") != 0 \
        and string.find(ip, "192.168.") != 0 \
        and string.find(ip, "10.") != 0 \
        and string.find(ip, "172.") != 0 \
        and string.find(ip, "0.") != 0 \
        and string.find(ip, "255") == -1 :
          localip = ip

      if localip != "":
        break

    logger.logit("IP matched " + localip)

  elif opt_snmp_agent != "":
    logger.logit("Trying snmp localip detection")

    # Create an instance of snmptable class
    instance = snmptable (opt_snmp_agent, opt_snmp_community)

    # Run snmptable against passed Object ID's 
    retval = []
    try:
      retval = instance.run([opt_snmp_objectid])
    except:
      logline = "Snmp session failed." 
      logger.logexit(logline)
      logger.logexit("Exception: " + `sys.exc_info()[0]`)
      sys.exit(-1)

    agentlen = len(opt_snmp_agent_prefix)
    objectlen = len(opt_snmp_objectid) + 1
    for (objid, value) in retval:
      logger.logit(objid + ' ---> ' + str(value))
      objval = objid[objectlen:]
      if objval[:agentlen] != opt_snmp_agent_prefix:
        localip = objval
        logger.logit("IP matched: " + localip)
        # match the last one so all options are printed in the log
        #break

  elif opt_Cayman_password != "":
    #
    # Cayman DSL 3220H router ip detection
    #
    #   This code was written for and tested on Device Firmware
    #   GatorSurf version 5.6.2 (build R0)
    #   with PPP / NAT
    
    #
    # determine the router host address
    #
    iphost = ""
    if Cayman_host != "":
      logger.logit("Cayman_host set explicitly.")
      iphost = Cayman_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.254")
      iphost = "192.168.1.254"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin console interface
    try:
      logger.logit("Trying Cayman DSL 3220H")
      tn = telnetlib.Telnet(iphost)
      logger.logit("Creating telnetlib obj done")
      tn.read_until("ogin:")
      logger.logit("Login prompt found")
      tn.write(Cayman_user + "\r\n")
      logger.logit("Cayman_user sent")
      tn.read_until("assword:")
      logger.logit("Password prompt found")
      tn.write(opt_Cayman_password + "\r\n")
      logger.logit("opt_Cayman_password sent")
      tn.read_until(">")
      tn.write("show ip interface\r\n")
      logger.logit("show ip interface command sent")
      ipdata = tn.read_until(">", 2000)
      tn.write("exit\r\n")
      logger.logit("exit command sent")
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "cayman.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("cayman.out file created")

    # look for the WAN device in ipdata
    p1 = string.rfind(ipdata, "PPP")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1+1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)
      

  elif opt_Gnet_password != "":
    #
    # Gnet ADSL Router
    #
    #   This code was written for and tested on
    #   Gnet model BB0040 ADSL Router version 2.A3.2.03 (Build 011207.A)
    #   running ADSL/PPPOE/NAT in the device
    #
    # determine the router host address
    #
    iphost = ""
    if Gnet_host != "":
      logger.logit("Gnet_host set explicitly.")
      iphost = Gnet_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.254")
      iphost = "192.168.1.254"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin console interface
    try:
      logger.logit("Trying Gnet model BB0040 ADSL router")
      tn = telnetlib.Telnet(iphost)
      logger.logit("Creating telnetlib obj done")
      tn.read_until("assword:")
      logger.logit("Password prompt found")
      tn.write(opt_Gnet_password + "\r\n")
      logger.logit("opt_Gnet_password sent")
      tn.read_until(">")
      tn.write("ip subnet\r\n")
      logger.logit("ip subnet command sent")
      ipdata = tn.read_until(">", 2000)
      tn.write("@close\r\n")
      logger.logit("@close command sent")
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "gnet.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("gnet.out file created")

    # look for the WAN device in ipdata
    p1 = string.rfind(ipdata, "subnet ppp_device")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1+1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)
      

  elif opt_Compex_password != "":
    #
    # Compex NetPassage 15 router ip detection
    #
    #   This code was written for and tested on Device Firmware
    #   version "2.67 Build 1005, Mar 5 2001"
    
    #
    # determine the router host address
    #
    iphost = ""
    if Compex_host != "":
      logger.logit("Compex_host set explicitly.")
      iphost = Compex_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.168.1")
      iphost = "192.168.168.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin console interface
    try:
      logger.logit("Trying Compex NetPassage 15")
      tn = telnetlib.Telnet(iphost)
      logger.logit("Creating telnetlib obj done")
      tn.read_until("assword:")
      logger.logit("Password prompt found")
      tn.write(opt_Compex_password + "\r\n")
      logger.logit("opt_Compex_password sent")
      tn.read_until("ommand>")
      tn.write("show ip\r\n")
      logger.logit("show ip command sent")
      ipdata = tn.read_until("ommand>", 2000)
      tn.write("exit\r\n")
      logger.logit("exit command sent")
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "compex.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("compex.out file created")

    # look for the WAN device in ipdata
    p1 = string.rfind(ipdata, "WAN")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)
      
  elif opt_Zyxel_ME_password != "":
    # 
    # ZyXEL Prestige 642ME router ip detection
    # 

    #
    # determine the router host address
    # 
    iphost = ""
    if Zyxel_ME_host != "":
      logger.logit("Zyxel_ME_host set explicitly.")
      iphost = Zyxel_ME_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying ZyXEL Prestige 642ME")
      tn = telnetlib.Telnet(iphost)
      logger.logit("Creating telnetlib obj done")
      tn.read_until("assword:")
      logger.logit("Password prompt found")
      tn.write(opt_Zyxel_ME_password + "\r\n")
      logger.logit("opt_Zyxel_ME_password sent")
      tn.read_until(">")
      tn.write("ip ifconfig\r\n")
      logger.logit("ip ifconfig sent")
      ipdata = tn.read_until(">", 2000)
      logger.logit("ipdata read")
      tn.write("exit\r\n")
      logger.logit("exit sent")
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "zyxelme.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("zyxelme.out file created")

    # look for the last wanif0 device in the log
    p1 = string.rfind(ipdata, "wanif0")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)
    else:
      p1 = string.rfind(ipdata, "enif1")
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)
  
  elif opt_Zyxel_password != "":
    # 
    # ZyXEL 642R router ip detection
    # 

    #
    # determine the router host address
    # 
    iphost = ""
    if Zyxel_host != "":
      logger.logit("Zyxel_host set explicitly.")
      iphost = Zyxel_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying ZyXEL Prestige 642R and 310")
      tn = telnetlib.Telnet(iphost)
      logger.logit("Creating telnetlib obj done")
      tn.read_until("assword:")
      logger.logit("Password prompt found")
      tn.write(opt_Zyxel_password + "\r\n")
      logger.logit("opt_Zyxel_password sent")
      #tn.read_until("Menu Selection Number:")
      tn.write("24\r\n")
      logger.logit("menu number 24 sent")
      #tn.read_until("Menu Selection Number:")
      tn.write("8\r\n")
      logger.logit("menu number 8 sent")
      tn.write("ip ifconfig\r\n")
      logger.logit("ip ifconfig sent")
      ip1 = tn.read_until(">", 2000)
      ip2 = tn.read_until(">", 2000)
      logger.logit("ip1 and ip2 read")
      tn.write("exit\r\n")
      logger.logit("exit sent")
      #tn.read_until("Menu Selection Number:")
      tn.write("99\r\n")
      logger.logit("menu number 99 sent")
      ipdata = ip1 + ip2
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "zyxel.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("zyxel.out file created")

    # look for the last wanif0 device in the log
    p1 = string.rfind(ipdata, "wanif0")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)
    else:
      p1 = string.rfind(ipdata, "enif1")
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)
  
  elif opt_Hawking_password != "":
    # 
    # Hawking router ip detection
    # 
    ipdir = Hawking_page

    #
    # determine the router host address
    # 
    iphost = ""
    if Hawking_host != "":
      logger.logit("Hawking_host set explicitly.")
      iphost = Hawking_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.10.10")
      iphost = "192.168.10.10"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    logger.logit("Trying HawkingTech")
    filename = "hawking.out"
    if opt_directory != "":
      filename = opt_directory + filename
    ipdata = BasicAuth(logger, iphost, Hawking_page, Hawking_user, opt_Hawking_password, filename)

    # look for local ip in the log
    p1 = string.find(ipdata, "WAN")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

  elif opt_Ugate_router != 0:
    # 
    # UgatePlus router ip detection
    # 
    ipdir = Ugate_page

    #
    # determine the router host address
    # 
    iphost = ""
    if Ugate_host != "":
      logger.logit("Ugate_host set explicitly.")
      iphost = Ugate_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.0.1")
      iphost = "192.168.0.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying UgatePlus")
      ipurl = "http://" + iphost + Ugate_page
      urlfp = urllib.urlopen(ipurl)
      ipdata = urlfp.read()
      urlfp.close()
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "ugate.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("ugate.out file created")

    # look for the last Default gateway 
    p1 = string.rfind(ipdata, "I.P. Address")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

  elif opt_Veicon_password != "":
    # 
    # Eicon Diva 2430 SE ADSL Modem with password
    # 
    ipdir = Veicon_page

    #
    # determine the router host address
    # 
    iphost = ""
    if Eicon_host != "":
      logger.logit("Veicon_host set explicitly.")
      iphost = Veicon_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying Eicon with password")
      params = urllib.urlencode({'password': opt_Veicon_password})
      ipurl = "http://" + iphost + Veicon_page
      urlfp = urllib.urlopen(ipurl, params)
      ipdata = urlfp.read()
      urlfp.close()
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "veicon.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("veicon.out file created")

    # look for the last Default gateway 
    p1 = string.rfind(ipdata, "WAN IP address")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

  elif opt_Barricade_password != "":
    # 
    # Newer SMC Barricade with passwords on port 88
    # 
    ipdir = Barricade_page

    #
    # determine the router host address
    # 
    iphost = ""
    if Barricade_host != "":
      logger.logit("Barricade_host set explicitly.")
      iphost = Barricade_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.2.1")
      iphost = "192.168.2.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    logger.logit("Trying new Barricade with password")

    try:
      ipurl = "http://" + iphost + ":88/login.htm"
      logger.logit("urlopen " + ipurl)
      urlfp = urllib.urlopen(ipurl)
      logger.logit("urlfp.read")
      ipdata = urlfp.read()
      logger.logit("urlfp.close")
      urlfp.close()
      logger.logit("filename = login.out")
      filename = "login.out"
      if opt_directory != "":
        filename = opt_directory + filename
      logger.logit("file open")
      fp = open(filename, "w")
      logger.logit("write data")
      fp.write(ipdata)
      logger.logit("file close")
      fp.close()
      logger.logit("login.out file created")
    except:
      logline = "Failed to get login form"
      logger.logexit(logline)
      sys.exit(-1)

    try:
      logger.logit("Try to post to form")
      params = urllib.urlencode({'pws': opt_Barricade_password})
      ipurl = "http://" + iphost + ":88/login.htm"
      logger.logit("urlopen " + ipurl)
      urlfp = urllib.urlopen(ipurl, params)
      logger.logit("urlfp.read")
      ipdata = urlfp.read()
      logger.logit("urlfp.close")
      urlfp.close()
      filename = "post.out"
      if opt_directory != "":
        filename = opt_directory + filename
      fp = open(filename, "w")
      fp.write(ipdata)
      fp.close()
      logger.logit("post.out file created")
    except:
      logline = "Failed to post password to login form"
      logger.logexit(logline)
      sys.exit(-1)

    try:
      logger.logit("Now try to access status.HTM on port 88")
      ipurl = "http://" + iphost + ":88/status.HTM"
      urlfp = urllib.urlopen(ipurl)
      ipdata = urlfp.read()
      urlfp.close()

      filename = "barricade.out"
      if opt_directory != "":
        filename = opt_directory + filename
      fp = open(filename, "w")
      fp.write(ipdata)
      fp.close()
      logger.logit("barricade.out file created")
    except:
      logline = "Failed accessing status page "
      logger.logexit(logline)
      sys.exit(-1)

    # look for the last Default gateway 
    p1 = string.rfind(ipdata, "WAN IP")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

        
  elif opt_Eicon_router != 0:
    # 
    # Eicon Diva 2430 SE ADSL Modem ip detection
    # 
    ipdir = Eicon_page

    #
    # determine the router host address
    # 
    iphost = ""
    if Eicon_host != "":
      logger.logit("Eicon_host set explicitly.")
      iphost = Eicon_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying Eicon")
      ipurl = "http://" + iphost + Eicon_page
      urlfp = urllib.urlopen(ipurl)
      ipdata = urlfp.read()
      urlfp.close()
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "eicon.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("eicon.out file created")

    # look for the last Default gateway 
    p1 = string.rfind(ipdata, "WAN IP address")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

        
  elif opt_II_password != "":
    # 
    # Instant Internet router ip detection
    # 

    #
    # determine the router host address
    # 
    iphost = ""
    if II_host != "":
      logger.logit("II_host set explicitly.")
      iphost = II_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying Instant Internet ")
      tn = telnetlib.Telnet(iphost)
      logger.logit("Creating telnetlib obj done")
      tn.read_until("assword:")
      logger.logit("Password prompt found")
      tn.write(opt_II_password + "\r\n")
      logger.logit("opt_II_password sent")
      tn.write("ppp " + opt_II_interface + "\r\n")
      logger.logit("ppp " + opt_II_interface + " sent")
      ip1 = tn.read_until("state:", 2000)
      logger.logit("ip read")
      tn.write("exit\r\n")
      logger.logit("exit sent")
      ipdata = ip1
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)


    # create an output file of the response
    filename = "II.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("II.out file created")

    # look for the last ipadr device in the log
    p1 = string.rfind(ipdata, "ipadr local:")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)


  elif opt_Nexland_router != 0:
    # 
    # Nexland router ip detection
    # 
    ipdir = Nexland_page

    #
    # determine the router host address
    # 
    iphost = ""
    if Nexland_host != "":
      logger.logit("Nexland_host set explicitly.")
      iphost = Nexland_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying Nexland")
      ipurl = "http://" + iphost + Nexland_page
      urlfp = urllib.urlopen(ipurl)
      ipdata = urlfp.read()
      urlfp.close()
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "nexland.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("nexland.out file created")

    # look for the last Default gateway 
    # p1 = string.rfind(ipdata, "Default gateway")
    p1 = string.find(ipdata, "IP Address<")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

  elif opt_Pro800Turbo_router != 0:
    # 
    # Nexland Pro800Turbo router ip detection
    # 
    ipdir = Pro800Turbo_page

    #
    # determine the router host address
    # 
    iphost = ""
    if Pro800Turbo_host != "":
      logger.logit("Pro800Turbo_host set explicitly.")
      iphost = Nexland_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying Pro800Turbo")
      ipurl = "http://" + iphost + Pro800Turbo_page
      urlfp = urllib.urlopen(ipurl)
      ipdata = urlfp.read()
      urlfp.close()
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "pro800turbo.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("pro800turbo.out file created")

    p1 = 0
    local_ips = []
    connected = []
    while 1:
      p2 = string.find(ipdata[p1:], ">Connection Status<")
      if p2 == -1:
        break
      p1 = p1 + p2 + 1
      cmatch = re.search(">([^>]+)</td>",ipdata[p1:])
      if cmatch == None:
        break
      connected.append(cmatch.group(1))
      p2 = string.find(ipdata[p1:], "IP Address<")
      if p2 == -1:
        break
      p1 = p1 + p2
      if p1 == -1:
        break
      ipmatch = Addressgrep.search(ipdata, p1)
      p1 = p1 + len("IP Address<")
      if ipmatch == None:
        local_ips.append(None)
      else:
        local_ips.append(ipmatch.group())

    if Pro800Turbo_port == 'force':
      if local_ips[Pro800Turbo_port_number] != '0.0.0.0':
        # if forced, don't even check connection.  We might as well use
        # the IP we get, even it it isn't currently working.
        localip = local_ips[Pro800Turbo_port_number]
    else:
      if     local_ips[Pro800Turbo_port_number] != '0.0.0.0' \
         and connected[Pro800Turbo_port_number] == 'Connected':
        localip = local_ips[Pro800Turbo_port_number]
      else:
        for i in range(len(local_ips)):
          if local_ips[i] != '0.0.0.0':
            localip = local_ips[i]
            if connected[i] == 'Connected':
              break
            # Else keep looking for one that is "Connected".  If we don't find
            # one, might as well use the an ip address, even if not
            # "Connected".  I've had situations where that was still usable.
    if localip != "":
      logger.logit("IP matched: " + localip)

  elif opt_SMC_router != 0:
    # 
    # SMC barricade router ip detection
    # 
    ipdir = SMC_page

    #
    # determine the router host address
    # 
    iphost = ""
    if SMC_host != "":
      logger.logit("SMC_host set explicitly.")
      iphost = SMC_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.0.254")
      iphost = "192.168.0.254"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying SMC")
      ipurl = "http://" + iphost + SMC_page
      urlfp = urllib.urlopen(ipurl)
      ipdata = urlfp.read()
      urlfp.close()
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "smc.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("smc.out file created")

    # grab first thing that looks like an IP address
    ipmatch = Addressgrep.search(ipdata)
    if ipmatch != None:
      localip = ipmatch.group()
      logger.logit("IP matched: " + localip)

  elif opt_Cisco_password != "":
    # 
    # Cisco router ip detection
    # 

    #
    # determine the router host address
    # 
    iphost = ""
    if Cisco_host != "":
      logger.logit("Cisco_host set explicitly.")
      iphost = Cisco_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.10.5")
      iphost = "192.168.10.5"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    # first try to talk to a Cisco 667i
    try:
      logger.logit("Trying Cisco DSL 677i")
      tn = telnetlib.Telnet(iphost)
      logger.logit("Creating telnetlib obj done")
      tn.read_until("assword:")
      logger.logit("Password prompt found")
      tn.write(opt_Cisco_password + "\r\n")
      logger.logit("opt_Cisco_password sent")
      tn.write("show er\r\n")
      logger.logit("show er sent")
      ipdata = tn.read_until("Total Number", 1000)
      logger.logit("ipdata read")
      tn.write("exit\r\n")
      logger.logit("exit sent")
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "cisco.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("cisco.out file created")

    # look for the last (rfind) negotiated IP in the log
    p1 = string.rfind(ipdata, "Negotiated IP Address")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

  elif opt_ISDNCisco_password != "":
    # 
    # ISDNCisco router ip detection
    # 

    #
    # determine the router host address
    # 
    iphost = ""
    if ISDNCisco_host != "":
      logger.logit("ISDNCisco_host set explicitly.")
      iphost = ISDNCisco_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.10.5")
      iphost = "192.168.10.5"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    # first try to talk to a Cisco 667i
    try:
      logger.logit("Trying Cisco ISDN 700 series")
      tn = telnetlib.Telnet(iphost)
      logger.logit("Creating telnetlib obj done")
      tn.read_until("assword:")
      logger.logit("Password prompt found")
      tn.write(opt_ISDNCisco_password + "\r\n")
      logger.logit("opt_ISDNCisco_password sent")
      tn.write("show ip co\r\n")
      logger.logit("show ip co sent")
      ipdata = tn.read_until("Profile     PAT", 1000)
      logger.logit("ipdata read")
      tn.write("bye\r\n")
      logger.logit("bye sent")
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "cisco.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("cisco.out file created")

    # look for the last negotiated IP in the log
    # you may have to change this to a user defined profile
    p1 = string.rfind(ipdata, "RemoteNet") 
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

  elif opt_Netopia_password != "":
    # 
    # Netopia router ip detection
    # 
    ipdir = Netopia_page

    #
    # determine the router host address
    # 
    iphost = ""
    if Netopia_host != "":
      logger.logit("Netopia_host set explicitly.")
      iphost = Netopia_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.0.1")
      iphost = "192.168.0.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    logger.logit("Trying Netopia")
    filename = "netopia.out"
    if opt_directory != "":
      filename = opt_directory + filename
    ipdata = BasicAuth(logger, iphost, Netopia_page, Netopia_user, opt_Netopia_password, filename)

    # look for local ip in the log
    p1 = string.find(ipdata, "local")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

  elif opt_Draytek_password != "":
    # 
    # Draytek router ip detection
    # 
    ipdir = Draytek_page

    #
    # determine the router host address
    # 
    iphost = ""
    if Draytek_host != "":
      logger.logit("Draytek_host set explicitly.")
      iphost = Draytek_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    logger.logit("Trying Draytek")
    filename = "draytek.out"
    if opt_directory != "":
      filename = opt_directory + filename
    ipdata = BasicAuth(logger, iphost, Draytek_page, Draytek_user, opt_Draytek_password, filename)

    # grab first thing that looks like an IP address
    ipmatch = Addressgrep.search(ipdata)
    if ipmatch != None:
      localip = ipmatch.group()
      logger.logit("IP matched: " + localip)

  elif opt_Macsense_password != "":
    # 
    # MacSense router ip detection
    # 
    ipdir = Macsense_page

    #
    # determine the router host address
    # 
    iphost = ""
    if Macsense_host != "":
      logger.logit("Macsense_host set explicitly.")
      iphost = Macsense_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying MacSense XRouter Pro router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying MacSense")
      h1 = httplib.HTTP(iphost)

      authstring = base64.encodestring(Macsense_user + ":" + opt_Macsense_password)
      authstring = string.replace(authstring, "\012", "")
      ipdir = Macsense_page + ' \r\n' \
        + 'Authorization: Basic ' \
        + authstring + '\r\n'
      h1.putrequest('GET', ipdir)
      h1.endheaders()

      errcode, errmsg, headers = h1.getreply()
      fp = h1.getfile()
      ipdata = fp.read()
      fp.close()
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the linksys response
    filename = "macsense.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("macsense.out file created")

    p1 = string.find(ipdata, "Public IP")
    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

  elif opt_Netgear_password != "":
    # 
    # Netgear router ip detection
    # 
    ipdir = Netgear_page

    #
    # determine the router host address
    # 
    Netgear_host = routerIP
    iphost = ""
    if Netgear_host != "":
      logger.logit("Netgear_host set explicitly.")
      iphost = Netgear_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.0.1")
      iphost = "192.168.0.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    logger.logit("Trying Netgear")
    filename = "netgear.out"
    if opt_directory != "":
      filename = opt_directory + filename
    ipdata = BasicAuth(logger, iphost, Netgear_page, Netgear_user, opt_Netgear_password, filename)

    # look for the last WAN Port in the log
    p1 = string.rfind(ipdata, "WAN")
    if p1 == -1:
      ipdata = BasicAuth(logger, iphost, Netgear314_page1, Netgear_user, opt_Netgear_password, filename)
      p1 = string.rfind(ipdata, "WAN")
    if p1 == -1:
      ipdata = BasicAuth(logger, iphost, Netgear314_page2, Netgear_user, opt_Netgear_password, filename)
      p1 = string.rfind(ipdata, "WAN")

    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

        logger.logit("Logging out on Netgear")
        # hit the logout page
        filename = "logout.out"
        if opt_directory != "":
          filename = opt_directory + filename
        ipdata = BasicAuth(logger, iphost, Netgear_logout, Netgear_user, opt_Netgear_password, filename)

  elif opt_DI704_password != "":
    # 
    # DI704 router ip detection
    # 
    ipdir = DI704_page

    #
    # determine the router host address
    # 
    DI704_host = routerIP
    iphost = ""
    if DI704_host != "":
      logger.logit("DI704_host set explicitly.")
      iphost = DI704_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.0.1")
      iphost = "192.168.0.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    logger.logit("Trying DI704")
    try:
      logger.logit("Try to post to form")
      params = urllib.urlencode({'RC': '@D', 'ACCT': 'root', 'URL': opt_DI704_password})
      ipurl = "http://" + iphost + "/cgi-bin/logi"
      logger.logit("urlopen " + ipurl)
      urlfp = urllib.urlopen(ipurl, params)
      logger.logit("urlfp.read")
      ipdata = urlfp.read()
      logger.logit("urlfp.close")
      urlfp.close()
      filename = "post.out"
      if opt_directory != "":
        filename = opt_directory + filename
      fp = open(filename, "w")
      fp.write(ipdata)
      fp.close()
      logger.logit("post.out file created")
    except:
      logline = "Failed to post password to login form"
      logger.logexit(logline)
      sys.exit(-1)

    try:
      logger.logit("Now try to access status.HTM now")
      ipurl = "http://" + iphost + "/status.HTM"
      urlfp = urllib.urlopen(ipurl)
      ipdata = urlfp.read()
      urlfp.close()

      filename = "di704.out"
      if opt_directory != "":
        filename = opt_directory + filename
      fp = open(filename, "w")
      fp.write(ipdata)
      fp.close()
      logger.logit("di704.out file created")
    except:
      logline = "Failed accessing status page "
      logger.logexit(logline)
      sys.exit(-1)

    # look for the first WAN Port in the log
    p1 = string.find(ipdata, "IP Address")

    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

  elif opt_DI804_password != "":
    # 
    # DI804 router ip detection
    # 
    ipdir = DI804_page

    #
    # determine the router host address
    # 
    DI804_host = routerIP
    iphost = ""
    if DI804_host != "":
      logger.logit("DI804_host set explicitly.")
      iphost = DI804_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    logger.logit("Trying DI804")
    filename = "di804.out"
    if opt_directory != "":
      filename = opt_directory + filename
    ipdata = BasicAuth(logger, iphost, DI804_page, DI804_user, opt_DI804_password, filename)

    # look for the first WAN Port in the log
    p1 = string.find(ipdata, "Current IP")

    if p1 != -1:
      ipmatch = Addressgrep.search(ipdata, p1)
      if ipmatch != None:
        localip = ipmatch.group()
        logger.logit("IP matched: " + localip)

  elif opt_Linksys_router != 0:
    # 
    # Linksys router ip detection
    # 
    ipdir = Linksys_page

    #
    # determine the linksys router host address
    # 
    iphost = ""
    if Linksys_host != "":
      logger.logit("Linksys_host set explicitly.")
      iphost = Linksys_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying linksys router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying Linksys")
      h1 = httplib.HTTP(iphost)

      #
      # Hack from Bobby Griggs for authorization.
      #
      # For some reason the router won't authenticate when
      # using standard headers for authorization.  Like this:
      #
      #h1.putrequest('GET', ipdir)
      #authstring = base64.encodestring(Linksys_user + ":" + opt_Linksys_password)
      #h1.putheader("Authorization", "Basic " + authstring)
      #
      # It may be looking for lines that end with just \n not \r\n.
      #
      # Note:  Modified by Greg Bentz.
      #        Linksys firmware 1.37, doesn't like the trailing \n on the authstring.
      #        Also requires "\r\n".
      #        My theory concerning the standard headers is that the Linksys header
      #        parsing requires all the header info to appear in one packet.
      #        Use of an extra putheader() call puts the authorization information into
      #        a second packet which is not read by the Linksys device.
      #
      authstring = base64.encodestring(Linksys_user + ":" + opt_Linksys_password)
      authstring = string.replace(authstring, "\012", "")
      ipdir = Linksys_page + ' \r\n' \
        + 'Authorization: Basic ' \
        + authstring + '\r\n'
      h1.putrequest('GET', ipdir)

      h1.endheaders()

      errcode, errmsg, headers = h1.getreply()
      fp = h1.getfile()
      ipdata = fp.read()
      fp.close()
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)


    # create an output file of the linksys response
    filename = "linksys.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("linksys.out file created")

    # work in progress
    #if string.find(ipdata, "Status: Disconnected") != -1:
    #  logger.logit("Linksys disconnected status found!")
    #  try:
    #    logger.logit("Trying to push the connect button")
    #  except:
    #    logline = "Error trying to push connect button.  Continuing."
    #    logger.logexit(logline)

    p1 = string.find(ipdata, "WAN")
    if p1 != -1:
      p2 = string.find(ipdata, "IP Address", p1)
      if p2 != -1:
        ipmatch = Addressgrep.search(ipdata, p2)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)
      

  elif opt_Watchguard_password != "":
    # 
    # Watchguard firewall/router ip detection
    # 
    ipdir = Watchguard_page

    #
    # determine the watchguard soho router host address
    # 
    iphost = ""
    if Watchguard_host != "":
      logger.logit("Watchguard_host set explicitly.")
      iphost = Watchguard_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.111.1")
      iphost = "192.168.111.1"
    else:
      logline = "Trying Watchguard SOHO firewall at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying Watchguard")
      h1 = httplib.HTTP(iphost)

      authstring = base64.encodestring(Watchguard_user + ":" + opt_Watchguard_password)
      authstring = string.replace(authstring, "\012", "")
      ipdir = Watchguard_page + ' \r\n' \
        + 'Authorization: Basic ' \
        + authstring + '\r\n'
      h1.putrequest('GET', ipdir)
      h1.putheader("AUTHORIZATION", "Basic " + authstring)

      h1.endheaders()

      errcode, errmsg, headers = h1.getreply()
      fp = h1.getfile()
      ipdata = fp.read()
      fp.close()
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    ipmatch = Addressgrep.search(ipdata)
    if ipmatch != None:
      localip = ipmatch.group()
      logger.logit("IP matched: " + localip)
    else:
      logger.logit("Trying Watchguard new firmware")
      h1 = httplib.HTTP(iphost)

      authstring = base64.encodestring(Watchguard_user + ":" + opt_Watchguard_password)
      authstring = string.replace(authstring, "\012", "")
      ipdir = Watchguard_page2 + ' \r\n' \
        + 'Authorization: Basic ' \
        + authstring + '\r\n'
      h1.putrequest('GET', ipdir)
      h1.putheader("AUTHORIZATION", "Basic " + authstring)
      h1.endheaders()

      errcode, errmsg, headers = h1.getreply()
      fp = h1.getfile()
      ipdata = fp.read()
      fp.close()

    # create an output file of the watchguard response
    filename = "watchguard.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("watchguard.out file created")

    ipmatch = Addressgrep.search(ipdata)
    if ipmatch != None:
      localip = ipmatch.group()
      logger.logit("IP matched: " + localip)

  elif opt_DI701_password != "":

    #
    # determine the router host address
    #
    DI701_host = routerIP
    iphost = ""
    if DI701_host != "":
      logger.logit("DI701_host set explicitly.")
      iphost = DI701_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 192.168.1.1")
      iphost = "192.168.1.1"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying DLink DI701")
      tn = telnetlib.Telnet(iphost,333)
      logger.logit("Creating telnetlib obj done")
      tn.read_until("assword : ")
      logger.logit("Password prompt found")
      tn.write(opt_DI701_password + "\r")
      logger.logit("opt_DI701_password sent")
      tn.read_until("command>")
      tn.write("show\r")
      logger.logit("show command sent")
      tn.read_until("address of global port : [", 2000)
      ip2 = tn.read_until("]", 2000)
      logger.logit("ip read")
      #tn.write("exit\r\n")
      #logger.logit("exit sent")
      ipdata = ip2[:-1]
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "di701.out"
    if opt_directory != "":
      filename = opt_directory + filename
    open(filename, "w").write(ipdata)
    logger.logit("di701.out file created")

    localip = ipdata
    logger.logit("IP matched: " + localip)

  elif opt_AlcatelSTP_password != "":

    #
    # determine the router host address
    #
    iphost = ""
    if AlcatelSTP_host != "":
      logger.logit("AlcatelSTP_host set explicitly.")
      iphost = AlcatelSTP_host
    else:
      iphost = DefaultRoute(logger, Tempfile)

    if iphost == "":
      logger.logit("No router ip detected.  Assuming 10.0.0.138")
      iphost = "10.0.0.138"
    else:
      logline = "Trying router at " + iphost
      logger.logit(logline)

    # connect to the router's admin webpage
    try:
      logger.logit("Trying Alcatel STP")
      tn = telnetlib.Telnet(iphost)
      logger.logit("Creating telnetlib obj done")
      tn.read_until("User : ")
      logger.logit("User prompt found")
      tn.write("nobody\r\n")
      logger.logit("opt_Alcatel_password sent")
      tn.read_until("assword : ")
      logger.logit("Password prompt found")
      tn.write(opt_AlcatelSTP_password + "\r\n")
      logger.logit("opt_AlcatelSTP_password sent")
      tn.read_until("=>")
      tn.write("ip aplist\r\n")
      logger.logit("ip aplist sent")
      tn.read_until("SERIAL")
      tn.read_until("inet addr:")
      ip2 = tn.read_until(" ")
      logger.logit("ip read")
      tn.write("exit\r\n")
      logger.logit("exit sent")
      ipdata = ip2[:-1]
    except:
      logline = "No address found on router at " + iphost
      logger.logexit(logline)
      sys.exit(-1)

    # create an output file of the response
    filename = "alcatel_stp.out"
    if opt_directory != "":
      filename = opt_directory + filename
    open(filename, "w").write(ipdata)
    logger.logit("alcatel_stp.out file created")

    localip = ipdata
    logger.logit("IP matched: " + localip)

  elif opt_router != "":
    logger.logit("web based ip detection for localip")
    ipurl = ""

    # check for deprecated url
    if string.find(opt_router, "cgi-bin/check_ip.cgi") != -1:
      logger.logexit("You should be using -r checkip.dyndns.org ")
      logger.logexit("Continuing with new URL.")
      opt_router = "checkip.dyndns.org:8245"
    
    # strip off the http part, if any
    if opt_router[:7] == "HTTP://" or opt_router[:7] == "http://":
      ipurl = opt_router[7:]
    else:
      ipurl = opt_router

    # stick it back on for urllib usage
    ipurl = "http://" + ipurl

    # grab the data
    try:
      logger.logit("Trying URL " + ipurl)
      urlfp = urllib.urlopen(ipurl)
      ipdata = urlfp.read()
      urlfp.close()
    except:
      logline = "Unable to open url " + ipurl
      logger.logexit(logline)
      logger.logexit("Exception: " + `sys.exc_info()[0]`)
      sys.exit(-1)


    # create an output file of the ip detection response
    filename = "webip.out"
    if opt_directory != "":
      filename = opt_directory + filename
    fp = open(filename, "w")
    fp.write(ipdata)
    fp.close()
    logger.logit("webip.out file created")

    # grab first thing that looks like an IP address
    ipmatch = Addressgrep.search(ipdata)
    if ipmatch != None:
      localip = ipmatch.group()
      logger.logit("webip detected = " + localip)

  else:
    logger.logit("Interface ip detection on sys.platform = " + sys.platform)
    if sys.platform == "win32":
      logger.logit("win32 interface ip detection for localip")
      getip = Win32ip 
      os.system (getip + " > " + Tempfile)
      fp = open(Tempfile, "r")
      ipdata = fp.read()
      fp.close()
      # grab the first dotted quad after the interface
      p1 = string.find(ipdata, opt_interface)
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)

    elif string.find(sys.platform, "sunos") != -1:
      logger.logit("Sunos interface ip detection for localip (untested)")
      getip = Sunip + " " + opt_interface
      os.system (getip + " > " + Tempfile)
      fp = open(Tempfile, "r")
      ipdata = fp.read()
      fp.close()
      # grab the first dotted quad after the interface
      p1 = string.find(ipdata, opt_interface)
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)

    elif string.find(sys.platform, "linux") != -1:
      logger.logit("linux interface ip detection for localip")
      getip = Linuxip + " " + opt_interface
      os.system (getip + " > " + Tempfile)
      fp = open(Tempfile, "r")
      ipdata = fp.read()
      fp.close()
      # grab the first dotted quad after the interface
      p1 = string.find(ipdata, opt_interface)
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)

    elif string.find(sys.platform, "Darwin") != -1:
      logger.logit("Darwin interface ip detection for localip")
      getip = Macip + " " + opt_interface 
      os.system (getip + " > " + Tempfile)
      fp = open(Tempfile, "r")
      ipdata = fp.read()
      fp.close()
      # grab the first dotted quad after the LAST inet (to avoid dead routes)
      p1 = string.rfind(ipdata, "inet ")
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)

    elif string.find(sys.platform, "os2") != -1:
      logger.logit("OS2 interface ip detection for localip")
      getip = Os2ip + " " + opt_interface
      os.system (getip + " > " + Tempfile)
      fp = open(Tempfile, "r")
      ipdata = fp.read()
      fp.close()
      # grab the first dotted quad after the LAST inet (to avoid dead routes)
      p1 = string.rfind(ipdata, "inet ")
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)

    elif string.find(sys.platform, "beos") != -1:
      logger.logit("BeOS interface ip detection for localip")
      getip = Beosip 
      os.system (getip + " > " + Tempfile)
      fp = open(Tempfile, "r")
      ipdata = fp.read()
      fp.close()
      # grab the first dotted quad after interface text
      p1 = string.rfind(ipdata, opt_interface + ":")
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)

    elif string.find(sys.platform, "bsd") != -1:
      logger.logit("*BSD* interface ip detection for localip")
      getip = BSDip + " " + opt_interface + " | grep -v 192.168 "
      os.system (getip + " > " + Tempfile)
      fp = open(Tempfile, "r")
      ipdata = fp.read()
      fp.close()
      # grab the first dotted quad after the LAST inet (to avoid dead routes)
      p1 = string.rfind(ipdata, "inet ")
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)

    elif string.find(sys.platform, "sco_") != -1:
      logger.logit("SCO interface ip detection for localip")
      getip = Scoip + " " + opt_interface 
      os.system (getip + " > " + Tempfile)
      fp = open(Tempfile, "r")
      ipdata = fp.read()
      fp.close()
      # grab the first dotted quad after the LAST inet (to avoid dead routes)
      p1 = string.rfind(ipdata, "inet ")
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)

    else:
      logger.logit("Default interface ip detection for localip (untested)")
      getip = Otherip + " " + opt_interface 
      os.system (getip + " > " + Tempfile)
      fp = open(Tempfile, "r")
      ipdata = fp.read()
      fp.close()
      # grab the first dotted quad after the LAST inet (to avoid dead routes)
      p1 = string.rfind(ipdata, "inet ")
      if p1 != -1:
        ipmatch = Addressgrep.search(ipdata, p1)
        if ipmatch != None:
          localip = ipmatch.group()
          logger.logit("IP matched: " + localip)

    # check if we have a localip from all the above elifs
    if localip == "":
      logline = "No address found on interface " + opt_interface + " use -i"
      logger.logexit(logline)
      sys.exit(-1)


  # end of all determining localip cases
  # check if the router elif's found no address
  if localip == "":
    logline = "No address found on router." 
    logger.logexit(logline)
    sys.exit(-1)

  # check if detected ip is not valid
  if localip == "0.0.0.0":
    logline = "The router has external IP 0.0.0.0 assigned. " 
    logger.logexit(logline)
    sys.exit(-1)


  #
  # check the IP to make sure it is sensible
  #
  p1 = string.find(localip, ".")
  p2 = string.find(localip, ".", p1+1)
  p3 = string.find(localip, ".", p2+1)
  p4 = string.find(localip, ".", p3+1)
  if p1 == -1 or p2 == -1 or p3 == -1 or p4 != -1:
    logline = "Invalid local address " + localip
    logger.logexit(logline)
    sys.exit(-1)
  
  try:
    ip1 = string.atoi(localip[0:p1])
    ip2 = string.atoi(localip[p1+1:p2])
    ip3 = string.atoi(localip[p2+1:p3])
    ip4 = string.atoi(localip[p3+1:])
  except:
    ip1 = 0
    ip2 = 0
    ip3 = 0
    ip4 = 0

  # 0-255 in first three allowed, 0 to 255 in last 
  if ip1 < 0 or ip1 > 255 or ip2 < 0 or ip2 > 255 or ip3 < 0 or ip3 > 255 or ip4 < 0 or ip4 > 255:
    logline = "Invalid local address " + localip
    logger.logexit(logline)
    sys.exit(-1)

  #
  # create the dat file from dns lookup if specified
  #
  if opt_makedat == 1:
    logger.logit("DNS lookups to create data file.")

    datexists = 0
    try:
      fp = open (Datfile, "r")
      fp.close()
      datexists = 1
      logger.logexit("There is already an ipcheck.dat file existing.")
      logger.logexit("Remove this file first before running --makedat")
    except:
      logger.logit("Good, no ipcheck.dat file found.")

    if datexists == 1:
      # can't exit in the try block cause except catches
      sys.exit(0)

    ip1 = ""
    ip2 = ""
    h = ""
    try:
      for h in hostnames:
        if ip1 == "":
          logger.logexit("ip1 looking up " + h)
          (a, b, c) = socket.gethostbyname_ex(h)
          line = `a` + `b` + `c`
          logger.logexit("result: " + line)
          ip1 = c[0]
          logger.logit("ip1 = " + ip1)
          ip2 = ip1
        else:
          logger.logexit("ip2 looking up " + h)
          (a, b, c) = socket.gethostbyname_ex(h)
          line = `a` + `b` + `c`
          logger.logexit("result: " + line)
          ip2 = c[0]
          logger.logit("ip2 = " + ip2)

        # check if not same
        if ip1 != ip2:
          logger.logexit("WARNING: hostnames have different ips.")
          logger.logexit("I'm going to set the force option so all hosts")
          logger.logexit("will be synchronized to the same IP address.")
          opt_force = 1

    except:
      logger.logexit("Problems looking up hostname " + h)
      logger.logexit("Make sure the hostname is correct, is setup at Dyndns,")
      logger.logexit("and that local DNS lookups are working fine.")
      logger.logexit("Exception: " + `sys.exc_info()[0]`)
      sys.exit(-1)


    logger.logit("Writing the new dat file.")
    fp = open (Datfile, "w")
    fp.write(ip1 + "\n")
    for host in hostnames:
      fp.write(host + "\n")
    fp.close()
    


  #
  # read the data from file of last update, if any
  #
  fileip = ""
  filehosts = []
  fileage = 0
  try:
    fp = open (Datfile, "r")
    fileip = fp.readline()
    if fileip[-1] == "\n": 
      fileip = fileip[:-1]
    while 1:
      fileline = fp.readline()
      if not fileline:
        break
      filehosts.append(fileline[:-1])
    fp.close()
    
    #
    # get the age of the file
    #
    currtime = time.time()
    statinfo = os.stat(Datfile)
    fileage = (currtime - statinfo[8]) / (60*60*24)

  except:
    # do not create the file automatically cause people could get
    # into loops and use up a lot of bandwidth doing dns lookup
    logger.logexit("No ipcheck.dat file found.")
    logger.logexit("Use same command+options ONCE with --makedat to create from DNS lookup.")
    sys.exit(0)


  #
  # check filehosts list versus hostnames list
  #
  mismatch = 0
  for h in filehosts:
    if h not in hostnames:
      mismatch = 1
  for h in hostnames:
    if h not in filehosts:
      mismatch = 1
  if mismatch == 0:
    logger.logit("Good, filehosts and hostnames are the same.")
  else:
    # do not create the file automatically cause people could get
    # into loops and use up a lot of bandwidth doing dns lookup
    logger.logexit("The hostnames listed do not match the ipcheck.dat file.")
    logger.logexit("Remove the dat file and use same command ONCE with --makedat.")
    logger.logexit("Note that if you are maintaining both a custom domain and")
    logger.logexit("a dyndns domain, you should be using the -d option and")
    logger.logexit("keeing the data files in separate directories.")
    sys.exit(0)



  #
  # read the data from error file, if any
  #
  errors = []
  try:
    fp = open (Errfile, "r")
    while 1:
      errline = fp.readline()
      if not errline:
        break
      errors.append(errline[:-1])
    fp.close()
  except:
    logger.logit("Good, no ipcheck.err file.")

  if len(errors) > 0 and opt_force == 0:
    logger.logit("Handling errors in ipcheck.err file.")
    for err in errors:
      errlist = string.split(err, " ")
      if string.find(err, "badauth") == 0:
        logger.logit("badauth found.")
        if errlist[1] == opt_username and errlist[2] == opt_password:
          logger.logexit("Previous authorization error encountered for")
          logger.logexit("Username:" + opt_username)
          logger.logexit("Password:" + opt_password)
          logger.logexit("Erase the ipcheck.err file if this is correct now.")
          sys.exit(-1)
        else:
          logger.logit("trying new username or password.")
          logger.logit("ipcheck.err file removed and continuing.")
          os.unlink (Errfile)
      elif string.find(err, "badsys") == 0:
        logger.logit("badsys found.")
        logger.logexit("Previous system error encountered for " + errlist[1])
        logger.logexit("Erase the ipcheck.err file if this is correct now.")
        sys.exit(-1)
      elif string.find(err, "badagent") == 0:
        logger.logit("badagent found.")
        logger.logexit("Badagent contact author at kal@users.sourceforge.net.")
        sys.exit(-1)
      elif string.find(err, "shutdown") == 0:
        logger.logit("shutdown found.")
        logger.logexit("Service shutdown from dyndns.org")
        logger.logexit("Check http://www.dyndns.org/status.shtml")
        logger.logexit("Erase the ipcheck.err file when shutdown is over.")
        sys.exit(-1)
      elif string.find(err, "abuse") == 0:
        logger.logit("abuse found.")
        if errlist[1] in hostnames:
          logger.logexit("Previous abuse lockout encountered for " + errlist[1])
          logger.logexit("Use the form at http://support.dyndns.org/dyndns/abuse.shtml")
          logger.logexit("Erase the ipcheck.err file when dyndns notifies you (by email).") 
          sys.exit(-1)
      elif string.find(err, "notfqdn") == 0:
        logger.logit("notfqdn found.")
        if errlist[1] in hostnames:
          logger.logexit("Previous notfqdn encountered for host:" + errlist[1])
          logger.logexit("Erase the ipcheck.err file if this is really correct.")
          sys.exit(-1)
      elif string.find(err, "!donator") == 0:
          logger.logexit("Previous !donator encountered for " + errlist[1])
          logger.logexit("Erase the ipcheck.err file when this problem is fixed.") 
          logger.logexit(logline)
          sys.exit(-1)
      elif string.find(err, "nohost") == 0:
        logger.logit("nohost found.")
        if errlist[1] in hostnames:
          logger.logexit("Previous nohost encountered for " + errlist[1])
          logger.logexit("You may be trying -s for a dynamic host or vice versa.")
          logger.logexit("Erase the ipcheck.err if file this host is now created.")
          sys.exit(-1)
      elif string.find(err, "!yours") == 0:
        logger.logit("!yours found.")
        if errlist[1] in hostnames:
          logger.logexit("Previous !yours encountered for " + errlist[1])
          logger.logexit("Erase the ipcheck.err file when the problem is fixed.")
          sys.exit(-1)
      elif string.find(err, "!active") == 0:
        logger.logit("!active found.")
        if errlist[1] in hostnames:
          logger.logexit("Previous !active encountered for " + errlist[1])
          logger.logexit("You need to activate your Custom domain first.")
          logger.logexit("Dyndns may require it to be properly delegated.")
          logger.logexit("Erase the ipcheck.err file when the problem is fixed.")
          sys.exit(-1)
      elif string.find(err, "numhost") == 0:
        logger.logit("numhost found.")
        logger.logexit("Contact support@dyndns.org about numhost error.")
        logger.logexit("Attach the ipcheck.html file for details.")
        logger.logexit("Erase the ipcheck.err file when the problem is fixed.")
        sys.exit(-1)
      elif string.find(err, "dnserr") == 0:
        logger.logit("numhost found.")
        logger.logexit("Contact support@dyndns.org about dnserr error.")
        logger.logexit("Attach the ipcheck.html file for details.")
        logger.logexit("Erase the ipcheck.err file when the problem is fixed.")
        sys.exit(-1)
      else:
        logger.logexit("Unrecognized error in ipcheck.err file.")
        logger.logexit("Erase the ipcheck.err if there is no problem.")
        sys.exit(-1)

  #
  # read the data from wait file, if any
  #
  waitcode = ""
  waitdate = ""
  try:
    fp = open (Waitfile, "r")
    waitcode = fp.readline()
    if waitcode[-1] == "\n": 
      waitcode = waitcode[:-1]
    waitdate = fp.readline()
    if waitdate[-1] == "\n": 
      waitdate = waitdate[:-1]
    fp.close()
  except:
    logger.logit("Good, no ipcheck.wait file.")

  if waitcode != "" and opt_force == 0:

    logger.logit("Found wait entry.")
    logger.logit(waitcode)
    logger.logit(waitdate)

    #
    # first line is the code
    # second line is time.time() when the code was received
    # now determine whether we should continue or abort
    # remove the file if the wait is no longer needed
    #
    try:
      waitnum = string.atof(waitdate)
    except:
      waitnum = 0.0

    if waitnum == 0.0:
      logger.logit("Invalid wait date in ipcheck.wait file.")
      logger.logit("ipcheck.wait file removed and continuing.")
      os.unlink (Waitfile)

    elif waitcode[0] == 'u':
      # wait until GMT
      logger.logit("Decoding wait until entry in ipcheck.wait file.")

      # First we check the age of the file.
      currtime = time.time()
      statinfo = os.stat(Waitfile)
      if (currtime - statinfo[8]) / (60*60) > 24:
        # the file is older than 24 hours and should be ignored
        logger.logit("Stale ipcheck.wait file removed and continuing.")
        os.unlink (Waitfile)
      elif (currtime - waitnum) / (60*60) > 24:
        # the code is older than 24 hours and should be ignored
        logger.logit("Stale code in file removed and continuing.")
        os.unlink (Waitfile)
      else:
        try:
          waitsec = string.atoi(waitcode[2:])
        except:
          waitsec = 0

        currtime = time.time()
        if currtime > waitnum + waitsec:
          logger.logit("until wait entry expired.")
          logger.logit("ipcheck.wait file removed and continuing.")
          os.unlink (Waitfile)
        else:
          logger.logit("until wait entry in effect: quietly aborting.")
          sys.exit(-1)
  
    else:
      # wait h, m or s
      logger.logit("Decoding hms entry in ipcheck.wait file.")
      try:
        waitsec = string.atoi(waitcode[1:3])
        if waitcode[3] == 'h' or waitcode[3] == 'H':
          waitsec = waitsec * 60 * 60
        elif waitcode[3] == 'm' or waitcode[3] == 'M':
          waitsec = waitsec * 60 
      except:
        waitsec = 0

      currtime = time.time()
      if currtime > waitnum + waitsec:
        logger.logit("hms wait entry expired.")
        logger.logit("ipcheck.wait file removed and continuing.")
        os.unlink (Waitfile)
      else:
        logger.logit("hms wait entry in effect: quietly aborting.")
        sys.exit(-1)

  #
  # determine whether and which hosts need updating
  #
  updatehosts = []

  # if opt_force is set then update all hosts
  # or offline mode selected
  if opt_force == 1 or opt_offline:
    logger.logit("Updates forced by -f option.")
    for host in hostnames:
      updatehosts.append(host)

  # else if file age is older than update all hosts
  elif fileage > Touchage:
    logger.logit("Updates required by stale ipcheck.dat file.")
    for host in hostnames:
      updatehosts.append(host)

  # else check the address used in last update
  elif localip != fileip:
    logger.logit("Updates required by ipcheck.dat address mismatch.")
    for host in hostnames:
      updatehosts.append(host)

  # This case is probably deprecated but will leave it in
  # case I missed something.  When reading the dat file,
  # I'm going to now only proceed if hostnames == filehosts.
  # Otherwise, a message will be printed out and an option
  # to create a dat file from dns lookups will be recommended.

  else:
    logger.logit("Checking hosts in file vs command line.")
    updateflag = 0
    for host in hostnames:
      if host not in filehosts:
        updateflag = 1

    # If anyone of the hosts on the command line needs updating,
    # put them all in the updatehosts list so they will get the
    # same last updated timestamp at dyndns.  This way they all 
    # won't need to be touched again for Touchage days, instead 
    # of having multiple touches for different last updated dates.
    if updateflag == 1:
      for host in hostnames:
        updatehosts.append(host)

  if updatehosts == []:
    # Quietly log this message then exit too.
    logger.logit("The database matches local address.  No hosts update.")
    sys.exit(0)

  #
  # build the query strings
  #
  updateprefix = Updatepage
  if opt_static == 1:
    updateprefix = updateprefix + "?system=statdns&hostname="
  elif opt_custom == 1:
    updateprefix = updateprefix + "?system=custom&hostname="
  else:
    updateprefix = updateprefix + "?system=dyndns&hostname="

  hostlist = ""
  for host in updatehosts:
    hostlist = hostlist + host + ","
    logger.logit(host + " needs updating")
  if len(hostlist) > 0:
    hostlist = hostlist[:-1]

  if opt_offline == 1:
    if opt_static == 1:
      logger.logexit("offline and static mode not allowed together.")
      sys.exit(-1)
    if opt_custom == 1:
      logger.logexit("offline and custom mode not allowed together.")
      sys.exit(-1)

  updatesuffix = ""
  if opt_offline == 1:
    #updatesuffix = updatesuffix + "&myip=1.0.0.0" 
    updatesuffix = updatesuffix + "&offline=YES"
  else:
    # only do these other things if not setting offline mode
    if opt_guess == 1:
      logger.logit("Letting dyndns guess the IP.")
      updatesuffix = ""
      localip = ""
    else:
      updatesuffix = updatesuffix + "&myip=" + localip 

    # custom domains do not have wildcard or mx records
    if opt_custom == 0:

      if opt_wildcard == 1:
        updatesuffix = updatesuffix + "&wildcard=ON"
      else:
        updatesuffix = updatesuffix + "&wildcard=OFF"

      if opt_backupmx == 1:
        updatesuffix = updatesuffix + "&backmx=YES"
      else:
        updatesuffix = updatesuffix + "&backmx=NO"

      if opt_mxhost != "":
        updatesuffix = updatesuffix + "&mx=" + opt_mxhost

  logger.logit("Prefix = " + updateprefix)
  logger.logit("Hosts  = " + hostlist)
  logger.logit("Suffix = " + updatesuffix)

  if opt_testrun == 1:
    logger.logit("test run exits here")
    sys.exit()
    

    #
    # Check whether we can actually update the Datfile. 
    # If we cannot, it will result in a loop:
    # We are going to continually update the DNS and it will result 
    # in the triggering of the abuse protection system of dyndns.
    # Modification by : Lucas Bruand <lucas.bruand@NOSPAM.ecl2002.ec-lyon.fr>
    #
    try:
      fp = open (Datfile, "w")
      fp.write("An error occured while updating the DNS.\n")
      fp.close()
    except:
      # We cannot open in write mode ?
      logger.logexit("Cannot access '%s' file in write mode while " % Datfile)
      logger.logexit("not in test run. This can lead to unnecessary repeated")
      logger.logexit("updates of the DNS. Please modify access permission to '%s' "% Datfile)
      sys.exit(-1)  	  

  #
  # update those hosts 
  #
  if opt_no_https == 0:
    logline = "trying to open HTTPS connection" 
    logger.logit(logline)
    try:
      if opt_proxy == 0:
        h2 = httplib.HTTPS(Updatehost)
      else:
        h2 = httplib.HTTPS(Updatehost, 8245)
    except:
      logline = "trying to open normal HTTP connection" 
      logger.logit(logline)
      if opt_proxy == 0:
        h2 = httplib.HTTP(Updatehost)
      else:
        h2 = httplib.HTTP(Updatehost, 8245)
  else:
    logline = "trying to open normal HTTP connection" 
    logger.logit(logline)
    if opt_proxy == 0:
      h2 = httplib.HTTP(Updatehost)
    else:
      h2 = httplib.HTTP(Updatehost, 8245)

  logline = "httplib connection opened" 
  logger.logit(logline)

  h2.putrequest("GET", updateprefix + hostlist + updatesuffix)
  h2.putheader("HOST", Updatehost)
  h2.putheader("USER-AGENT", Useragent)
  authstring = base64.encodestring(opt_username + ":" + opt_password)
  authstring = string.replace(authstring, "\012", "")
  h2.putheader("AUTHORIZATION", "Basic " + authstring)
  h2.endheaders()
  errcode, errmsg, headers = h2.getreply()

  # log the result
  logline = "http code = " + `errcode`
  logger.logit(logline)
  logline = "http msg  = " + errmsg
  logger.logit(logline)

  # try to get the html text
  try:
    fp = h2.getfile()
    httpdata = fp.read()
    fp.close()
  except:
    httpdata = "No output from http request."

  # explicitly close
  fp.close()

  logline = "fd closed" 
  logger.logit(logline)

  # create the output file
  fp = open (Htmlfile, "w")
  fp.write(httpdata)
  fp.close()
  logger.logit("ipcheck.html file created")

  #
  # check the result for fatal errors
  #
  
  # badauth may appear anywhere when errcode is 401
  if string.find(httpdata, "badauth") != -1 and errcode == 401:
    logline = "Invalid username and password specified on command line." 
    logger.logexit(logline)

    #
    # save the error to an ipcheck.err file
    #
    fp = open (Errfile, "w")
    fp.write("badauth " + opt_username + " " + opt_password + "\n")
    fp.close()
    logger.logit("ipcheck.err FILE CREATED.")

    sys.exit(-1)

  elif errcode == 404:
    logger.logexit("404 Not Found returned by dyndns server.")
    logger.logexit("Please try again in a few minutes.")
    sys.exit(-1)

  # badsys must begin the resulting text and errcode is 200
  elif string.find(httpdata, "badsys") == 0 and errcode == 200:
    logline = "Bad system parameter specified (not dyndns or statdns)." 
    logger.logexit(logline)

    #
    # save the error to an ipcheck.err file
    #
    fp = open (Errfile, "w")
    if opt_static == 1:
      fp.write("badsys statdns\n")
    elif opt_custom == 1:
      fp.write("badsys custom\n")
    else:
      fp.write("badsys dyndns\n")
    fp.close()
    logger.logit("ipcheck.err FILE CREATED.")

    sys.exit(-1)

  # badagent must begin the resulting text and errcode is 200
  elif string.find(httpdata, "badagent") == 0 and errcode == 200:
    logger.logexit("Badagent contact author at kal@users.sourceforge.net.")

    #
    # save the error to an ipcheck.err file
    #
    fp = open (Errfile, "w")
    fp.write("badagent\n")
    fp.close()
    logger.logit("ipcheck.err FILE CREATED.")

    sys.exit(-1)

  # 911 may appear anywhere when errcode is 500
  elif string.find(httpdata, "911") != -1 and errcode == 500:
    logline = "Dyndns 911 result.  Dyndns emergency shutdown."
    logger.logexit(logline)

    #
    # save the error to an ipcheck.err file
    #
    fp = open (Errfile, "w")
    fp.write("shutdown\n")
    fp.close()
    logger.logit("ipcheck.err FILE CREATED.")

    sys.exit(-1)

  # 999 may appear anywhere when errcode is 500
  elif string.find(httpdata, "999") != -1 and errcode == 500:
    logline = "Dyndns 999 result.  Dyndns emergency shutdown."
    logger.logexit(logline)

    #
    # save the error to an ipcheck.err file
    #
    fp = open (Errfile, "w")
    fp.write("shutdown\n")
    fp.close()
    logger.logit("ipcheck.err FILE CREATED.")

    sys.exit(-1)

  #
  # don't really know what codes go with numhost, dnserr and wxxxx
  # probably errcode 200 but no need to assume this instead
  # assume they will be sent at the beginning of a line
  # we check those codes below
  #

  elif errcode == 200:

    # build the results list
    results = []
    fp = open (Htmlfile, "r")
    for host in hostnames:
      resultline = fp.readline()
      if resultline[-1:] == "\n":
        resultline = resultline[:-1]
      results.append(resultline)
    fp.close()

    # check if we have one result per updatehosts 
    if len(results) == len(updatehosts):
      idx = 0
      success = 0
      for host in updatehosts:
        #
        # use logexit to generate output (email if ran from a cronjob)
        #
        if string.find(results[idx], "good") == 0:
          logline = host + " " + results[idx] + " -update successful"
          if opt_quiet == 0:
            logger.logexit(logline)
          else:
            logger.logit(logline)

          # update the localip dyndns found if guess was used
          if opt_guess == 1 and localip == "":
            p1 = string.find(results[idx], " ")
            localip = string.rstrip(results[idx][p1+1:])
            logger.logit("Dyndns guessed IP: " + localip)

          # set the success update flag
          success = 1

        elif string.find(results[idx], "nochg") == 0:
          logline = host + " " + results[idx] + " -abusive if continually repeated"
          logger.logexit(logline)

          # update the localip dyndns found if guess was used
          if opt_guess == 1 and localip == "":
            p1 = string.find(results[idx], " ")
            localip = string.rstrip(results[idx][p1+1:])
            logger.logit("Dyndns guessed IP: " + `localip`)

        elif string.find(results[idx], "!active") == 0:
          logline = host + " " + results[idx] + " -zone not active yet"
          logger.logexit(logline)
          logger.logexit("Try again in an hour")

          # clear localip to remove ipcheck.dat file
          localip = ""

        elif string.find(results[idx], "abuse") == 0:
          logline = host + " " + results[idx] + " -hostname blocked for abuse"
          logger.logexit(logline)
          logger.logexit("Use the form at http://support.dyndns.org/dyndns/abuse.shtml")
          logger.logexit("Erase the ipcheck.err file when dyndns notifies you (by email).") 

          # update the localip dyndns found if guess was used
          if opt_guess == 1 and localip == "":
            p1 = string.find(results[idx], " ")
            localip = string.rstrip(results[idx][p1+1:])
            logger.logit("Dyndns guessed IP: " + `localip`)

          #
          # save the error to an ipcheck.err file
          #
          fp = open (Errfile, "a")
          fp.write("abuse " + host + "\n")
          fp.close()
          logger.logit("ipcheck.err FILE CREATED.")

        elif string.find(results[idx], "notfqdn") == 0:
          logline = host + " " + results[idx] + " -FQDN hostnames needed"
          logger.logexit(logline)

          #
          # save the error to an ipcheck.err file
          #
          fp = open (Errfile, "a")
          fp.write("notfqdn " + host + "\n")
          fp.close()
          logger.logit("ipcheck.err FILE CREATED.")

          # set the localip so next update will be made
          localip = "0.0.0.0"

        elif string.find(results[idx], "nohost") == 0:
          logline = host + " " + results[idx] + " -hostname not found"
          logger.logexit(logline)

          #
          # save the error to an ipcheck.err file
          #
          fp = open (Errfile, "a")
          fp.write("nohost " + host + "\n")
          fp.close()
          logger.logit("ipcheck.err FILE CREATED.")

          # set the localip so next update will be made
          localip = "0.0.0.0"

        elif string.find(results[idx], "!active") == 0:
          logline = host + " " + results[idx] + " -hostname not activated yet"
          logger.logexit(logline)

          #
          # save the error to an ipcheck.err file
          #
          fp = open (Errfile, "a")
          fp.write("!active " + host + "\n")
          fp.close()
          logger.logit("ipcheck.err FILE CREATED.")

          # set the localip so next update will be made
          localip = "0.0.0.0"

        elif string.find(results[idx], "!yours") == 0:
          logline = host + " " + results[idx] + " -hostname not yours"
          logger.logexit(logline)

          #
          # save the error to an ipcheck.err file
          #
          fp = open (Errfile, "a")
          fp.write("!yours " + host + "\n")
          fp.close()
          logger.logit("ipcheck.err FILE CREATED.")

          # set the localip so next update will be made
          localip = "0.0.0.0"

        elif string.find(results[idx], "numhost") == 0:
          logline = host + " " + results[idx] + " -send ipcheck.html to support@dyndns.org"
          logger.logexit(logline)

          #
          # save the error to an ipcheck.err file
          #
          fp = open (Errfile, "a")
          fp.write("numhost " + host + "\n")
          fp.close()
          logger.logit("ipcheck.err FILE CREATED.")

          # set the localip so next update will be made
          localip = "0.0.0.0"

        elif string.find(results[idx], "dnserr") == 0:
          logline = host + " " + results[idx] + " -send ipcheck.html to support@dyndns.org"
          logger.logexit(logline)

          #
          # save the error to an ipcheck.err file
          #
          fp = open (Errfile, "a")
          fp.write("dnserr " + host + "\n")
          fp.close()
          logger.logit("ipcheck.err FILE CREATED.")

          # set the localip so next update will be made
          localip = "0.0.0.0"

        elif string.find(results[idx], "wu") == 0:
          logline = host + " " + results[idx] + " -wait until entry created"
          logger.logexit(logline)

          # get the wait code HH MM 
          try:
            codeHH = string.atoi(results[idx][2:4])
            codeMM = string.atoi(results[idx][4:6])
          except:
            codeHH = 0
            codeMM = 0
          codeHHMM = codeHH * 100 + codeMM

          # try to get the current time from the HTTP headers at dyndns 
          datetuple = headers.getdate("Date")
          if datetuple == None:
            logger.logit("Date header not found.  Using local clock.")
            datetuple = gmtime(time.time())
          currHH = datetuple[3]
          currMM = datetuple[4]
          currHHMM = currHH * 100 + currMM

          # compute the HHMM we need to wait
          if (codeHHMM <= currHHMM):
            # The codeHHMM is smaller than GMT of when we received the code.
            # Example: NIC returned 02:30 (codeHHMM) when we tried to update 
            # at 21:30 (currHHMM).  So we should be waiting 21:30 to 24:00
            # plus 00:00 to 02:30 seconds.
            waitHH = (23 - currHH) + codeHH
            waitMM = (60 - currMM) + codeMM
            logger.logit("Wraparound calculation.")
          else:
            waitHH = codeHH - currHH
            waitMM = codeMM - currMM
            logger.logit("Normal calculation.")
          
          # convert to seconds
          waitval = (waitHH * 60 + waitMM) * 60

          logger.logit("currHHMM = " + `currHHMM`)
          logger.logit("codeHHMM = " + `codeHHMM`)
          logger.logit("waitval  = " + `waitval`)

          # convert back to seconds
          #
          # save the until calculation to an ipcheck.wait file
          #
          fp = open (Waitfile, "a")
          fp.write("u " + `waitval` + "\n")
          currtime = time.time()
          fp.write(`time.time()` + "\n")
          fp.close()
          logger.logit("ipcheck.wait file created.")

          # set the localip so next update will be made
          localip = "0.0.0.0"

        elif string.find(results[idx], "w") == 0:
          logline = host + " " + results[idx] + " -wait entry created"
          logger.logexit(logline)

          #
          # save the waitcode to an ipcheck.wait file
          #
          fp = open (Waitfile, "a")
          fp.write(results[idx] + "\n")
          currtime = time.time()
          fp.write(`time.time()` + "\n")
          fp.close()
          logger.logit("ipcheck.wait file created.")

          # set the localip so next update will be made
          localip = "0.0.0.0"

        elif string.find(results[idx], "!donator") == 0:
          logline = host + " " + results[idx] + " -trying donator only feature"
          logger.logexit(logline)

          #
          # save the error to an ipcheck.err file
          #
          fp = open (Errfile, "a")
          fp.write("!donator " + host + "\n")
          fp.close()
          logger.logit("ipcheck.err FILE CREATED.")

          # set the localip so next update will be made
          localip = "0.0.0.0"

        # looks like the homeip.net domain gives blank lines sometimes???
        elif len(results[idx]) == 0:
          logger.logexit("BLANK RESULT LINE!  Please forward the following output")
          logger.logexit("(and logfile if you have one) to kal@users.sourceforge.net:")
          logger.logexit("updatehosts:")
          logger.logexit(`updatehosts`)
          logger.logexit("results:")
          logger.logexit(`results`)
          continue

        else:
          logline = host + " " + results[idx] + " -unknown result line"
          logger.logexit(logline)

        idx = idx + 1

      if success == 1 and opt_execute != "":
        os.system (opt_execute)

    else:
      logger.logexit("Unrecognized result page in ipcheck.html.")
      
    #
    # write the update data to file
    #
    if localip != "":
      fp = open (Datfile, "w")
      if opt_offline == 0:
        fp.write(localip + "\n")
      else:
        fp.write("1.0.0.0\n")

      # hostnames == updatehosts in the current version 
      # but that may change in future versions of the client
      for host in hostnames:
        fp.write(host + "\n")
      fp.close()
      logger.logit("ipcheck.dat file updated.")

  else:
    logger.logexit("Unrecognized errcode returned by dyndns server.")
    logger.logexit("Please send me the ipcheck.html file.")
    logger.logexit("kal@users.sourceforge.net")
    sys.exit(-1)


if __name__=="__main__":

  _main(sys.argv)




