1#!/usr/local/bin/python3.8
2import base64, getopt, urllib, httplib, os, re, sys, stat, string, time, telnetlib, socket, binascii, urllib2
3
4try:
5  import syslog
6except:  # for platforms without syslog that try to use --syslog option
7  class fake_syslog:
8    def openlog(self,foo):
9      raise Exception("Syslog not supported on this platform")
10    def syslog(self,foo):
11      raise Exception("Syslog not supported on this platform")
12  syslog = fake_syslog()
13
14try:
15  from pysnmp import session
16  from pysnmp import error
17except:
18  class fake_session:
19    class session:
20      def __init__(self, a, c):
21        raise Exception("Pysnmp missing, note you need version 1.x series of Pysnmp")
22  session = fake_session()
23
24
25Version = "0.240"
26
27#
28# ipcheck.py
29#
30# Copyright GNU GENERAL PUBLIC LICENSE Version 2
31# http://www.gnu.org/copyleft/gpl.html
32#
33# Author  : Kal <kal@users.sourceforge.net>
34#
35# Acknowledgements
36# ================
37#
38# dyndns crew             -a great service, reliable and professional
39# Bobby Griggs            -ls_dyndns.py client
40# Vincent Zweije          -HTTP Date header idea for wuHHMM codes
41# Todd Rose               -Various suggestions and Linksys support
42# Yaron Minsky            -syslog patch and RT311 support
43# Karen Chancellor        -RT311 tests
44# Johannes Maslowski      -Draytek Vigor support
45# Ulf Axelsson            -option -d fixes
46# Del Hodge               -Netopia R9100 support
47# Jan Bjorvik             -Cisco DSL support
48# Robert Towster          -SMC barricade
49# Onno Kortmann           -acctfile security suggestion
50# Greg Bentz              -Linksys firmware 1.37, BSD Default route
51# Erwin Burgstaller       -Cisco ISDN support
52# Allen Eastwood          -HawkingTech support
53# JP Szikora              -ZyXEL Prestige support
54# Remi Zara               -NetBSD info
55# Thomas Deselaers        -Debian package manpage
56# Steve Warner            -SNMP support
57# John Radimecky          -Watchguard SOHO support
58# Mark Anderson           -router global var bug, time, testrun, docs
59# Justin Kuo              -Nexland ISB2LAN
60# Mark Lederer            -MacOS X
61# Mark Aufflick           -Compex Netpassage 15
62# Ken Frank               -UgatePlus, BSD 4.3 info
63# Michel Bouissou         -Cayman DSL support
64# Jan Carlson             -Gnet ADSL router model BB0040 support
65# Tony Scicchitano        -BeOS local ip detection
66# Bas Heijermans          -OS/2 tips and code
67# Jeff Senn (jas)         -DLink DI701 w/PPPOE, Win32 Default Route
68# Jim Richardson          -RT314 tests
69# Andrew Gillham          -NetBSD route detection
70# K Scott                 -Netgear logout page
71# Neal Probert            -custom dns bug
72# Dave Burris             -sco openserver support
73# Jerome Sautret          -Eicon modem support
74# Daryl Boyd              -Nortel Instant Internet modem support
75# John Ruttenberg         -Nexland Pro800Turbo support, and auth fixes
76# Tony Scicchitano        -New SMC Barricade with password
77# Michael O'Quinn         -searching syslog option for IP
78# Lucas Bruand            -Check datfile for "w" mode
79# Jon Hart                -Pointing out 255 can be used in dotted quad
80# Cedric Moreau           -Alcatel Speed Touch Pro
81# Frank Adcock            -DLink DI804 patch
82# Darren Tucker           -tracking down 404 handling error
83# Tristan Hill            -snmpget option
84# Victor Ng               -platform strings case insensitive
85# David Jordan            -Netgear338 support
86# Juha Ylitalo            -code cleanup patches
87# Larry Kluger            -DLink DI713P support
88# Douglas Henke           -Siemens SpeedStream 2620 with password
89# Paul Andreassen         -add port forwarding for Alcatel Speed Touch Pro
90# J.D. Bronson            -upper opts typo, netgear 3114 fixes, zywall 10
91# Adam Jenkins            -Barricade 7004VWBR patch see --VWBR
92# Stephan Allene          -DLink DSL504 support
93# Stephan Allene          -Correct bug with DLink DSL504 support
94# Carl John Nobile        -badauth bug fix
95# Cobe Higginbottom       -DI704 no password patch
96# Marc Tanner             -DI614+ notes
97# For CISCO IOS: Hansjoerg G.Henker  BitH@GMX.DE - www.c-bit.org
98# Brad Crittenden         -VT1000v patch
99# Mark Keisler            -default route detection fix
100# Jason Anderson          -Linksys RT31P2 patch
101# Tuan Hoang              -SMC Barricade logout fix
102# Robert Holland          -Adtran Netvanta support
103# Gene Cumm               -Barricade 7004 fixes and ssl check
104# David Bresson           -Linsys WRT56G
105# Evan Carey              -Netgear WTG624
106# Jordi Pujol             -Alcatel SpeedStream v.4.3.2.6
107# Jordi Pujol             verify actual ip address with a DNS lookup
108# Jordi Pujol             possibility to specify values of wilcard and backup_mx
109#
110# global constants
111#
112Updatehost = "members.dyndns.org"
113Updatepage = "/nic/update"
114Useragent = "ipcheck/" + Version
115Fakeagent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)"
116
117Touchage = 25                       # days after which to force an update
118                                    # Touchage = 0 means don't ever force
119
120Linuxip = "/sbin/ifconfig"
121Win32ip = "ipconfig /all"
122Sunip = "/usr/sbin/ifconfig"
123BSDip = "/sbin/ifconfig"
124Macip = "/sbin/ifconfig"
125Beosip = "netstat"
126Os2ip = "ifconfig"
127scoip = "/etc/ifconfig"
128Otherip = "/sbin/ifconfig"
129
130Linuxrt = "/sbin/route -n"
131Win32rt = "route print"
132Sunrt = "/bin/netstat -irn"
133BSDrt = "/sbin/route -n get default"
134Macrt = "/usr/sbin/netstat -r"
135Beosrt = "netstat"
136Os2rt = "route -n get default"
137scort = "/usr/bin/netstat -nr"
138Otherrt = "/sbin/route -n show"
139
140
141# regular expression for address
142Addressgrep = re.compile ('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
143
144def Usage():
145  print """
146Make sure you can write to the current directory for data
147files and that you always run from the same directory.
148The first time you run the script, you will be asked to run
149with the --makedat option in addition to any other options.
150This will create the data files for the hostnames and options
151your specify on the command line.  You should only do this once.
152Subsequent runs should be made without the --makedat option.
153
154For help with different options: python ipcheck.py -h
155For supported devices listing  : python ipcheck.py --devices
156For long detailed help text    : python ipcheck.py --help
157
158Example 1: the external IP is on eth0 of the current machine
159python ipcheck.py -l -i eth0 username password hostnames
160
161Example 2: you are using the Linksys routing device
162python ipcheck.py -l -L linksyspassword username password hostnames
163
164Example 3: you want to use web based ip detection
165python ipcheck.py -l -r checkip.dyndns.org:8245 ...
166
167where ... is your dyndns username password and hostnames.
168Hostnames should be comma delimited if there are more than one.
169"""
170
171def Options():
172  print """
173Usage  : ipcheck.py [options] Username Password Hostnames
174or       ipcheck.py [options] --acctfile acct_info_file
175
176Options: -a address     manually specify the address
177         -r URL         NAT router, use web IP detection
178         -A text        scan syslog for an IP after text (Unix only)
179         -F filename    guess the WAN IP from a firewall log
180         -b VALUE       set backup mx option to VALUE (default NOCHG, values: YES|NO|NOCHG),
181                        if option is present without value, VALUE is YES
182         -c             custom dns option (default dynamic)
183         -d dir         directory for data files (default current)
184         -D             check also the ip against DNS services
185         -e script      execute script after a successful update
186         -f             force update regardless of current state
187         -g             NAT router, let dyndns guess your IP
188                        (do not use this in a cronjob, try -r)
189         -h             print this help text
190         --help         print all available help text
191         -i interface   interface for local address (default tun0)
192         -j             disable https
193         -l             log debugging text to ipcheck.log file
194         --syslog       log debugging text to syslog (Unix only)
195         -m mxhost      mx host (default NOCHG, values: mailexchanger|NOCHG)
196         -o             set dyndns offline mode
197         -p             proxy bypass on port 8245
198         -q             quiet mode (unless there is an error)
199         -s             static dns option (default dynamic)
200         -t             test run, do not send the update
201         -v             verbose mode
202         -w VALUE       set wildcard mode to VALUE (default NOCHG, values: ON|OFF|NOCHG)
203                        if option is present without value, VALUE is ON
204         --makedat      create the ipcheck.dat file by dns lookup
205         --devices      print router options (Linksys, Netgear, etc)
206         -n ip 		the router IP address on the internal lan
207
208For help with different options: python ipcheck.py -h
209For supported devices listing  : python ipcheck.py --devices
210For long detailed help text    : python ipcheck.py --help
211"""
212
213def Devices():
214  print """
215The script will locate the address of your router automatically by
216looking at the default route of the machine you are running on.
217Then it will read the status page for the external IP address
218and use that for updates.  You need to specify the admin password
219with the appropriate option."""
220# remember -A already used above
221  print """
222         --pfile        device password below is actually a filename
223         -B password    New Barricade with password on port 88
224         --VWBR         Use with -B to indicate 7004VWBR Router
225         -C password    Cisco (667i) DSL router password
226         -D password    Draytek (Vigor2000) NAT router password
227         -E             Eicon Diva (no password needed)
228         -G             UgatePlus (no password needed)"""
229# remember -F already used above
230  print """
231         -H password    HawkingTech router password
232         -I password    Cisco (700 series) ISDN router password
233         -J password    ZyXEL prestige 642ME router password
234         -K password    Compex NetPassage 15
235         -L password    Linksys (BEFSR41) NAT router password
236         -M password    MacSense password
237         -N password    Netgear RT311 NAT router password
238         -O password    Netopia (R9100) NAT router password
239         -P port[,password]
240                         Nexland Pro800Turbo, WAN port, port==any use the
241                         first connected port; port=[01] use the port'th port
242                         if available, else any; port=-[01] use port'th port
243                         if available, else fail.  Specify password if
244                         required.  For example, -P any,123 says to use the
245                         first port and password 123.  -P 1 says prefer port
246                         #1 and no password is required.  -P -0,xyz forces
247                         port 0 and uses password xyz.
248         -Q pword,iface password and interface for Instant Internet
249         -R password    Netgear FR3114 password
250         -S             SMC Barricade (no password needed)
251         --WBR password Use with -S if 2404WBR with password
252         -T password    Alcatel Speed Touch Pro password
253                        (you can also try -r 10.0.0.138/cgi/router/)
254         -V password    Eicon Diva (see -E for no password)
255         -W password    Watchguard SOHO NAT firewall password
256         -X             Nexland router (no password set)
257         -Y password    Cayman DSL 3220H NAT router password
258         -Z password    ZyXEL 642R and Zywall 10 router password
259         -1 password    DLink DSL504 password
260         -2 password    Siemens SpeedStream 2620 router password
261         -3 password    Netgear RT338 ISDN router
262         -4 password    Gnet model BB0040 ADSL router password
263         -5             DLink DI704 with no password
264         -6 password    DLink DI704 password
265         -7 password    DLink DI701 password
266         -8 password    DLink DI804/DI614+ password
267         -9 password    DLink DI713P password
268         --WTG624=password    Netgear WTG624 router
269         --VT1000v      Motorola VT1000v VoIP voice terminal (no password needed)
270         --Netvanta=password
271                        Adtran Netvanta series routers,
272                        both telnet and 'enable' passwords
273                        must be configured to be same value
274
275You can change the default username for the above devices with:
276
277         -U username    override the default NAT router username
278                        leave this option out to use the default
279
280For Cisco IOS devices and any others that understand SNMP, you
281can also use --snmp to detect the external IP.
282
283         --snmp snmp_agent,community,numeric_objectid
284
285You will need the v1.x pysnmp module from http://pysnmp.sourceforge.net/
286The snmp code does not work with v2.x or 3.x of pysnmp
287You also need to know the agent, community and numeric objectid:
288python ipcheck.py --snmp 172.62.254.254,public,.1.3.5.2.1.2.10.2.5.4 ...
289where ... = username password hostnames
290
291Alternate/Generic SNMP retrieval
292         --snmpget snmp_agent,community,numeric_objectid
293You will need the v1.x pysnmp module from http://pysnmp.sourceforge.net/
294The snmp code does not work with v2.x or 3.x of pysnmp
295You also need to know the agent(hostname or ip), community and
296numeric objectid:
297python ipcheck.py --snmpget router,public,.1.3.6.1.4.1.343.6.23.1.12.1.2.3 ...
298where ... = username password hostnames
299This option will do a snmp get to the specified objectid which needs to be
300that of the ip to be used in the update
301
302         --forward port[/protocol],...
303Ports to be forward from your router to this machine.
304Defaults to tcp protocol. Stay set until router turned off.
305example: -T password --forward=80,time/udp,21/6
306"""
307
308def HelpText():
309  print """
310Start ipcheck.py with no arguments to get some quick examples.
311
312The script creates data files in the current working directory.
313Make sure you have write permission and that you run the script
314from the same directory each time.  You can use the -d option
315to specify an alternate directory for data files.
316
317The first time you run the script, you will be asked to run
318with the --makedat option.  This will create the data files
319and complete the update.  You should only do this once.
320Subsequent runs should be made without the --makedat option.
321
322If -f is set, all hosts will be updated regardless of the
323current error, wait or IP state.  You should never need this.
324
325You can place your username password and hostnames in a file
326(all on the first line) and use the --acctfile option if you do
327not wish your password to show up on a ps.
328
329The best way to run ipcheck is in the /etc/ppp/ip-up.local file
330or the BSD ppp.linkup file (you will need to sleep 30 before
331running the script since ppp.linkup runs before the link is up.)
332The script will also run from a cronjob.  Just make sure the
333hostnames are the same in each execution.  You should make sure
334it is using the same directory each time for data files.  The -d
335option can be used to specify where data files go.
336
337The file ipcheck.dat contains the IP address and hostnames
338used in the last update.  If the ipcheck.dat file is older
339than """ + `Touchage` + """ days, an update will be made to touch the hostnames.
340
341The file ipcheck.wait is created if dyndns requests a wait
342before retrying.  This file will be automatically removed when
343the wait is no longer in effect.
344
345The file ipcheck.err is created if the response is an error.
346It will not try to update again until this error is resolved.
347You must remove the file yourself once the problem is fixed.
348
349If your ISP has a badly behaved transparent proxy on port 80
350traffic, you can try the -p option to use port 8245.
351
352If a http message is sent to dyndns.org, the response will be
353saved in the ipcheck.html file.
354
355Custom domains can be specified with the -c option.  You must
356first complete the create database step on the Dyndns web page.
357Suppose you have the domain ipcheck.org defined as an A record
358and your nodes aliased to ipcheck.org with CNAME records.  Use:
359python ipcheck.py -c username password ipcheck.org
360
361Note that if you intended to maintain both a custom domain and
362a dyndns domain (ie. ipcheck.dyndns.org) you should be using
363the -d option to keep the data files in separate directories.
364The custom domains are not compatible with the mx, backmx and
365wildcard options.  Setup your database accordingly.
366
367To be sure that the address is correct, the script performs a DNS
368lookup and checks the answer against the local database address.
369IMPORTANT: Updating DNS records takes some time, don't run this
370script repeatedly, wait more than 5 minutes for DNS updates.
371
372The script can find your public IP address in one of several ways:
373
3741) interface IP detection is the default method and appropriate
375if the machine you are running on has an interface with the public
376IP addressed assigned.  The script knows how to query various
377operating systems for the address of an interface specified
378with the -i option (default tun0).  Note on Win32 systems
379specify the MAC address device after -i and on BeOS systems
380specify the interface number after -i (eg. -i 1).
381
3822) router IP detection is used if you have a routing device
383such as a Netgear RT311.  Use the --devices option to get a
384help on specific devices.  This method is used by the script
385if you specify one of the device-related options.
386
3873) web IP detection may be used if your device is not supported
388python ipcheck.py -r checkip.dyndns.org:8245 ...
389where ... = username password hostnames
390This method is used if you specify the -r option.
391IMPORTANT: Do not run web based IP detection more often
392than once every 15 minutes.  It is costing dyndns bandwidth.
393
3944) you can explicitly set the desired IP address with -a
395
3965) when -g is used, the script will not send any IP address
397at all (even ones detected by the previous options).  Only
398the account information will be sent to the dyndns server.
399The dyndns server will assign the hostnames to the source
400IP address of the request.  The assigned address is saved in
401the ipcheck.dat file.  IMPORTANT: Do not run this from a cronjob
402unless you know the address saved in the ipcheck.dat file
403matches locally detected public IP to prevent unnecessary updates.
404
405If your have an unsupported device and are willing to help with
406some testing, email me.
407
408The ipcheck homepage can be found at:
409http://ipcheck.sourceforge.net/
410
411Client development information can be found at:
412http://support.dyndns.org/dyndns/clients/devel/
413
414Please include the ipcheck.log file if you email me with a problem.
415kal@users.sourceforge.net
416"""
417
418
419class Logger:
420  #
421  # open a new log file in the target dir if logging
422  # a race condition if there are tons of scripts
423  # starting at the same time and should really use locking
424  # but that would be overkill for this app
425  #
426  def __init__(self, logname = "ipcheck.log", verbose = 0, logging = 0, use_syslog = 0):
427    self.logname = logname
428    self.verbose = verbose
429    self.logging = logging
430    self.syslog = use_syslog
431    self.prefix = "ipcheck.py: "
432
433    asctime = time.asctime(time.localtime(time.time()))
434
435    if self.syslog:
436      syslog.openlog("ipcheck")
437    if self.logging:
438      self.logfp = open(self.logname, "w")
439      self.logfp.write(Useragent + "\n")
440      self.logfp.write(self.prefix + asctime + "\n")
441      self.logfp.write(self.prefix + "logging to " + self.logname + "\n")
442      self.logfp.close()
443    if self.verbose:
444      print Useragent
445      print self.prefix + asctime
446
447  # normal logging message
448  def logit(self, logline):
449    if self.verbose:
450      print self.prefix + logline
451      if self.syslog:
452        syslog.syslog(logline)
453    if self.logging:
454      self.logfp = open(self.logname, "a")
455      self.logfp.write(self.prefix + logline + "\n")
456      self.logfp.close()
457
458  # logging message that gets printed even if not verbose
459  def logexit(self, logline):
460    print self.prefix + logline
461    if self.logging:
462      self.logfp = open(self.logname, "a")
463      self.logfp.write(self.prefix + logline + "\n")
464      self.logfp.close()
465    if self.syslog:
466      syslog.syslog(logline)
467
468
469def DefaultRoute(logger, Tempfile):
470  logger.logit("Searching default route on sys.platform = " + sys.platform)
471  iphost = ""
472  platform = string.lower(sys.platform)
473  if string.find(platform, "win32") != -1:
474    logger.logit("WIN32 default route detection for router.")
475    os.system (Win32rt + " > " + Tempfile)
476    fp = open(Tempfile, "r")
477    try:
478     while 1:
479      fileline = fp.readline()
480      if not fileline:
481        break
482      # jas:
483      # the code that was here did not work at all for the output
484      # of 'route print' on my win98 box.
485      # Here is a very simple version that works well...
486      tst = string.split(fileline)
487      if len(tst) > 2 and tst[0] == "0.0.0.0":
488        iphost = tst[2]
489        break
490    finally:
491       fp.close()
492  elif string.find(platform, "linux") != -1:
493    logger.logit("Linux default route detection for router.")
494    fp = os.popen(Linuxrt, "r")
495    lines = string.split(fp.read(), "\n")
496    fp.close()
497    for fileline in lines:
498      if string.find(fileline, "UG") != -1:
499        if string.find(fileline, "0.0.0.0") != -1:
500          ipmatch = Addressgrep.search(fileline)
501          ip1 = ipmatch.group()
502          p1 = string.find(fileline, ip1) + len(ip1)
503          ipmatch = Addressgrep.search(fileline, p1)
504          iphost = ipmatch.group()
505          break
506
507  elif string.find(platform, "sunos") != -1:
508    logger.logit("Sunos default route detection for router.")
509    fp = os.popen(Sunrt, "r")
510    content = fp.read()
511    fp.close()
512    p1 = string.find(content, "default")
513    if p1 != -1:
514      ipmatch = Addressgrep.search(content, p1+8)
515      iphost = ipmatch.group()
516
517  elif string.find(platform, "darwin") != -1:
518    logger.logit("Darwin default route detection for router.")
519    fp = os.popen(Macrt, "r")
520    content = fp.read()
521    fp.close()
522    p1 = string.find(content, "default")
523    if p1 != -1:
524      ipmatch = Addressgrep.search(content, p1+8)
525      iphost = ipmatch.group()
526
527  elif string.find(platform, "netbsd") != -1:
528    logger.logit("NetBSD default route detection for router.")
529    fp = os.popen(BSDrt, "r")
530    content = fp.read()
531    fp.close()
532    p1 = string.find(content, "gateway")
533    if p1 != -1:
534      ipmatch = Addressgrep.search(content, p1+8)
535      iphost = ipmatch.group()
536
537  elif string.find(platform, "freebsd") != -1:
538    logger.logit("Freebsd default route detection for router.")
539    fp = os.popen(BSDrt, "r")
540    content = fp.read()
541    fp.close()
542    p1 = string.find(content, "gateway")
543    if p1 != -1:
544      ipmatch = Addressgrep.search(content, p1+8)
545      iphost = ipmatch.group()
546
547  elif string.find(platform, "os2") != -1:
548    logger.logit("OS2 default route detection for router.")
549    os.system (Os2rt + " > " + Tempfile)
550    fp = open(Tempfile, "r")
551    while 1:
552      fileline = fp.readline()
553      if not fileline:
554        break
555      p1 = string.find(fileline, "default")
556      if p1 != -1:
557        ipmatch = Addressgrep.search(fileline, p1+8)
558        iphost = ipmatch.group()
559        break
560    fp.close()
561
562  elif string.find(platform, "sco") != -1:
563    logger.logit("SCO default route detection for router.")
564    os.system (Scort + " > " + Tempfile)
565    fp = open(Tempfile, "r")
566    while 1:
567      fileline = fp.readline()
568      if not fileline:
569        break
570      p1 = string.find(fileline, "default")
571      if p1 != -1:
572        ipmatch = Addressgrep.search(fileline, p1+8)
573        iphost = ipmatch.group()
574        break
575    fp.close()
576
577  elif string.find(platform, "beos") != -1:
578    logger.logexit("BeOS default route detection via network settings file.")
579    fp = open("/boot/home/config/settings/network", "r")
580    while 1:
581      fileline = fp.readline()
582      if not fileline:
583        break
584      p1 = string.find(fileline, "ROUTER")
585      if p1 != -1:
586        ipmatch = Addressgrep.search(fileline, p1+8)
587        iphost = ipmatch.group()
588        break
589    fp.close()
590
591  else:
592    logger.logit("Unknown platform default route detection for router.")
593    os.system (Otherrt + " > " + Tempfile)
594    fp = open(Tempfile, "r")
595    while 1:
596      fileline = fp.readline()
597      if not fileline:
598        break
599      p1 = string.find(fileline, "default")
600      if p1 != -1:
601        ipmatch = Addressgrep.search(fileline, p1+8)
602        iphost = ipmatch.group()
603        break
604    fp.close()
605
606  return iphost
607
608
609def BasicAuth(logger, iphost, page, user, passwd, outfile):
610
611  ipdata = ""
612  try:
613    logger.logit("Basic authentication page: " + page)
614    h1 = httplib.HTTP(iphost)
615    h1.putrequest("GET", page)
616    fakeagent = "Mozilla/4.76 [en] (X11; U; Linux 2.4.1-0.1.9 i586)"
617    h1.putheader("USER-AGENT", fakeagent)
618    authstring = base64.encodestring(user + ":" + passwd)
619    authstring = string.replace(authstring, "\012", "")
620    h1.putheader("AUTHORIZATION", "Basic " + authstring)
621    h1.endheaders()
622    errcode, errmsg, headers = h1.getreply()
623    fp = h1.getfile()
624    ipdata = fp.read()
625    fp.close()
626  except:
627    logline = "Failed connecting to router at " + iphost
628    logger.logexit(logline)
629    logger.logexit("Exception: " + `sys.exc_info()[0]`)
630    sys.exit(-1)
631
632  # create an output file of the response
633  fp = open(outfile, "w")
634  fp.write(ipdata)
635  fp.close()
636  logger.logit(outfile + " file created")
637
638  return ipdata
639
640
641
642#
643# taken directly from the examples directory in pysnmp distribution
644# http://pysnmp.sourceforge.net/
645#
646# results of run are stored in retval and returned
647#
648class snmptable (session.session):
649    """Retrieve a table from remote SNMP process
650    """
651    def __init__ (self, agent, community):
652        """Explicitly call superclass's constructor as it gets overloaded
653           by this class constructor and pass a few arguments alone.
654        """
655        session.session.__init__ (self, agent, community)
656
657    def run (self, objids):
658        """Query SNMP agent for one or more Object IDs. The objid
659           argument should be a list of strings where each string
660           represents an Object ID in dotted numbers notation
661           (e.g. ['.1.3.6.1.4.1.307.3.2.1.1.1.4.1']).
662        """
663
664        # clear the retval
665        retval = []
666
667        # Convert string type Object ID's into numeric representation
668        numeric_objids = map (self.str2nums, objids)
669
670        # BER encode SNMP Object ID's to query
671        encoded_objids = map (self.encode_oid, numeric_objids)
672
673        # Since we are going to _query_ SNMP agent for Object ID's
674        # associated value, there will be no variable values passed to
675        # SNMP agent.
676        encoded_values = []
677
678        # Remember the beginning of the table
679        head_encoded_objid = encoded_objids[0]
680
681        # Traverse the agent's MIB
682        while 1:
683            # Build a complete SNMP message of type 'GETNEXTREQUEST', pass it
684            # a list BER encoded Object ID's to query and an empty list of values
685            # associated with these Object ID's (empty list as there is no point
686            # to pass any variables values along the SNMP GETNEXT request)
687            question = self.encode_request ('GETNEXTREQUEST', encoded_objids, encoded_values)
688
689            # Try to send SNMP message to SNMP agent and receive a response.
690            answer = self.send_and_receive (question)
691
692            # Catch SNMP exceptions
693            try:
694                # As we get a response from SNMP agent, try to disassemble SNMP reply
695                # and extract two lists of BER encoded SNMP Object ID's and
696                # associated values).
697                (encoded_objids, encoded_values) = self.decode_response (answer)
698
699            # SNMP agent reports 'no such name' when table is over
700            except error.SNMPError, why:
701                # If NoSuchName
702                if why.status == 2:
703                    # Return as we are done
704                    return retval
705                else:
706                    raise error.SNMPError(why.status, why.index)
707
708            # Stop at the end of the table
709            if not self.oid_prefix_check (head_encoded_objid, encoded_objids[0]):
710                # Return as we are done
711                return retval
712
713            # Decode BER encoded Object ID.
714            objids = map (self.decode_value, encoded_objids)
715
716            # Decode BER encoded values associated with Object ID's.
717            values = map (self.decode_value, encoded_values)
718
719            # Convert two lists into a list of tuples for easier printing
720            results = map (None, objids, values)
721
722            # Just print them out
723            # for (objid, value) in results:
724            #    print objid + ' ---> ' + str(value)
725            retval = retval + results
726
727    def getrow (self, objid):
728        """Query SNMP agent for one Object ID. The objid argument
729           should be a string representing a Object ID in dotted
730           numbers notation
731           (e.g. '.1.3.6.1.4.1.307.3.2.1.1.1.4.1').
732        """
733        # Convert string type Object IDs into numeric representation
734        numeric_objid = self.str2nums(objid)
735
736        # BER encode SNMP Object IDs to query
737        encoded_objid = self.encode_oid(numeric_objid)
738
739        # Build a complete SNMP message
740        question = self.encode_request ('GETREQUEST', [encoded_objid], [])
741
742        # Try to send SNMP message to SNMP agent and receive a response.
743        answer = self.send_and_receive (question)
744
745        # As we get a response from SNMP agent, try to disassemble SNMP reply
746        # and extract two lists of BER encoded SNMP Object IDs and
747        # associated values).
748        (_encoded_objids, encoded_values) = self.decode_response (answer)
749
750        # Decode BER encoded value.
751        return self.decode_value(encoded_values[0])
752###########################################################################
753# Ipcheckfile is common baseclass for Datfile and Errorfile
754class Ipcheckfile:
755  # Constructor
756  # You can give filename in here or leave it later.
757  def __init__(self, fname=None):
758    self.fname = fname
759
760  # getFilename
761  # Return: Filename (just matter of courtesy to make method for it)
762  def getFilename(self):
763    return self.fname
764
765  # setFilename (just matter of courtesy to make method for it)
766  def setFilename(self, fname):
767    self.fname = fname
768
769  # exists
770  # Return: 1, file exists
771  #         0, file doesn't exist
772  # Note: this doesn't say that you can necessarily read it.
773  def exists(self):
774    exists = 0
775    if "access" in os.__dict__.keys():
776       exists = os.access (self.fname, os.F_OK)
777    else:
778      try:
779        fp = open (self.fname, "r")
780        fp.close()
781        exists = 1
782      except:
783        pass
784    return exists
785
786###########################################################################
787# Datfile handles reading and writing of datfile.
788# Format:
789# IPaddress
790# hostname1
791# hostname2
792# hostname3
793# ...
794# Variables:
795# - fname - name of datfile
796# - ip - our public IP address
797# - hostnames - list of hostnames related to the IP address on first line.
798class Datfile(Ipcheckfile):
799  #
800  # Constructor
801  def __init__(self, fname = None):
802    Ipcheckfile.__init__(self, fname)
803    self.ip = None
804
805  #
806  # Age of file based on difference between current time and the time,
807  # when it was last modified.
808  # Return: time difference in seconds.
809  def getAge(self):
810    currtime = time.time()
811    mtime = os.stat(self.fname)[stat.ST_MTIME]
812    fileage = (currtime - mtime) / (60*60*24)
813    return fileage
814
815  #
816  # read
817  # Read content of file and return tuple, where first variable is
818  # your public IP and second is list of hostnames assosiated to it.
819  # Return: (ip,list of hostnames)
820  def read(self):
821    fp = open(self.fname, "r")
822    lines = string.split(fp.read(), "\n")
823    fp.close()
824    ip = lines[0]
825    hosts = []
826    for line in lines[1:]:
827      if line:
828        hosts.append(line)
829    assert hosts
830    return (ip,hosts)
831
832  # setIP
833  # setIP for write() that will happen later.
834  def setIP(self, ip):
835    self.ip = ip
836
837  # write
838  # Write valid datfile based on ip and hostnames information.
839  # If caller has not given them, use the values that have been
840  # stored into instance variables.
841  def write(self, ip = None, hostnames = None):
842    if not ip:
843      ip = self.ip
844
845    assert ip and hostnames
846    fp = open(self.fname, "w")
847    fp.write(ip + "\n")
848    for host in hostnames:
849      fp.write(host + "\n")
850    fp.close()
851
852
853###########################################################################
854# Errorfile handles reading, writing and analyzing of errfile.
855class Errorfile(Ipcheckfile):
856  #
857  # Constructor
858  # You can give filename in here or leave it later.
859  def __init__(self, logger, fname = None):
860    self.logger = logger
861    Ipcheckfile.__init__(self, fname)
862
863  # analyze
864  # analyze content of existing errorfile.
865  # Parameters:
866  # - username that user would like to use.
867  # - password that user would like to use.
868  # - hostnames that user would like to update.
869  # Return:
870  # 1 - if fatal errors were encountered
871  # 0 - if its OK to continue
872  def analyze(self, username, password, hostnames):
873    # generic_cases always print same message"
874    generic_cases = {
875      "badagent" : ["Badagent contact author at kal@users.sourceforge.net."],
876      "dnserr"   : ["Contact support@dyndns.org about dnserr error.",
877                    "Attach the ipcheck.html file for details.",
878                    "Erase the ipcheck.err file when the problem is fixed."],
879      "numhost"  : ["Contact support@dyndns.org about numhost error.",
880                    "Attach the ipcheck.html file for details.",
881                    "Erase the ipcheck.err file when the problem is fixed."],
882      "shutdown" : ["Service shutdown from dyndns.org",
883                    "Check http://www.dyndns.org/status.shtml",
884                    "Erase the ipcheck.err file when shutdown is over."]
885    }
886    # one_param cases add first argument to the end of first line.
887    one_param = {
888      "badsys" :   ["system error",
889                    "Erase the ipcheck.err file if this is correct now."],
890      "!donator" : ["!donator",
891                    "Erase the ipcheck.err file when this problem is fixed."],
892    }
893    # hostname cases are shown only if first argument in error matches with
894    # one of the hostnames that we would like to update.
895    # Problematic hostname is shown at the end of first line.
896    hostname_cases = {
897      "abuse" :   ["abuse lockout",
898                   "Use the form at http://support.dyndns.org/dyndns/abuse.shtml",
899                   "Erase the ipcheck.err file when dyndns notifies you (by email)." ],
900      "!active" : ["!active",
901                   "You need to activate your Custom domain first.",
902                   "Dyndns may require it to be properly delegated.",
903                   "Erase the ipcheck.err file when the problem is fixed."],
904      "nohost"  : ["nohost",
905                   "You may be trying -s for a dynamic host or vice versa.",
906                   "Erase the ipcheck.err if file this host is now created."],
907      "notfqdn" : ["notfqdn",
908                   "Erase the ipcheck.err file if this is really correct."],
909      "!yours"  : ["!yours",
910                   "Erase the ipcheck.err file when the problem is fixed."],
911    }
912
913    self.logger.logit("Handling errors in ipcheck.err file.")
914    errors = []
915    fatal = 0
916    if self.exists():
917      fp = open(self.fname, "r")
918      errors = string.split(fp.read(), "\n")
919      fp.close()
920    for err in errors:
921      fatal = 1
922      errlist = string.split(err, " ")
923      if err[:7] == "badauth":
924        self.logger.logit("badauth found.")
925        if errlist[1] == username and errlist[2] == password:
926          self.logger.logexit("Previous authorization error encountered for")
927          self.logger.logexit("Username:" + username)
928          self.logger.logexit("Password:" + password)
929          self.logger.logexit("Erase the ipcheck.err file if this is correct now.")
930        else:
931          self.logger.logit("trying new username or password.")
932          self.logger.logit("ipcheck.err file removed and continuing.")
933          os.unlink(self.fname)
934          fatal = 0
935      elif errlist[0] in generic_cases.keys():
936        self.logger.logit(errlist[0] + " found.")
937        for line in generic_cases[errlist[0]]:
938          self.logger.logexit(line)
939      elif errlist[0] in one_param.keys():
940        self.logger.logit(errlist[0] + " found.")
941        self.logger.logexit("Previous " + one_param[errlist[0]][0] + " encountered for " + errlist[1])
942        for line in one_param[errlist[0]][1:]:
943          self.logger.logexit(line)
944      elif errlist[0] in hostname_cases.keys():
945        self.logger.logit(errlist[0] + " found.")
946        if errlist[1] in hostnames:
947          self.logger.logexit("Previous " + hostname_cases[errlist[0]][0] + " encountered for host: " + errlist[1])
948          for line in hostname_cases[errlist[0]][1:]:
949            self.logger.logexit(line)
950        else:
951          fatal = 0
952      elif err:
953        self.logger.logexit("Unrecognized error in ipcheck.err file.")
954        self.logger.logexit("Erase the ipcheck.err if there is no problem.")
955      else:
956        fatal = 0
957      if fatal:
958        break
959
960    return fatal
961
962  def write(self, description, fatal=None):
963    if fatal:
964      mode = "w"
965    else:
966      mode = "a"
967    old = self.exists()
968    fp = open(self.fname, mode)
969    fp.write(description + "\n" )
970    fp.close()
971    if not old:
972      self.logger.logit("ipcheck.err FILE CREATED.")
973
974# acctfile has account information about your dyndns account.
975# Format: username password hostname1,hostname2,hostname3
976# Parameters:
977# - acctfile - filename for account information
978# - logger - instance of Logger for logging
979# Return: ["username", "password", "hostname1,hostname2,hostname3"]
980# Exception:
981# - sys.exit(-1) in all problems.
982def read_acctfile(fname, logger):
983  try:
984    fp = open (fname, "r")
985    data = fp.read()
986    fp.close()
987  except:
988    logger.logexit("Bad acctfile: " + fname)
989    logger.logexit("Exception: " + `sys.exc_info()[0]`)
990    sys.exit(-1)
991
992  fields = string.split(data)
993  if len(fields) != 3:
994    logline = "File does not contain 3 arguments: " + fname
995    logger.logexit(logline)
996    sys.exit(-1)
997  return fields
998
999def read_pfile(fname, logger):
1000  if string.find(fname, "--pfile") != -1:
1001    logger.logexit("Bad usage.  Try: --pfile -X filename")
1002    logger.logexit("where X is the option letter for your device.")
1003    logger.logexit("Do not put the filename right after the --pfile option.")
1004    sys.exit(-1)
1005
1006  try:
1007    fp = open (fname, "r")
1008    data = fp.read()
1009    fp.close()
1010  except:
1011    logger.logexit("Bad pfile: " + fname)
1012    logger.logexit("Exception: " + `sys.exc_info()[0]`)
1013    sys.exit(-1)
1014
1015  # strip training CRLF
1016  if data[-1] == '\n' or data[-1] == '\r':
1017    data = data[:-1]
1018  if data[-1] == '\n' or data[-1] == '\r':
1019    data = data[:-1]
1020
1021  return data
1022
1023# check_ip verifies that ip address, which we are planning
1024# to send to dyndns.org is really valid.
1025# Parameters:
1026# - localip - ip that we are planning to send
1027# Return:
1028# - None, if its valid
1029# - string, which explains why its not valid.
1030def check_ip(localip):
1031  logline = None
1032  if not localip:
1033    # check if the router elif's found no address
1034    logline = "No address found on router."
1035  elif localip == "0.0.0.0":
1036    # check if detected ip is not valid
1037    logline = "The router has external IP 0.0.0.0 assigned. "
1038  elif string.count(localip, ".") != 3:
1039    # check the IP to make sure it is sensible
1040    logline = "Invalid local address " + localip
1041  else:
1042    octets = string.split(localip, ".")
1043    ip = [0,0,0,0]
1044    try:
1045      for i in range(4):
1046        ip[i] = int(octets[i])
1047    except:
1048      ip = [0,0,0,0]
1049
1050    # 0-255 in first three allowed, 1-255 in last also
1051    if ip[0] < 0 or ip[0] > 255 \
1052    or ip[1] < 0 or ip[1] > 255 \
1053    or ip[2] < 0 or ip[2] > 255 \
1054    or ip[3] < 0 or ip[3] > 255:
1055      logline = "Invalid local address " + localip
1056
1057  return logline
1058
1059# check_public_ip verifies that given ip address does not belong to
1060# one of those private ip address spaces, which are reserved for
1061# intranet use.
1062# Parameters:
1063# - localip - ip that needs checking
1064# Return:
1065# - None, if its private address
1066# - string, if its valid address
1067def check_public_ip(localip):
1068  if localip[:4] != "127." \
1069  and localip[:8] != "192.168." \
1070  and localip[:3] != "10." \
1071  and localip[:4] != "172." \
1072  and localip[:2] != "0." \
1073  and string.find(localip, "255") == -1:
1074    return localip
1075  return None
1076
1077def _main(argv):
1078
1079  #
1080  # ROUTER SUPPORT GLOBALS
1081  #
1082  # leave Linksys_host = "" to autodetect via the default route
1083  # enter an ip here to skip the autodetect, this goes for all
1084  # the xxxx_host variables below
1085  #
1086  routerIP = ""
1087
1088  #
1089  # Linksys router support details from bgriggs@pobox.com
1090  #
1091  Linksys_user = " "
1092  Belkin_f5d7230_page = "/"
1093  Linksys_page = "/Status.htm"
1094
1095  Macsense_user = " "
1096  Macsense_page = "/Status.htm"
1097
1098  #
1099  # Motorola VT1000v
1100  MotorolaVT1000v_page = "/startupdata.html"
1101  #username and password are not needed
1102
1103
1104  #
1105  # Netgear router support
1106  #
1107  Netgear_user = "admin"
1108  Netgear_page = "/mtenSysStatus.html"
1109  Netgear314_page1 = "/rpMten.html"
1110  Netgear314_page2 = "/mtenSysStatus.html"
1111  NetgearFR_page = "/auth.html"
1112  Netgear_logout = "/Logout.html"
1113
1114  Netgear3114_user = "admin"
1115  Netgear3114_page1 = "/"
1116  Netgear3114_page2 = "/st_dhcp.htm"
1117  Netgear3114_page3 = "/logout.htm"
1118
1119  # Gene Cumm--Netgear FVS318	//GRC
1120  NetgearFVS318_page = "/sysstatus.html"
1121
1122  # Netgear WTG624
1123  NetgearWTG624_page1 = "/"
1124  NetgearWTG624_page2 = "/RST_status.htm"
1125  NetgearWTG624_page3 = "/LGO_logout.htm"
1126
1127  #
1128  # DLink DI-804/DI-614+ router support
1129  #
1130  DI804_user = "admin"
1131  DI804_page = "/doc/m3.htm"
1132  DI614_page = "/st_devic.html"
1133
1134  #
1135  # DLink DI-713P router support
1136  #
1137  DI713P_user = "root"
1138  DI713P_page = "/cgi-bin/logi"
1139
1140  #
1141  # DLink DI-704 router with no password support
1142  #
1143  DInop_user = "admin"
1144  DInop_page = "status.htm"
1145
1146  #
1147  # DLink DI-704 router support
1148  #
1149  DI704_user = "root"
1150  DI704_page = "/cgi-bin/logi"
1151
1152  #
1153  # DLink DSL-504 router support
1154  #
1155  DSL504_user = "admin"
1156  DSL504_page = "/sum/RoutingTable_ntpr.html"
1157
1158  #
1159  # Draytek Vigor2000 router support
1160  #
1161  Draytek_user = "admin"
1162  Draytek_page = "/doc/digisdn.sht"
1163
1164  #
1165  # Netopia R9100 router support
1166  #
1167  Netopia_user = ""
1168  Netopia_page = "/WanEvtLog"
1169
1170  #
1171  # Cisco routers (667 and 770)
1172  # uses telnet with no user name
1173  #
1174
1175  #
1176  # Adtran Netvanta routers
1177  # uses telnet with no user name
1178  #
1179
1180  #
1181  # SMC Barricade
1182  #
1183  SMC_page = "/status.HTM"
1184  #username and password are not needed
1185
1186  #
1187  # HawkingTech router support
1188  #
1189  Hawking_user = "admin"
1190  Hawking_page = "/Monitor.htm"
1191
1192  #
1193  # ZyXEL router support, uses telnet
1194  #
1195
1196  #
1197  # DI701 router support, uses telnet
1198  #
1199
1200  #
1201  # Watchguard SOHO firewall/router support
1202  #
1203  Watchguard_user = "admin"
1204  Watchguard_page = "/sysstat.htm"
1205  Watchguard_page2 = "/external.htm"
1206
1207  #
1208  # Nexland (but see Pro800Turbo, below)
1209  #
1210  Nexland_page = "/status.htm"
1211  #username and password are not needed
1212
1213  #
1214  # Nexland Pro800Turbo
1215  #
1216  Pro800Turbo_page = "/status.html"
1217  Pro800Turbo_port = "any"
1218  Pro800Turbo_port_number = 0
1219  #username and password are not needed
1220
1221  #
1222  # UgatePlus
1223  #
1224  Ugate_page = "/st_dhcp.htm"
1225  #username and password are not needed
1226
1227  #
1228  # Eicon Diva 2430 SE ADSL Modem
1229  #
1230  Eicon_page = "/Status.htm"
1231  #username and password are not needed
1232
1233  #
1234  # Eicon Diva with password
1235  #
1236  Veicon_user = ""
1237  Veicon_page = "/login.htm"
1238
1239  # Instant Internet router
1240
1241  #
1242  # Compex NetPassage 15
1243  # uses telnet with no username
1244  #
1245
1246  #
1247  # Cayman DSL 3220-H
1248  # uses telnet
1249  #
1250  Cayman_user = "admin"
1251
1252  #
1253  # Gnet model BB0040 ADSL router
1254  # uses telnet
1255  #
1256  Gnet_user = ""
1257
1258  #
1259  # Netgear RT338 ISDN router
1260  # uses telnet
1261  #
1262  Netgear338_user = ""
1263
1264  #
1265  # Newer SMC Barricade with password on port 88
1266  #
1267  Barricade_user = "admin"
1268  Barricade_page = "/status.HTM"
1269
1270  #
1271  # Siemens SpeedStream 2620 with password on port 88
1272  #
1273  Siemens2620_page = "/MAIN.HTM"
1274
1275  #
1276  # Alcatel Speed Touch Pro uses telnet
1277  #
1278  # username is not needed
1279  Alcatel_user = " "
1280
1281  #
1282  # default options
1283  #
1284  opt_address = ""
1285  opt_force = 0
1286  opt_checkDNS = 0
1287  opt_logging = 0
1288  opt_syslog  = 0
1289  opt_verbose = 0
1290  opt_hostnames = ""
1291  opt_interface = "tun0"
1292  opt_username = ""
1293  opt_password = ""
1294  opt_static = 0
1295  opt_wildcard = "NOCHG"
1296  opt_backupmx = "NOCHG"
1297  opt_mxhost = "NOCHG"
1298  opt_proxy = 0
1299  opt_router = ""
1300  opt_guess = 0
1301  opt_quiet = 0
1302  opt_offline = 0
1303  opt_execute = ""
1304  opt_directory = ""
1305  opt_acctfile = ""
1306  opt_pfile = 0
1307  opt_natuser = ""
1308  opt_forward = []
1309  opt_Linksys_password = ""
1310  opt_Linksys_router = 0
1311  opt_Netgear_password = ""
1312  opt_Netgear3114_password = ""
1313  opt_NetgearWTG624_password = ""
1314  opt_Draytek_password = ""
1315  opt_Netopia_password = ""
1316  opt_Cisco_password = ""
1317  opt_SMC_router = 0
1318  opt_Nexland_router = 0
1319  opt_Pro800Turbo_router = 0
1320  opt_ISDNCisco_password = ""
1321  opt_Hawking_password = ""
1322  opt_Zyxel_password = ""
1323  opt_Zyxel_ME_password = ""
1324  opt_Watchguard_password = ""
1325  opt_DInop_router = 0
1326  opt_DI704_password = ""
1327  opt_DI701_password = ""
1328  opt_DI713P_password = ""
1329  opt_DI804_password = ""
1330  opt_DSL504_password = ""
1331  opt_snmp_agent = ""
1332  opt_snmp_community = ""
1333  opt_snmp_objectid = ""
1334  opt_snmp_agent_prefix = ""
1335  opt_custom = 0
1336  opt_testrun = 0
1337  opt_makedat = 0
1338  opt_Compex_password = ""
1339  opt_Cayman_password = ""
1340  opt_Gnet_password = ""
1341  opt_Ugate_router = 0
1342  opt_II_password = ""
1343  opt_Belkin_f5d7230_router = 0
1344  opt_II_interface = ""
1345  opt_Eicon_router = 0
1346  opt_Veicon_password = ""
1347  opt_Barricade_password = ""
1348  opt_7004VWBR = 0
1349  opt_WBR = ""
1350  opt_Siemens2620_password = ""
1351  opt_after_syslog = ""
1352  opt_firewall_log = ""
1353  opt_Macsense_password = ""
1354  opt_MotorolaVT1000v_router = 0
1355  opt_AlcatelSTP_password = ""
1356  opt_no_https = 0
1357  opt_Netgear338_password = ""
1358  opt_Netvanta_password = ""
1359
1360  #
1361  # parse the command line options
1362  #
1363  if len(argv) == 1:
1364    Usage()
1365    sys.exit(0)
1366
1367  try:
1368    loweropts = "a:bcd:e:fghi:jlm:n:opqr:stvw"
1369    upperopts = "A:B:C:D:EF:GH:I:J:K:L:M:N:O:P:Q:R:ST:U:V:W:XY:Z:1:2:3:4:56:7:8:9:"
1370    wordopts = ["syslog", "pfile", "acctfile=", "help", "devices", "snmp=", "makedat", "snmpget=", "forward=", "VWBR", "WBR=", "VT1000v", "Netvanta=","WTG624=", "Belkin_f5d7230"]
1371    opts, args = getopt.getopt(argv[1:], loweropts+upperopts, wordopts)
1372  except getopt.error, reason:
1373    print reason
1374    sys.exit(-1)
1375
1376  #
1377  # PYTHON GURU NEEDED
1378  #
1379  # Is there any way in python to set argv to hide the command line?
1380  # ala the perl $0 = "orcus [accepting connections]";
1381  #
1382  # http://theoryx5.uwinnipeg.ca/CPAN/perl/pod/perlfaq8/Is_there_a_way_to_hide_perl_s_command_line_from_programs_such_as_ps_.html
1383  #
1384
1385  #
1386  # check verbose, logging and detailed help options first
1387  # check directory to place logging file
1388  #
1389  for opt in opts:
1390    (lopt, ropt) = opt
1391    if lopt == "-l":
1392      opt_logging = 1
1393    elif lopt == "--syslog":
1394      opt_syslog = 1
1395    elif lopt == "-v":
1396      opt_verbose = 1
1397    elif lopt == "--devices":
1398      Devices()
1399      sys.exit(0)
1400    elif lopt == "--help":
1401      Usage()
1402      Options()
1403      Devices()
1404      HelpText()
1405      sys.exit(0)
1406    elif lopt == "-h":
1407      Options()
1408      sys.exit(0)
1409    elif lopt == "-d":
1410      if os.path.isdir(ropt):
1411        opt_directory = ropt
1412      else:
1413        print "bad directory option"
1414        sys.exit()
1415
1416      # fix the dir name to end in slash
1417      if opt_directory[-1:] != "/":
1418        opt_directory = opt_directory + "/"
1419
1420  #
1421  # create the logger object
1422  #
1423  if opt_directory:
1424    logger = Logger(opt_directory + "ipcheck.log", opt_verbose, opt_logging, opt_syslog)
1425    logline = "opt_directory set to " + opt_directory
1426    logger.logit(logline)
1427  else:
1428    logger = Logger("ipcheck.log", opt_verbose, opt_logging, opt_syslog)
1429
1430  #
1431  # check acctfile option
1432  #
1433  for opt in opts:
1434    (lopt, ropt) = opt
1435    if lopt == "--acctfile":
1436      opt_acctfile = ropt
1437      logline = "opt_acctfile set to " + opt_acctfile
1438      logger.logit(logline)
1439
1440  #
1441  # check pfile option
1442  #
1443  for opt in opts:
1444    (lopt, ropt) = opt
1445    if lopt == "--pfile":
1446      opt_pfile = 1
1447      logline = "opt_pfile set"
1448      logger.logit(logline)
1449
1450  if len(args) != 3 and not opt_acctfile:
1451    Usage()
1452    sys.exit(0)
1453
1454  #
1455  # okay now parse rest of the options and log as needed
1456  #
1457  for opt in opts:
1458    (lopt, ropt) = opt
1459    if lopt == "-a":
1460      opt_address = ropt
1461      logline = "opt_address set to " + opt_address
1462      logger.logit(logline)
1463    elif lopt == "-D":
1464      opt_checkDNS = 1
1465      logline = "requested to check the ip against DNS"
1466      logger.logit(logline)
1467    elif lopt == "-i":
1468      opt_interface = ropt
1469      logline = "opt_interface set to " + opt_interface
1470      logger.logit(logline)
1471    elif lopt == "-f":
1472      opt_force = 1
1473      logline = "opt_force set "
1474      logger.logit(logline)
1475    elif lopt == "-j":
1476      opt_no_https = 1
1477      logline = "opt_no_https set "
1478      logger.logit(logline)
1479    elif lopt == "-w":
1480      if ropt != "":
1481        opt_wildcard = "ropt"
1482      else:
1483        opt_wildcard = "ON"
1484      logline = "opt_wildcard set to " + opt_wildcard
1485      logger.logit(logline)
1486    elif lopt == "-s":
1487      opt_static = 1
1488      logline = "opt_static set "
1489      logger.logit(logline)
1490    elif lopt == "-c":
1491      opt_custom = 1
1492      logline = "opt_custom set "
1493      logger.logit(logline)
1494    elif lopt == "-b":
1495      if ropt != "":
1496        opt_backupmx = "ropt"
1497      else:
1498        opt_backupmx = "YES"
1499      logline = "opt_backupmx set to " + opt_backupmx
1500      logger.logit(logline)
1501    elif lopt == "-p":
1502      opt_proxy = 1
1503      logline = "opt_proxy set "
1504      logger.logit(logline)
1505    elif lopt == "-m":
1506      opt_mxhost = ropt
1507      logline = "opt_mxhost set to " + opt_mxhost
1508      logger.logit(logline)
1509    elif lopt == "-r":
1510      opt_router = ropt
1511      logline = "opt_router set to " + opt_router
1512      logger.logit(logline)
1513    elif lopt == "-g":
1514      opt_guess = 1
1515      logline = "opt_guess set "
1516      logger.logit(logline)
1517    elif lopt == "-t":
1518      opt_testrun = 1
1519      logline = "opt_testrun set "
1520      logger.logit(logline)
1521    elif lopt == "--makedat":
1522      opt_makedat = 1
1523      logline = "opt_makedat set "
1524      logger.logit(logline)
1525    elif lopt == "-q":
1526      opt_quiet = 1
1527      logline = "opt_quiet set "
1528      logger.logit(logline)
1529    elif lopt == "-o":
1530      opt_offline = 1
1531      logline = "opt_offline set "
1532      logger.logit(logline)
1533    elif lopt == "-e":
1534      opt_execute = ropt
1535      logline = "opt_execute set to " + opt_execute
1536      logger.logit(logline)
1537    elif lopt == "-U":
1538      opt_natuser = ropt
1539      logline = "opt_natuser set to " + opt_natuser
1540      logger.logit(logline)
1541
1542      Linksys_user = opt_natuser
1543      Macsense_user = opt_natuser
1544      Netgear_user = opt_natuser
1545      Netgear3114_user = opt_natuser
1546      Draytek_user = opt_natuser
1547      Netopia_user = opt_natuser
1548      Hawking_user = opt_natuser
1549      Watchguard_user = opt_natuser
1550      Veicon_user = opt_natuser
1551    elif lopt == "--Belkin_f5d7230":
1552      opt_Belkin_f5d7230_router = 1
1553      logline = "opt_Belkin_f5d7230_router set "
1554      logger.logit(logline)
1555      Cayman_user = opt_natuser
1556      Gnet_user = opt_natuser
1557      Barricade_user = opt_natuser
1558      DI804_user = opt_natuser
1559      Alcatel_user = opt_natuser
1560
1561    elif lopt == "--VT1000v":
1562      opt_MotorolaVT1000v_router = 1
1563      logline = "opt_MotorolaVT1000v_router set "
1564      logger.logit(logline)
1565    elif lopt == "-M":
1566      if opt_pfile == 1:
1567        opt_Macsense_password = read_pfile(ropt, logger)
1568        logger.logit("opt_Macsense_password from file")
1569      else:
1570        opt_Macsense_password = ropt
1571        logger.logit("opt_Macsense_password from command line")
1572      logger.logit("*" * len(opt_Macsense_password))
1573    elif lopt == "-L":
1574      opt_Linksys_router = 1
1575      if opt_pfile == 1:
1576        opt_Linksys_password = read_pfile(ropt, logger)
1577        logger.logit("opt_Linksys_password from file")
1578      else:
1579        opt_Linksys_password = ropt
1580        logger.logit("opt_Linksys_password from command line")
1581      logger.logit("*" * len(opt_Linksys_password))
1582    elif lopt == "-N":
1583      if opt_pfile == 1:
1584        opt_Netgear_password = read_pfile(ropt, logger)
1585        logger.logit("opt_Netgear_password from file")
1586      else:
1587        opt_Netgear_password = ropt
1588        logger.logit("opt_Netgear_password from command line")
1589      logger.logit("*" * len(opt_Netgear_password))
1590    elif lopt == "-R":
1591      if opt_pfile == 1:
1592        opt_Netgear3114_password = read_pfile(ropt, logger)
1593        logger.logit("opt_Netgear3114_password from file")
1594      else:
1595        opt_Netgear3114_password = ropt
1596        logger.logit("opt_Netgear3114_password from command line")
1597      logger.logit("*" * len(opt_Netgear3114_password))
1598    elif lopt == "-D":
1599      if opt_pfile == 1:
1600        opt_Draytek_password = read_pfile(ropt, logger)
1601        logger.logit("opt_Draytek_password from file")
1602      else:
1603        opt_Draytek_password = ropt
1604        logger.logit("opt_Draytek_password from command line")
1605      logger.logit("*" * len(opt_Draytek_password))
1606    elif lopt == "-O":
1607      if opt_pfile == 1:
1608        opt_Netopia_password = read_pfile(ropt, logger)
1609        logger.logit("opt_Netopia_password from file")
1610      else:
1611        opt_Netopia_password = ropt
1612        logger.logit("opt_Netopia_password from command line")
1613      logger.logit("*" * len(opt_Netopia_password))
1614    elif lopt == "-C":
1615      if opt_pfile == 1:
1616        opt_Cisco_password = read_pfile(ropt, logger)
1617        logger.logit("opt_Cisco_password from file")
1618      else:
1619        opt_Cisco_password = ropt
1620        logger.logit("opt_Cisco_password from command line")
1621      logger.logit("*" * len(opt_Cisco_password))
1622    elif lopt == "-S":
1623      opt_SMC_router = 1
1624      logline = "opt_SMC_router set "
1625      logger.logit(logline)
1626    elif lopt == "-G":
1627      opt_Ugate_router = 1
1628      logline = "opt_Ugate_router set "
1629      logger.logit(logline)
1630    elif lopt == "-E":
1631      opt_Eicon_router = 1
1632      logline = "opt_Eicon_router set "
1633      logger.logit(logline)
1634    elif lopt == "-V":
1635      if opt_pfile == 1:
1636        opt_Veicon_password = read_pfile(ropt, logger)
1637        logger.logit("opt_Veicon_password from file")
1638      else:
1639        opt_Veicon_password = ropt
1640        logger.logit("opt_Veicon_password from command line")
1641      logger.logit("*" * len(opt_Veicon_password))
1642    elif lopt == "-B":
1643      if opt_pfile == 1:
1644        opt_Barricade_password = read_pfile(ropt, logger)
1645        logger.logit("opt_Barricade_password from file")
1646      else:
1647        opt_Barricade_password = ropt
1648        logger.logit("opt_Barricade_password from command line")
1649      logger.logit("*" * len(opt_Barricade_password))
1650    elif lopt == "--VWBR":
1651      opt_7004VWBR = 1
1652    elif lopt == "--WBR":
1653      opt_WBR = ropt
1654    elif lopt == "-Q":
1655      Qopts = string.split(ropt, ",")
1656      if len(Qopts) != 2:
1657        logline = "Bad -Q option: " + ropt
1658        logger.logexit(logline)
1659        sys.exit(-1)
1660      logger.logit(logline)
1661      if opt_pfile == 1:
1662        opt_II_password = read_pfile(Qopts[0], logger)
1663        logger.logit("opt_II_password from file")
1664      else:
1665        opt_II_password = Qopts[0]
1666        logger.logit("opt_II_password from command line")
1667      logger.logit("*" * len(opt_II_password))
1668
1669      opt_II_interface = Qopts[1]
1670      logline = "opt_II_interface = " + opt_II_interface
1671    elif lopt == "-X":
1672      opt_Nexland_router = 1
1673      logline = "opt_Nexland_router set "
1674      logger.logit(logline)
1675    elif lopt == "-P":
1676      opt_Pro800Turbo_router = 1
1677      ropt_save = ropt
1678      cindex = string.find(ropt,",")
1679      if cindex == -1:
1680        ropt_port = ropt
1681        Pro800Turbo_password = None
1682      else:
1683        ropt_port = ropt[:cindex]
1684        Pro800Turbo_password = ropt[cindex+1:]
1685
1686      if ropt_port == 'any':
1687        Pro800Turbo_port = 'any'
1688      else:
1689        if ropt_port[0] == '-':
1690          Pro800Turbo_port = 'force'
1691          ropt_port = ropt_port[1:]
1692        else:
1693          Pro800Turbo_port = 'prefer'
1694        try:
1695          ropt_int = int(ropt_port)
1696          if ropt_int < -1 or ropt_int > 1:
1697            raise ValueError("invalid port value %s" % (ropt_save))
1698          Pro800Turbo_port_number = ropt_int
1699        except:
1700          logline = "Bad -P option %s" % (ropt_save)
1701          logger.logexit(logline)
1702          sys.exit(-1)
1703      logline = "opt_Pro800Turbo port %s %d" % (Pro800Turbo_port,
1704                                                Pro800Turbo_port_number)
1705      logger.logit(logline)
1706    elif lopt == "--forward":
1707      opt_forward_ports = string.split(ropt, ",")
1708      if len(opt_forward_ports)==0:
1709        logger.logexit("Not ports specified to forward")
1710        sys.exit(-1)
1711      for opt_forward_port in opt_forward_ports:
1712        opt_forward_portprotocol=string.split(opt_forward_port,"/")
1713        if len(opt_forward_portprotocol)==1:
1714          opt_forward_portprotocol=opt_forward_portprotocol+["tcp"]
1715        if len(opt_forward_portprotocol)!=2:
1716          logline = "Bad -forward option %s" % opt_forward_port
1717          logger.logexit(logline)
1718          sys.exit(-1)
1719        opt_forward=opt_forward+[ opt_forward_portprotocol ]
1720      logline = "opt_forward %s" % str(opt_forward)
1721      logger.logit(logline)
1722    elif lopt == "-I":
1723      if opt_pfile == 1:
1724        opt_ISDNCisco_password = read_pfile(ropt, logger)
1725        logger.logit("opt_ISDNCisco_password from file")
1726      else:
1727        opt_ISDNCisco_password = ropt
1728        logger.logit("opt_ISDNCisco_password from command line")
1729      logger.logit("*" * len(opt_ISDNCisco_password))
1730    elif lopt == "-H":
1731      if opt_pfile == 1:
1732        opt_Hawking_password = read_pfile(ropt, logger)
1733        logger.logit("opt_Hawking_password from file")
1734      else:
1735        opt_Hawking_password = ropt
1736        logger.logit("opt_Hawking_password from command line")
1737      logger.logit("*" * len(opt_Hawking_password))
1738    elif lopt == "-J":
1739      if opt_pfile == 1:
1740        opt_Zyxel_ME_password = read_pfile(ropt, logger)
1741        logger.logit("opt_Zyxel_ME_password from file")
1742      else:
1743        opt_Zyxel_ME_password = ropt
1744        logger.logit("opt_Zyxel_ME_password from command line")
1745      logger.logit("*" * len(opt_Zyxel_ME_password))
1746    elif lopt == "-Z":
1747      if opt_pfile == 1:
1748        opt_Zyxel_password = read_pfile(ropt, logger)
1749        logger.logit("opt_Zyxel_password from file")
1750      else:
1751        opt_Zyxel_password = ropt
1752        logger.logit("opt_Zyxel_password from command line")
1753      logger.logit("*" * len(opt_Zyxel_password))
1754    elif lopt == "-2":
1755      if opt_pfile == 1:
1756        opt_Siemens2620_password = read_pfile(ropt, logger)
1757        logger.logit("opt_Siemens2620_password from file")
1758      else:
1759        opt_Siemens2620_password = ropt
1760        logger.logit("opt_Siemens2620_password from command line")
1761      logger.logit("*" * len(opt_Siemens2620_password))
1762    elif lopt == "-3":
1763      if opt_pfile == 1:
1764        opt_Netgear338_password = read_pfile(ropt, logger)
1765        logger.logit("opt_Netgear338_password from file")
1766      else:
1767        opt_Netgear338_password = ropt
1768        logger.logit("opt_Netgear338_password from command line")
1769      logger.logit("*" * len(opt_Netgear338_password))
1770    elif lopt == "-4":
1771      if opt_pfile == 1:
1772        opt_Gnet_password = read_pfile(ropt, logger)
1773        logger.logit("opt_Gnet_password from file")
1774      else:
1775        opt_Gnet_password = ropt
1776        logger.logit("opt_Gnet_password from command line")
1777      logger.logit("*" * len(opt_Gnet_password))
1778    elif lopt == "-5":
1779      opt_DInop_router = 1
1780    elif lopt == "-6":
1781      if opt_pfile == 1:
1782        opt_DI704_password = read_pfile(ropt, logger)
1783        logger.logit("opt_DI704_password from file")
1784      else:
1785        opt_DI704_password = ropt
1786        logger.logit("opt_DI704_password from command line")
1787      logger.logit("*" * len(opt_DI704_password))
1788    elif lopt == "-7":
1789      if opt_pfile == 1:
1790        opt_DI701_password = read_pfile(ropt, logger)
1791        logger.logit("opt_DI701_password from file")
1792      else:
1793        opt_DI701_password = ropt
1794        logger.logit("opt_DI701_password from command line")
1795      logger.logit("*" * len(opt_DI701_password))
1796    elif lopt == "-8":
1797      if opt_pfile == 1:
1798        opt_DI804_password = read_pfile(ropt, logger)
1799        logger.logit("opt_DI804_password from file")
1800      else:
1801        opt_DI804_password = ropt
1802        logger.logit("opt_DI804_password from command line")
1803      logger.logit("*" * len(opt_DI804_password))
1804    elif lopt == "-9":
1805      if opt_pfile == 1:
1806        opt_DI713P_password = read_pfile(ropt, logger)
1807        logger.logit("opt_DI713P_password from file")
1808      else:
1809        opt_DI713P_password = ropt
1810        logger.logit("opt_DI713P_password from command line")
1811      logger.logit("*" * len(opt_DI713P_password))
1812    elif lopt == "-1":
1813      if opt_pfile == 1:
1814        opt_DSL504_password = read_pfile(ropt, logger)
1815        logger.logit("opt_DSL504_password from file")
1816      else:
1817        opt_DSL504_password = ropt
1818        logger.logit("opt_DSL504_password from command line")
1819      logger.logit("*" * len(opt_DSL504_password))
1820    elif lopt == "-W":
1821      if opt_pfile == 1:
1822        opt_Watchguard_password = read_pfile(ropt, logger)
1823        logger.logit("opt_Watchguard_password from file")
1824      else:
1825        opt_Watchguard_password = ropt
1826        logger.logit("opt_Watchguard_password from command line")
1827      logger.logit("*" * len(opt_Watchguard_password))
1828    elif lopt == "-K":
1829      if opt_pfile == 1:
1830        opt_Compex_password = read_pfile(ropt, logger)
1831        logger.logit("opt_Compex_password from file")
1832      else:
1833        opt_Compex_password = ropt
1834        logger.logit("opt_Compex_password from command line")
1835      logger.logit("*" * len(opt_Compex_password))
1836    elif lopt == "-A":
1837      opt_after_syslog = ropt
1838      logline = "opt_after_syslog = " + ropt
1839      logger.logit(logline)
1840    elif lopt == "-F":
1841      opt_firewall_log = ropt
1842      logline = "opt_firewall_log = " + ropt
1843      logger.logit(logline)
1844    elif lopt == "-Y":
1845      if opt_pfile == 1:
1846        opt_Cayman_password = read_pfile(ropt, logger)
1847        logger.logit("opt_Cayman_password from file")
1848      else:
1849        opt_Cayman_password = ropt
1850        logger.logit("opt_Cayman_password from command line")
1851      logger.logit("*" * len(opt_Cayman_password))
1852    elif lopt == "-T":
1853      if opt_pfile == 1:
1854        opt_AlcatelSTP_password = read_pfile(ropt, logger)
1855        logger.logit("opt_AlcatelSTP_password from file")
1856      else:
1857        opt_AlcatelSTP_password = ropt
1858        logger.logit("opt_AlcatelSTP_password from command line")
1859      logger.logit("*" * len(opt_AlcatelSTP_password))
1860    elif lopt == "-n":
1861      routerIP = ropt
1862      logline = "opt_router_ip = " + ropt
1863      logger.logit(logline)
1864
1865    elif lopt == "--snmp":
1866
1867      snmpopts = string.split(ropt, ",")
1868      if len(snmpopts) != 3:
1869        logline = "Bad --snmp option: " + ropt
1870        logger.logexit(logline)
1871        sys.exit(-1)
1872
1873      #
1874      # check snmp agent is an IP address
1875      #
1876      opt_snmp_agent = snmpopts[0]
1877      if string.count(opt_snmp, ".") != 3:
1878        logline = opt_snmp_agent + " bad snmp agent, IP address required"
1879        logger.logexit(logline)
1880        sys.exit(-1)
1881      opt_snmp_agent_prefix = string.join(string.split(opt_snmp_agent, ".", 3)[:2], ".")
1882
1883      #
1884      # community can be anything
1885      #
1886      opt_snmp_community = snmpopts[1]
1887
1888      #
1889      # check the objectid is numeric
1890      #
1891      opt_snmp_objectid = snmpopts[2]
1892      #objid_s = string.split(opt_snmp_objectid, '.')
1893      #objid_s = filter(lambda x: len(x), objid_s)
1894      #try:
1895      #  objid_n = map(lambda x: string.atol(x), objid_s)
1896      #except:
1897      #  logline = opt_snmp_objectid + " bad snmp objectid, numeric id required"
1898      #  logger.logexit(logline)
1899      #  sys.exit(-1)
1900
1901      logger.logit("opt_snmp_agent = " + opt_snmp_agent)
1902      logger.logit("opt_snmp_agent_prefix = " + opt_snmp_agent_prefix)
1903      logger.logit("opt_snmp_community = " + opt_snmp_community)
1904      logger.logit("opt_snmp_objectid = " + opt_snmp_objectid)
1905
1906    elif lopt == "--snmpget":
1907
1908      try:
1909        (opt_snmp_agent, opt_snmp_community, opt_snmp_objectid) = string.split(ropt, ',')
1910      except:
1911        logger.logexit("Bad --snmpget option: " + ropt)
1912        sys.exit(-1)
1913
1914      # Check for a half reasonable numeric object id
1915      if re.search("^\.([0-9]+\.)+[0-9]+$",opt_snmp_objectid) == None:
1916        logger.logexit("Bad Object ID: " + opt_snmp_objectid)
1917        sys.exit(-1)
1918
1919      logger.logit("opt_snmp_agent = " + opt_snmp_agent)
1920      logger.logit("opt_snmp_community = " + opt_snmp_community)
1921      logger.logit("opt_snmp_objectid = " + opt_snmp_objectid)
1922
1923    elif lopt == "--Netvanta":
1924      opt_Netvanta_password = ropt
1925      logger.logit("opt_Netvanta_password from command line")
1926      logger.logit("*" * len(opt_Netvanta_password))
1927
1928    elif lopt == "--WTG624":
1929      if opt_pfile == 1:
1930        opt_NetgearWTG624_password = read_pfile(ropt, logger)
1931        logger.logit("opt_NetgearWTG624_password from file")
1932      else:
1933        opt_NetgearWTG624_password = ropt
1934        logger.logit("opt_NetgearWTG624_password from command line")
1935      logger.logit("*" * len(opt_NetgearWTG624_password))
1936
1937  #
1938  # handle the username, password, hostnames part
1939  #
1940  if opt_acctfile:
1941    args = read_acctfile(opt_acctfile, logger)
1942
1943  opt_username = args[0]
1944  logline = "opt_username = " + opt_username
1945  logger.logit(logline)
1946
1947  opt_password = args[1]
1948  logger.logit("opt_password = " + "*" * len(opt_password))
1949
1950  opt_hostnames = args[2]
1951  logline = "opt_hostnames = " + opt_hostnames
1952  logger.logit(logline)
1953  hostnames = string.split(opt_hostnames, ",")
1954
1955  #
1956  # taint check, make sure each hostname is a dotted fqdn
1957  #
1958  for host in hostnames:
1959    if not "." in host:
1960      logline = "Bad hostname: " + host
1961      logger.logexit(logline)
1962      sys.exit(-1)
1963
1964  #
1965  # check if hostname is a custom domain
1966  #
1967  domains = [ \
1968"ath.cx",
1969"blogdns.com",
1970"blogdns.net",
1971"blogdns.org",
1972"blogsite.org",
1973"boldlygoingnowhere.org",
1974"dnsalias.com",
1975"dnsalias.net",
1976"dnsalias.org",
1977"dnsdojo.com",
1978"dnsdojo.net",
1979"dnsdojo.org",
1980"doesntexist.com",
1981"doesntexist.org",
1982"dontexist.com",
1983"dontexist.net",
1984"dontexist.org",
1985"dvrdns.org",
1986"dyn-o-saur.com",
1987"dynalias.com",
1988"dynalias.net",
1989"dynalias.org",
1990"dyndns.biz",
1991"dyndns.info",
1992"dyndns.org",
1993"dyndns.tv",
1994"dyndns.ws",
1995"endofinternet.net",
1996"endofinternet.org",
1997"endoftheinternet.org",
1998"ftpaccess.cc",
1999"game-host.org",
2000"game-server.cc",
2001"getmyip.com",
2002"go.dyndns.org",
2003"gotdns.com",
2004"gotdns.org",
2005"ham-radio-op.net",
2006"hobby-site.com",
2007"hobby-site.org",
2008"home.dyndns.org",
2009"homedns.org",
2010"homeftp.net",
2011"homeftp.org",
2012"homeip.net",
2013"homelinux.com",
2014"homelinux.net",
2015"homelinux.org",
2016"homeunix.com",
2017"homeunix.net",
2018"homeunix.org",
2019"is-a-chef.com",
2020"is-a-chef.net",
2021"is-a-chef.org",
2022"is-a-geek.com",
2023"is-a-geek.net",
2024"is-a-geek.org",
2025"is.dreaming.org",
2026"isa-geek.com",
2027"isa-geek.net",
2028"isa-geek.org",
2029"kicks-ass.net",
2030"kicks-ass.org",
2031"merseine.nu",
2032"mine.nu",
2033"mypets.ws",
2034"myphotos.cc",
2035"office-on-the.net",
2036"podzone.net",
2037"podzone.org",
2038"scrapper-site.net",
2039"scrapping.cc",
2040"selfip.biz",
2041"selfip.com",
2042"selfip.info",
2043"selfip.net",
2044"selfip.org",
2045"servebbs.com",
2046"servebbs.net",
2047"servebbs.org",
2048"serveftp.net",
2049"serveftp.org",
2050"servegame.org",
2051"shacknet.nu",
2052"thruhere.net",
2053"webhop.biz",
2054"webhop.info",
2055"webhop.net",
2056"webhop.org",
2057  ]
2058
2059  # add recursivedns.com to the domains
2060  domains = domains + ["recursivedns.com"]
2061
2062  if not opt_custom:
2063    for host in hostnames:
2064      h = string.lower(host)
2065      known = 0
2066      for dom in domains:
2067        if dom == h[-len(dom):]:
2068          known = 1
2069          break
2070      if not known:
2071        logline = "WARNING Unknown domain: " + host
2072        logger.logexit(logline)
2073        logger.logexit("If the domain is listed at http://www.dyndns.org/services/dyndns/domains.html")
2074        logger.logexit("then email kal@users.sourceforge.net to add the domain.")
2075        logger.logexit("Otherwise, you should be using -c for custom domains.")
2076
2077  #
2078  # taint check the mx host
2079  #
2080  if opt_mxhost:
2081    if string.find(opt_mxhost, "NOCHG") != -1:
2082      opt_mxhost = "NOCHG"
2083    elif not "." in opt_mxhost:
2084      logline = "Bad mxhost: " + opt_mxhost
2085      logger.logexit(logline)
2086      sys.exit(-1)
2087
2088  #
2089  # log the pwd
2090  #
2091  if os.environ.has_key("PWD"):
2092    logger.logit("PWD = " + os.environ["PWD"])
2093
2094  #
2095  # create the full path names
2096  #
2097  datfile = Datfile("ipcheck.dat")
2098  if opt_directory:
2099    datfile.setFilename(opt_directory + datfile.getFilename())
2100    logger.logit("Datfile = " + datfile.getFilename())
2101  errfile = Errorfile(logger, "ipcheck.err")
2102  if opt_directory:
2103    errfile.setFilename(opt_directory + errfile.getFilename())
2104    logger.logit("Errfile = " + errfile.getFilename())
2105  Waitfile = "ipcheck.wait"
2106  if opt_directory:
2107    Waitfile = opt_directory + Waitfile
2108    logger.logit("Waitfile = " + Waitfile)
2109  Htmlfile = "ipcheck.html"
2110  if opt_directory:
2111    Htmlfile = opt_directory + Htmlfile
2112    logger.logit("Htmlfile = " + Htmlfile)
2113  Tempfile = "ipcheck.tmp"
2114  if opt_directory:
2115    Tempfile = opt_directory + Tempfile
2116    logger.logit("Tempfile = " + Tempfile)
2117
2118
2119  #
2120  # determine the local machine's ip
2121  #
2122  localip = ""
2123  iphost = ""
2124  if opt_address:
2125    logger.logit("Manually setting localip with -a")
2126    localip = opt_address
2127  elif opt_after_syslog:
2128    logger.logit("Scanning /var/log/messages for last occurance of " + opt_after_syslog)
2129    fp = open("/var/log/messages", "r")
2130    ipdata = fp.read()
2131    fp.close()
2132    p1 = string.rfind(ipdata, opt_after_syslog)
2133    if p1 != -1:
2134      ipmatch = Addressgrep.search(ipdata[p1:])
2135      if ipmatch != None:
2136        localip = ipmatch.group()
2137        logger.logit("IP matched: " + localip)
2138    fp.close()
2139
2140  elif opt_firewall_log:
2141    logger.logit("Scanning " + opt_firewall_log)
2142    lines = []
2143    fp = open(opt_firewall_log, "r")
2144    while 1:
2145      l = fp.readline()
2146      if not l:
2147        break
2148      lines.append(l)
2149    fp.close()
2150    lcnt = len(lines)
2151
2152    localip = ""
2153    for x in xrange(lcnt-1, 0, -1):
2154      l = lines[x]
2155      if l[:3] == "NAT":
2156        ipmatch = Addressgrep.findall(l)
2157        if len(l) == 2:
2158          localip = check_public_ip(l[1])
2159        else:
2160          localip = check_public_ip(l[0])
2161      if localip:
2162        break
2163
2164    logger.logit("IP matched " + localip)
2165
2166  elif opt_snmp_agent_prefix:
2167    logger.logit("Trying snmp localip detection")
2168
2169    # Create an instance of snmptable class
2170    instance = snmptable (opt_snmp_agent, opt_snmp_community)
2171
2172    # Run snmptable against passed Object ID's
2173    retval = []
2174    try:
2175      retval = instance.run([opt_snmp_objectid])
2176    except:
2177      logline = "Snmp session failed."
2178      logger.logexit(logline)
2179      logger.logexit("Exception: " + `sys.exc_info()[0]`)
2180      sys.exit(-1)
2181
2182    agentlen = len(opt_snmp_agent_prefix)
2183    objectlen = len(opt_snmp_objectid) + 1
2184    for (objid, value) in retval:
2185      logger.logit(objid + ' ---> ' + str(value))
2186      objval = objid[objectlen:]
2187      if objval[:agentlen] != opt_snmp_agent_prefix:
2188        localip = objval
2189        logger.logit("IP matched: " + localip)
2190        # match the last one so all options are printed in the log
2191        #break
2192
2193  elif opt_snmp_agent:
2194
2195    mysnmptable = snmptable(opt_snmp_agent, opt_snmp_community)
2196
2197    try:
2198      value = mysnmptable.getrow(opt_snmp_objectid)
2199    except:
2200      logger.logexit("Snmp session failed.")
2201      logger.logexit("Exception: " + `sys.exc_info()[0]`)
2202      sys.exit(-1)
2203
2204    logger.logit(opt_snmp_objectid + ' ---> ' + str(value))
2205    localip = value
2206    logger.logit("IP from snmpget is: " + localip)
2207
2208
2209  elif opt_Cayman_password:
2210    #
2211    # Cayman DSL 3220H router ip detection
2212    #
2213    #   This code was written for and tested on Device Firmware
2214    #   GatorSurf version 5.6.2 (build R0)
2215    #   with PPP / NAT
2216
2217    #
2218    # determine the router host address
2219    #
2220    if routerIP:
2221      logger.logit("Cayman_host set explicitly.")
2222      iphost = routerIP
2223    else:
2224      iphost = DefaultRoute(logger, Tempfile)
2225
2226    if iphost:
2227      logline = "Trying router at " + iphost
2228      logger.logit(logline)
2229    else:
2230      logger.logit("No router ip detected.  Assuming 192.168.1.254")
2231      iphost = "192.168.1.254"
2232
2233    # connect to the router's admin console interface
2234    try:
2235      logger.logit("Trying Cayman DSL 3220H")
2236      tn = telnetlib.Telnet(iphost)
2237      logger.logit("Creating telnetlib obj done")
2238      tn.read_until("ogin:")
2239      logger.logit("Login prompt found")
2240      tn.write(Cayman_user + "\r\n")
2241      logger.logit("Cayman_user sent")
2242      tn.read_until("assword:")
2243      logger.logit("Password prompt found")
2244      tn.write(opt_Cayman_password + "\r\n")
2245      logger.logit("opt_Cayman_password sent")
2246      tn.read_until(">")
2247      tn.write("show ip interface\r\n")
2248      logger.logit("show ip interface command sent")
2249      ipdata = tn.read_until(">", 2000)
2250      tn.write("exit\r\n")
2251      logger.logit("exit command sent")
2252    except:
2253      logline = "No address found on router at " + iphost
2254      logger.logexit(logline)
2255      sys.exit(-1)
2256
2257    # create an output file of the response
2258    filename = "cayman.out"
2259    if opt_directory:
2260      filename = opt_directory + filename
2261    fp = open(filename, "w")
2262    fp.write(ipdata)
2263    fp.close()
2264    logger.logit("cayman.out file created")
2265
2266    # look for the WAN device in ipdata
2267    p1 = string.rfind(ipdata, "PPP")
2268    if p1 != -1:
2269      ipmatch = Addressgrep.search(ipdata, p1+1)
2270      if ipmatch != None:
2271        localip = ipmatch.group()
2272        logger.logit("IP matched: " + localip)
2273
2274  elif opt_Netgear338_password:
2275    #
2276    # Netgear RT338 ISDN router
2277    #
2278    # determine the router host address
2279    #
2280    if routerIP:
2281      logger.logit("Netgear338_host set explicitly.")
2282      iphost = routerIP
2283    else:
2284      iphost = DefaultRoute(logger, Tempfile)
2285
2286    # connect to the router's admin webpage
2287    try:
2288      logger.logit("Trying Netgear RT338")
2289      tn = telnetlib.Telnet(iphost)
2290      logger.logit("Creating telnetlib obj done")
2291      tn.read_until("assword:")
2292      logger.logit("Password prompt found")
2293      tn.write(opt_Netgear338_password + "\r\n")
2294      logger.logit("opt_Netgear338_password sent")
2295      tn.read_until("Number:")
2296      tn.write("24\r\n")
2297      logger.logit("menu number 24 sent")
2298      tn.read_until("Number:")
2299      tn.write("8\r\n")
2300      logger.logit("menu number 8 sent")
2301      ip1 = tn.read_until("router>", 2000)
2302      tn.write("ip ifconfig\r\n")
2303      logger.logit("ip ifconfig sent")
2304      ipdata = tn.read_until("router>", 2000)
2305    except:
2306      logline = "No address found on router at " + iphost
2307      logger.logexit(logline)
2308      sys.exit(-1)
2309
2310    # create an output file of the response
2311    filename = "netgear338.out"
2312    if opt_directory:
2313      filename = opt_directory + filename
2314    fp = open(filename, "w")
2315    fp.write(ipdata)
2316    fp.close()
2317    logger.logit("netgear338.out file created")
2318
2319    # look for the last wanif0 device in the log
2320    p1 = string.rfind(ipdata, "wanif0")
2321    if p1 != -1:
2322      ipmatch = Addressgrep.search(ipdata, p1)
2323      if ipmatch != None:
2324        localip = ipmatch.group()
2325        logger.logit("IP matched: " + localip)
2326    else:
2327      p1 = string.rfind(ipdata, "enif1")
2328      if p1 != -1:
2329        ipmatch = Addressgrep.search(ipdata, p1)
2330        if ipmatch != None:
2331          localip = ipmatch.group()
2332          logger.logit("IP matched: " + localip)
2333
2334
2335
2336  elif opt_Gnet_password:
2337    #
2338    # Gnet ADSL Router
2339    #
2340    #   This code was written for and tested on
2341    #   Gnet model BB0040 ADSL Router version 2.A3.2.03 (Build 011207.A)
2342    #   running ADSL/PPPOE/NAT in the device
2343    #
2344    # determine the router host address
2345    #
2346    if routerIP:
2347      logger.logit("Gnet_host set explicitly.")
2348      iphost = routerIP
2349    else:
2350      iphost = DefaultRoute(logger, Tempfile)
2351
2352    if iphost:
2353      logline = "Trying router at " + iphost
2354      logger.logit(logline)
2355    else:
2356      logger.logit("No router ip detected.  Assuming 192.168.1.254")
2357      iphost = "192.168.1.254"
2358
2359    # connect to the router's admin console interface
2360    try:
2361      logger.logit("Trying Gnet model BB0040 ADSL router")
2362      tn = telnetlib.Telnet(iphost)
2363      logger.logit("Creating telnetlib obj done")
2364      tn.read_until("assword:")
2365      logger.logit("Password prompt found")
2366      tn.write(opt_Gnet_password + "\r\n")
2367      logger.logit("opt_Gnet_password sent")
2368      tn.read_until(">")
2369      tn.write("ip subnet\r\n")
2370      logger.logit("ip subnet command sent")
2371      ipdata = tn.read_until(">", 2000)
2372      tn.write("@close\r\n")
2373      logger.logit("@close command sent")
2374    except:
2375      logline = "No address found on router at " + iphost
2376      logger.logexit(logline)
2377      sys.exit(-1)
2378
2379    # create an output file of the response
2380    filename = "gnet.out"
2381    if opt_directory:
2382      filename = opt_directory + filename
2383    fp = open(filename, "w")
2384    fp.write(ipdata)
2385    fp.close()
2386    logger.logit("gnet.out file created")
2387
2388    # look for the WAN device in ipdata
2389    p1 = string.rfind(ipdata, "subnet ppp_device")
2390    if p1 != -1:
2391      ipmatch = Addressgrep.search(ipdata, p1+1)
2392      if ipmatch != None:
2393        localip = ipmatch.group()
2394        logger.logit("IP matched: " + localip)
2395
2396
2397  elif opt_Compex_password:
2398    #
2399    # Compex NetPassage 15 router ip detection
2400    #
2401    #   This code was written for and tested on Device Firmware
2402    #   version "2.67 Build 1005, Mar 5 2001"
2403
2404    #
2405    # determine the router host address
2406    #
2407    if routerIP:
2408      logger.logit("Compex_host set explicitly.")
2409      iphost = routerIP
2410    else:
2411      iphost = DefaultRoute(logger, Tempfile)
2412
2413    if iphost:
2414      logline = "Trying router at " + iphost
2415      logger.logit(logline)
2416    else:
2417      logger.logit("No router ip detected.  Assuming 192.168.168.1")
2418      iphost = "192.168.168.1"
2419
2420    # connect to the router's admin console interface
2421    try:
2422      logger.logit("Trying Compex NetPassage 15")
2423      tn = telnetlib.Telnet(iphost)
2424      logger.logit("Creating telnetlib obj done")
2425      tn.read_until("assword:")
2426      logger.logit("Password prompt found")
2427      tn.write(opt_Compex_password + "\r\n")
2428      logger.logit("opt_Compex_password sent")
2429      tn.read_until("ommand>")
2430      tn.write("show ip\r\n")
2431      logger.logit("show ip command sent")
2432      ipdata = tn.read_until("ommand>", 2000)
2433      tn.write("exit\r\n")
2434      logger.logit("exit command sent")
2435    except:
2436      logline = "No address found on router at " + iphost
2437      logger.logexit(logline)
2438      sys.exit(-1)
2439
2440    # create an output file of the response
2441    filename = "compex.out"
2442    if opt_directory:
2443      filename = opt_directory + filename
2444    fp = open(filename, "w")
2445    fp.write(ipdata)
2446    fp.close()
2447    logger.logit("compex.out file created")
2448
2449    # look for the WAN device in ipdata
2450    p1 = string.rfind(ipdata, "WAN")
2451    if p1 != -1:
2452      ipmatch = Addressgrep.search(ipdata, p1)
2453      if ipmatch != None:
2454        localip = ipmatch.group()
2455        logger.logit("IP matched: " + localip)
2456
2457  elif opt_Zyxel_ME_password:
2458    #
2459    # ZyXEL Prestige 642ME router ip detection
2460    #
2461
2462    #
2463    # determine the router host address
2464    #
2465    if routerIP:
2466      logger.logit("Zyxel_ME_host set explicitly.")
2467      iphost = routerIP
2468    else:
2469      iphost = DefaultRoute(logger, Tempfile)
2470
2471    if iphost:
2472      logline = "Trying router at " + iphost
2473      logger.logit(logline)
2474    else:
2475      logger.logit("No router ip detected.  Assuming 192.168.1.1")
2476      iphost = "192.168.1.1"
2477
2478    # connect to the router's admin webpage
2479    try:
2480      logger.logit("Trying ZyXEL Prestige 642ME")
2481      tn = telnetlib.Telnet(iphost)
2482      logger.logit("Creating telnetlib obj done")
2483      tn.read_until("assword:")
2484      logger.logit("Password prompt found")
2485      tn.write(opt_Zyxel_ME_password + "\r\n")
2486      logger.logit("opt_Zyxel_ME_password sent")
2487      tn.read_until(">")
2488      tn.write("ip ifconfig\r\n")
2489      logger.logit("ip ifconfig sent")
2490      ipdata = tn.read_until(">", 2000)
2491      logger.logit("ipdata read")
2492      tn.write("exit\r\n")
2493      logger.logit("exit sent")
2494    except:
2495      logline = "No address found on router at " + iphost
2496      logger.logexit(logline)
2497      sys.exit(-1)
2498
2499    # create an output file of the response
2500    filename = "zyxelme.out"
2501    if opt_directory:
2502      filename = opt_directory + filename
2503    fp = open(filename, "w")
2504    fp.write(ipdata)
2505    fp.close()
2506    logger.logit("zyxelme.out file created")
2507
2508    # look for the last wanif0 device in the log
2509    p1 = string.rfind(ipdata, "wanif0")
2510    if p1 != -1:
2511      ipmatch = Addressgrep.search(ipdata, p1)
2512      if ipmatch != None:
2513        localip = ipmatch.group()
2514        logger.logit("IP matched: " + localip)
2515    else:
2516      p1 = string.rfind(ipdata, "enif1")
2517      if p1 != -1:
2518        ipmatch = Addressgrep.search(ipdata, p1)
2519        if ipmatch != None:
2520          localip = ipmatch.group()
2521          logger.logit("IP matched: " + localip)
2522
2523  elif opt_Zyxel_password:
2524    #
2525    # ZyXEL 642R router ip detection
2526    #
2527
2528    #
2529    # determine the router host address
2530    #
2531    if routerIP:
2532      logger.logit("Zyxel_host set explicitly.")
2533      iphost = routerIP
2534    else:
2535      iphost = DefaultRoute(logger, Tempfile)
2536
2537    if iphost:
2538      logline = "Trying router at " + iphost
2539      logger.logit(logline)
2540    else:
2541      logger.logit("No router ip detected.  Assuming 192.168.1.1")
2542      iphost = "192.168.1.1"
2543
2544    ipdata = ""
2545    ip1 = ""
2546    ip2 = ""
2547    # connect to the router's admin webpage
2548    try:
2549      logger.logit("Trying ZyXEL Prestige 642R and 310")
2550      tn = telnetlib.Telnet(iphost)
2551      logger.logit("Creating telnetlib obj done")
2552      tn.read_until("assword:")
2553      logger.logit("Password prompt found")
2554      tn.write(opt_Zyxel_password + "\r\n")
2555      logger.logit("opt_Zyxel_password sent")
2556      #tn.read_until("Menu Selection Number:")
2557      tn.write("24\r\n")
2558      logger.logit("menu number 24 sent")
2559      #tn.read_until("Menu Selection Number:")
2560      tn.write("8\r\n")
2561      logger.logit("menu number 8 sent")
2562      tn.write("ip ifconfig\r\n")
2563      logger.logit("ip ifconfig sent")
2564      ip1 = tn.read_until(">", 2000)
2565      ip2 = tn.read_until(">", 2000)
2566      logger.logit("ip1 and ip2 read")
2567      tn.write("exit\r\n")
2568      logger.logit("exit sent")
2569      tn.write("99\r\n")
2570      logger.logit("menu number 99 sent")
2571    except:
2572      logger.logit("may not have gotten second prompt")
2573      tn.write("exit\r\n")
2574      logger.logit("exit sent")
2575      tn.write("99\r\n")
2576      logger.logit("menu number 99 sent")
2577
2578    ipdata = ip1 + ip2
2579
2580    # create an output file of the response
2581    filename = "zyxel.out"
2582    if opt_directory:
2583      filename = opt_directory + filename
2584    fp = open(filename, "w")
2585    fp.write(ipdata)
2586    fp.close()
2587    logger.logit("zyxel.out file created")
2588
2589    # look for the last wanif0 device in the log
2590    p1 = string.rfind(ipdata, "wanif0")
2591    if p1 != -1:
2592      ipmatch = Addressgrep.search(ipdata, p1)
2593      if ipmatch != None:
2594        localip = ipmatch.group()
2595        logger.logit("IP matched: " + localip)
2596    else:
2597      p1 = string.rfind(ipdata, "enif1")
2598      if p1 != -1:
2599        ipmatch = Addressgrep.search(ipdata, p1)
2600        if ipmatch != None:
2601          localip = ipmatch.group()
2602          logger.logit("IP matched: " + localip)
2603
2604  elif opt_NetgearWTG624_password:
2605    if routerIP:
2606      logger.logit("NetgearWTG624_host set explicitly.")
2607      iphost = routerIP
2608    else:
2609      iphost = DefaultRoute(logger, Tempfile)
2610
2611    if iphost:
2612      logline = "Trying router at " + iphost
2613      logger.logit(logline)
2614    else:
2615      logger.logit("No router ip detected.  Assuming 192.168.0.1")
2616      iphost = "192.168.0.1"
2617
2618    logger.logit("Trying NetgearWTG624")
2619
2620    logger.logit("Authenticating with home page")
2621    filename = "netgearWTG624p1.out"
2622    if opt_directory:
2623      filename = opt_directory + filename
2624    logindata = BasicAuth(logger, iphost, NetgearWTG624_page1, Netgear_user, opt_NetgearWTG624_password, filename)
2625
2626    logger.logit("Getting status page")
2627    filename = "netgearWTG624p2.out"
2628    if opt_directory:
2629      filename = opt_directory + filename
2630    ipdata = BasicAuth(logger, iphost, NetgearWTG624_page2, Netgear_user, opt_NetgearWTG624_password, filename)
2631
2632    p1 = string.find(ipdata, "IP")
2633    if p1 != -1:
2634      ipmatch = Addressgrep.search(ipdata, p1)
2635      if ipmatch != None:
2636        localip = ipmatch.group()
2637        logger.logit("IP matched: " + localip)
2638
2639    logger.logit("Logging out")
2640    filename = "netgearWTG624p3.out"
2641    if opt_directory:
2642      filename = opt_directory + filename
2643    logoutdata = BasicAuth(logger, iphost, NetgearWTG624_page3, Netgear_user, opt_NetgearWTG624_password, filename)
2644
2645  elif opt_Netgear3114_password:
2646    if routerIP:
2647      logger.logit("Netgear3114_host set explicitly.")
2648      iphost = routerIP
2649    else:
2650      iphost = DefaultRoute(logger, Tempfile)
2651
2652    if iphost:
2653      logline = "Trying router at " + iphost
2654      logger.logit(logline)
2655    else:
2656      logger.logit("No router ip detected.  Assuming 192.168.100.1")
2657      iphost = "192.168.100.1"
2658
2659    logger.logit("Trying Netgear3114")
2660
2661    logger.logit("Authenticating with home page")
2662    filename = "netgear3114p1.out"
2663    if opt_directory:
2664      filename = opt_directory + filename
2665    logindata = BasicAuth(logger, iphost, Netgear3114_page1, Netgear3114_user, opt_Netgear3114_password, filename)
2666
2667    logger.logit("Getting status page")
2668    filename = "netgear3114p2.out"
2669    if opt_directory:
2670      filename = opt_directory + filename
2671    ipdata = BasicAuth(logger, iphost, Netgear3114_page2, Netgear3114_user, opt_Netgear3114_password, filename)
2672
2673    p1 = string.find(ipdata, "IP")
2674    if p1 != -1:
2675      ipmatch = Addressgrep.search(ipdata, p1)
2676      if ipmatch != None:
2677        localip = ipmatch.group()
2678        logger.logit("IP matched: " + localip)
2679
2680    logger.logit("Logging out")
2681    filename = "netgear3114p3.out"
2682    if opt_directory:
2683      filename = opt_directory + filename
2684    logoutdata = BasicAuth(logger, iphost, Netgear3114_page3, Netgear3114_user, opt_Netgear3114_password, filename)
2685
2686  elif opt_Hawking_password:
2687    #
2688    # Hawking router ip detection
2689    #
2690    ipdir = Hawking_page
2691
2692    #
2693    # determine the router host address
2694    #
2695    if routerIP:
2696      logger.logit("Hawking_host set explicitly.")
2697      iphost = routerIP
2698    else:
2699      iphost = DefaultRoute(logger, Tempfile)
2700
2701    if iphost:
2702      logline = "Trying router at " + iphost
2703      logger.logit(logline)
2704    else:
2705      logger.logit("No router ip detected.  Assuming 192.168.10.10")
2706      iphost = "192.168.10.10"
2707
2708    logger.logit("Trying HawkingTech")
2709    filename = "hawking.out"
2710    if opt_directory:
2711      filename = opt_directory + filename
2712    ipdata = BasicAuth(logger, iphost, ipdir, Hawking_user, opt_Hawking_password, filename)
2713
2714    # look for local ip in the log
2715    p1 = string.find(ipdata, "WAN")
2716    if p1 != -1:
2717      ipmatch = Addressgrep.search(ipdata, p1)
2718      if ipmatch != None:
2719        localip = ipmatch.group()
2720        logger.logit("IP matched: " + localip)
2721
2722  elif opt_Ugate_router:
2723    #
2724    # UgatePlus router ip detection
2725    #
2726    ipdir = Ugate_page
2727
2728    #
2729    # determine the router host address
2730    #
2731    if routerIP:
2732      logger.logit("Ugate_host set explicitly.")
2733      iphost = routerIP
2734    else:
2735      iphost = DefaultRoute(logger, Tempfile)
2736
2737    if iphost:
2738      logline = "Trying router at " + iphost
2739      logger.logit(logline)
2740    else:
2741      logger.logit("No router ip detected.  Assuming 192.168.0.1")
2742      iphost = "192.168.0.1"
2743
2744    # connect to the router's admin webpage
2745    try:
2746      logger.logit("Trying UgatePlus")
2747      ipurl = "http://" + iphost + Ugate_page
2748      urlfp = urllib.urlopen(ipurl)
2749      ipdata = urlfp.read()
2750      urlfp.close()
2751    except:
2752      logline = "No address found on router at " + iphost
2753      logger.logexit(logline)
2754      sys.exit(-1)
2755
2756    # create an output file of the response
2757    filename = "ugate.out"
2758    if opt_directory:
2759      filename = opt_directory + filename
2760    fp = open(filename, "w")
2761    fp.write(ipdata)
2762    fp.close()
2763    logger.logit("ugate.out file created")
2764
2765    # look for the last Default gateway
2766    p1 = string.rfind(ipdata, "I.P. Address")
2767    if p1 != -1:
2768      ipmatch = Addressgrep.search(ipdata, p1)
2769      if ipmatch != None:
2770        localip = ipmatch.group()
2771        logger.logit("IP matched: " + localip)
2772
2773  elif opt_Veicon_password:
2774    #
2775    # Eicon Diva 2430 SE ADSL Modem with password
2776    #
2777    ipdir = Veicon_page
2778
2779    #
2780    # determine the router host address
2781    #
2782    if routerIP:
2783      logger.logit("Veicon_host set explicitly.")
2784      iphost = routerIP
2785    else:
2786      iphost = DefaultRoute(logger, Tempfile)
2787
2788    if iphost:
2789      logline = "Trying router at " + iphost
2790      logger.logit(logline)
2791    else:
2792      logger.logit("No router ip detected.  Assuming 192.168.1.1")
2793      iphost = "192.168.1.1"
2794
2795    # connect to the router's admin webpage
2796    try:
2797      logger.logit("Trying Eicon with password")
2798      params = urllib.urlencode({'password': opt_Veicon_password})
2799      ipurl = "http://" + iphost + Veicon_page
2800      urlfp = urllib.urlopen(ipurl, params)
2801      ipdata = urlfp.read()
2802      urlfp.close()
2803    except:
2804      logline = "No address found on router at " + iphost
2805      logger.logexit(logline)
2806      sys.exit(-1)
2807
2808    # create an output file of the response
2809    filename = "veicon.out"
2810    if opt_directory:
2811      filename = opt_directory + filename
2812    fp = open(filename, "w")
2813    fp.write(ipdata)
2814    fp.close()
2815    logger.logit("veicon.out file created")
2816
2817    # look for the last Default gateway
2818    p1 = string.rfind(ipdata, "WAN IP address")
2819    if p1 != -1:
2820      ipmatch = Addressgrep.search(ipdata, p1)
2821      if ipmatch != None:
2822        localip = ipmatch.group()
2823        logger.logit("IP matched: " + localip)
2824
2825  elif opt_Barricade_password:
2826    #
2827    # Newer SMC Barricade with passwords on port 88
2828    #
2829    ipdir = Barricade_page
2830
2831    #
2832    # determine the router host address
2833    #
2834    if routerIP:
2835      logger.logit("Barricade_host set explicitly.")
2836      iphost = routerIP
2837    else:
2838      iphost = DefaultRoute(logger, Tempfile)
2839
2840    if iphost:
2841      logline = "Trying router at " + iphost
2842      logger.logit(logline)
2843    else:
2844      logger.logit("No router ip detected.  Assuming 192.168.2.1")
2845      iphost = "192.168.2.1"
2846
2847    logger.logit("Trying new Barricade with password")
2848
2849    if opt_7004VWBR:
2850      ipport = "80"
2851      loginaction = "/cgi-bin/login.exe"
2852      logoutaction = "/cgi-bin/logout.exe"
2853      statuspage = "/status_main.stm"
2854      ipprefix = "var wan_ip="
2855    else:
2856      ipport = "88"
2857      loginaction = "/login.htm"
2858      logoutaction = "/logout.htm"
2859      statuspage = "/status.HTM"
2860      ipprefix = "WAN IP"
2861
2862    try:
2863      ipurl = "http://" + iphost + ":" + ipport + "/login.htm"
2864      logger.logit("urlopen " + ipurl)
2865      urlfp = urllib.urlopen(ipurl)
2866      logger.logit("urlfp.read")
2867      ipdata = urlfp.read()
2868      logger.logit("urlfp.close")
2869      urlfp.close()
2870      logger.logit("filename = login.out")
2871      filename = "login.out"
2872      if opt_directory:
2873        filename = opt_directory + filename
2874      logger.logit("file open")
2875      fp = open(filename, "w")
2876      logger.logit("write data")
2877      fp.write(ipdata)
2878      logger.logit("file close")
2879      fp.close()
2880      logger.logit("login.out file created")
2881    except:
2882      logline = "Failed to get login form"
2883      logger.logexit(logline)
2884      sys.exit(-1)
2885
2886    try:
2887      logger.logit("Try to post to form")
2888      params = urllib.urlencode({'pws': opt_Barricade_password})
2889      ipurl = "http://" + iphost + ":" + ipport + loginaction
2890      logger.logit("urlopen " + ipurl)
2891      urlfp = urllib.urlopen(ipurl, params)
2892      logger.logit("urlfp.read")
2893      ipdata = urlfp.read()
2894      logger.logit("urlfp.close")
2895      urlfp.close()
2896      if string.find(ipdata, "not found") != -1 or string.find(ipdata, "<html><head><meta http-equiv=refresh content='0; url=index.htm'></head></html>") == -1:
2897          logger.logit("Trying to with page=login&")
2898          urlfp = urllib.urlopen(ipurl, "page=login&" + params)
2899          logger.logit("urlfp.read")
2900          ipdata = urlfp.read()
2901          logger.logit("urlfp.close")
2902          urlfp.close()
2903
2904      filename = "post.out"
2905      if opt_directory:
2906        filename = opt_directory + filename
2907      fp = open(filename, "w")
2908      fp.write(ipdata)
2909      fp.close()
2910      logger.logit("post.out file created")
2911    except:
2912      logline = "Failed to post password to login form"
2913      logger.logexit(logline)
2914      sys.exit(-1)
2915
2916    try:
2917      logger.logit("Now try to access " + statuspage + " on port " + ipport)
2918      ipurl = "http://" + iphost + ":" + ipport + statuspage
2919      urlfp = urllib.urlopen(ipurl)
2920      ipdata = urlfp.read()
2921      urlfp.close()
2922
2923      filename = "barricade.out"
2924      if opt_directory:
2925        filename = opt_directory + filename
2926      fp = open(filename, "w")
2927      fp.write(ipdata)
2928      fp.close()
2929      logger.logit("barricade.out file created")
2930    except:
2931      logline = "Failed accessing status page "
2932      logger.logexit(logline)
2933      sys.exit(-1)
2934
2935    # look for the last Default gateway
2936    p1 = string.rfind(ipdata, ipprefix)
2937    if p1 != -1:
2938      ipmatch = Addressgrep.search(ipdata, p1)
2939      if ipmatch != None:
2940        localip = ipmatch.group()
2941        logger.logit("IP matched: " + localip)
2942
2943    # logout so other users can login to the Barricade
2944    try:
2945      logger.logit("Try to post to logout form")
2946      ipurl = "http://" + iphost + ":" + ipport + logoutaction
2947      logger.logit("urlopen " + ipurl)
2948      urlfp = urllib.urlopen(ipurl)
2949      logger.logit("urlfp.read")
2950      ipdata = urlfp.read()
2951      logger.logit("urlfp.close")
2952      urlfp.close()
2953
2954      filename = "logout.out"
2955      if opt_directory:
2956        filename = opt_directory + filename
2957      fp = open(filename, "w")
2958      fp.write(ipdata)
2959      fp.close()
2960      logger.logit("logout.out file created")
2961    except:
2962      logline = "Failed to post to logout form"
2963      logger.logexit(logline)
2964      sys.exit(-1)
2965
2966  elif opt_Siemens2620_password:
2967    #
2968    # Siemens SpeedStream 2620 with passwords on port 88
2969    # (This is just like the SMC Barricade entry just above, save that
2970    # some of the URLs are slightly different. Is the Siemens unit just
2971    # a rebadged SMC or vice-versa?)
2972    #
2973    ipdir = Siemens2620_page
2974
2975    #
2976    # determine the router host address
2977    #
2978    if routerIP:
2979      logger.logit("Siemens2620_host set explicitly.")
2980      iphost = routerIP
2981    else:
2982      iphost = DefaultRoute(logger, Tempfile)
2983
2984    if iphost:
2985      logline = "Trying router at " + iphost
2986      logger.logit(logline)
2987    else:
2988      logger.logit("No router ip detected.  Assuming 192.168.254.254")
2989      iphost = "192.168.254.254"
2990
2991    logger.logit("Trying Siemens SpeedStream 2620 with password")
2992
2993    try:
2994      ipurl = "http://" + iphost + ":88/"
2995      logger.logit("urlopen " + ipurl)
2996      urlfp = urllib.urlopen(ipurl)
2997      logger.logit("urlfp.read")
2998      ipdata = urlfp.read()
2999      logger.logit("urlfp.close")
3000      urlfp.close()
3001      logger.logit("filename = login.out")
3002      filename = "login.out"
3003      if opt_directory:
3004        filename = opt_directory + filename
3005      logger.logit("file open")
3006      fp = open(filename, "w")
3007      logger.logit("write data")
3008      fp.write(ipdata)
3009      logger.logit("file close")
3010      fp.close()
3011      logger.logit("login.out file created")
3012    except:
3013      logline = "Failed to get login form"
3014      logger.logexit(logline)
3015      sys.exit(-1)
3016
3017    try:
3018      logger.logit("Try to post to form")
3019      params = urllib.urlencode({'pws': opt_Siemens2620_password})
3020      ipurl = "http://" + iphost + ":88/LOGIN.HTM"
3021      logger.logit("urlopen " + ipurl)
3022      urlfp = urllib.urlopen(ipurl, params)
3023      logger.logit("urlfp.read")
3024      ipdata = urlfp.read()
3025      logger.logit("urlfp.close")
3026      urlfp.close()
3027      if string.find(ipdata, "not found") != -1:
3028          logger.logit("Trying to with page=login&")
3029          params = urllib.urlencode({'pws': opt_Siemens2620_password})
3030          ipurl = "http://" + iphost + ":88/LOGIN.HTM"
3031          logger.logit("urlopen " + ipurl)
3032          urlfp = urllib.urlopen(ipurl, "page=login&" + params)
3033          logger.logit("urlfp.read")
3034          ipdata = urlfp.read()
3035          logger.logit("urlfp.close")
3036          urlfp.close()
3037
3038      filename = "post.out"
3039      if opt_directory:
3040        filename = opt_directory + filename
3041      fp = open(filename, "w")
3042      fp.write(ipdata)
3043      fp.close()
3044      logger.logit("post.out file created")
3045    except:
3046      logline = "Failed to post password to login form"
3047      logger.logexit(logline)
3048      sys.exit(-1)
3049
3050    try:
3051      logger.logit("Now try to access status.HTM on port 88")
3052      ipurl = "http://" + iphost + ":88/MAIN.HTM"
3053      urlfp = urllib.urlopen(ipurl)
3054      ipdata = urlfp.read()
3055      urlfp.close()
3056
3057      filename = "siemens.out"
3058      if opt_directory:
3059        filename = opt_directory + filename
3060      fp = open(filename, "w")
3061      fp.write(ipdata)
3062      fp.close()
3063      logger.logit("siemens.out file created")
3064    except:
3065      logline = "Failed accessing status page "
3066      logger.logexit(logline)
3067      sys.exit(-1)
3068
3069    # look for the last Default gateway
3070    p1 = string.rfind(ipdata, "WAN IP")
3071    if p1 != -1:
3072      ipmatch = Addressgrep.search(ipdata, p1)
3073      if ipmatch != None:
3074        localip = ipmatch.group()
3075        logger.logit("IP matched: " + localip)
3076
3077
3078  elif opt_Eicon_router:
3079    #
3080    # Eicon Diva 2430 SE ADSL Modem ip detection
3081    #
3082    ipdir = Eicon_page
3083
3084    #
3085    # determine the router host address
3086    #
3087    if routerIP:
3088      logger.logit("Eicon_host set explicitly.")
3089      iphost = routerIP
3090    else:
3091      iphost = DefaultRoute(logger, Tempfile)
3092
3093    if iphost:
3094      logline = "Trying router at " + iphost
3095      logger.logit(logline)
3096    else:
3097      logger.logit("No router ip detected.  Assuming 192.168.1.1")
3098      iphost = "192.168.1.1"
3099
3100    # connect to the router's admin webpage
3101    try:
3102      logger.logit("Trying Eicon")
3103      ipurl = "http://" + iphost + Eicon_page
3104      urlfp = urllib.urlopen(ipurl)
3105      ipdata = urlfp.read()
3106      urlfp.close()
3107    except:
3108      logline = "No address found on router at " + iphost
3109      logger.logexit(logline)
3110      sys.exit(-1)
3111
3112    # create an output file of the response
3113    filename = "eicon.out"
3114    if opt_directory:
3115      filename = opt_directory + filename
3116    fp = open(filename, "w")
3117    fp.write(ipdata)
3118    fp.close()
3119    logger.logit("eicon.out file created")
3120
3121    # look for the last Default gateway
3122    p1 = string.rfind(ipdata, "WAN IP address")
3123    if p1 != -1:
3124      ipmatch = Addressgrep.search(ipdata, p1)
3125      if ipmatch != None:
3126        localip = ipmatch.group()
3127        logger.logit("IP matched: " + localip)
3128
3129
3130  elif opt_II_password:
3131    #
3132    # Instant Internet router ip detection
3133    #
3134
3135    #
3136    # determine the router host address
3137    #
3138    if routerIP:
3139      logger.logit("II_host set explicitly.")
3140      iphost = routerIP
3141    else:
3142      iphost = DefaultRoute(logger, Tempfile)
3143
3144    if iphost:
3145      logline = "Trying router at " + iphost
3146      logger.logit(logline)
3147    else:
3148      logger.logit("No router ip detected.  Assuming 192.168.1.1")
3149      iphost = "192.168.1.1"
3150
3151    # connect to the router's admin webpage
3152    try:
3153      logger.logit("Trying Instant Internet ")
3154      tn = telnetlib.Telnet(iphost)
3155      logger.logit("Creating telnetlib obj done")
3156      tn.read_until("assword:")
3157      logger.logit("Password prompt found")
3158      tn.write(opt_II_password + "\r\n")
3159      logger.logit("opt_II_password sent")
3160      tn.write("ppp " + opt_II_interface + "\r\n")
3161      logger.logit("ppp " + opt_II_interface + " sent")
3162      ip1 = tn.read_until("state:", 2000)
3163      logger.logit("ip read")
3164      tn.write("exit\r\n")
3165      logger.logit("exit sent")
3166      ipdata = ip1
3167    except:
3168      logline = "No address found on router at " + iphost
3169      logger.logexit(logline)
3170      sys.exit(-1)
3171
3172
3173    # create an output file of the response
3174    filename = "II.out"
3175    if opt_directory:
3176      filename = opt_directory + filename
3177    fp = open(filename, "w")
3178    fp.write(ipdata)
3179    fp.close()
3180    logger.logit("II.out file created")
3181
3182    # look for the last ipadr device in the log
3183    p1 = string.rfind(ipdata, "ipadr local:")
3184    if p1 != -1:
3185      ipmatch = Addressgrep.search(ipdata, p1)
3186      if ipmatch != None:
3187        localip = ipmatch.group()
3188        logger.logit("IP matched: " + localip)
3189
3190
3191  elif opt_Nexland_router:
3192    #
3193    # Nexland router ip detection
3194    #
3195    ipdir = Nexland_page
3196
3197    #
3198    # determine the router host address
3199    #
3200    if routerIP:
3201      logger.logit("Nexland_host set explicitly.")
3202      iphost = routerIP
3203    else:
3204      iphost = DefaultRoute(logger, Tempfile)
3205
3206    if iphost:
3207      logline = "Trying router at " + iphost
3208      logger.logit(logline)
3209    else:
3210      logger.logit("No router ip detected.  Assuming 192.168.1.1")
3211      iphost = "192.168.1.1"
3212
3213    # connect to the router's admin webpage
3214    try:
3215      logger.logit("Trying Nexland")
3216      ipurl = "http://" + iphost + Nexland_page
3217      urlfp = urllib.urlopen(ipurl)
3218      ipdata = urlfp.read()
3219      urlfp.close()
3220    except:
3221      logline = "No address found on router at " + iphost
3222      logger.logexit(logline)
3223      sys.exit(-1)
3224
3225    # create an output file of the response
3226    filename = "nexland.out"
3227    if opt_directory:
3228      filename = opt_directory + filename
3229    fp = open(filename, "w")
3230    fp.write(ipdata)
3231    fp.close()
3232    logger.logit("nexland.out file created")
3233
3234    # look for the last Default gateway
3235    p1 = string.rfind(ipdata, "Default gateway")
3236    if p1 == -1:
3237      p1 = string.find(ipdata, "IP Address<")
3238    if p1 != -1:
3239      ipmatch = Addressgrep.search(ipdata, p1)
3240      if ipmatch != None:
3241        localip = ipmatch.group()
3242        logger.logit("IP matched: " + localip)
3243
3244  elif opt_Pro800Turbo_router:
3245    #
3246    # Nexland Pro800Turbo router ip detection
3247    #
3248    ipdir = Pro800Turbo_page
3249
3250    #
3251    # determine the router host address
3252    #
3253    if routerIP:
3254      logger.logit("Pro800Turbo_host set explicitly.")
3255      iphost = routerIP
3256    else:
3257      iphost = DefaultRoute(logger, Tempfile)
3258
3259    if iphost:
3260      logline = "Trying router at " + iphost
3261      logger.logit(logline)
3262    else:
3263      logger.logit("No router ip detected.  Assuming 192.168.1.1")
3264      iphost = "192.168.1.1"
3265
3266    # connect to the router's admin webpage
3267    try:
3268      logger.logit("Trying Pro800Turbo")
3269      h1 = httplib.HTTP(iphost)
3270      h1.putrequest('GET',Pro800Turbo_page)
3271      if Pro800Turbo_password:
3272        authstring = base64.encodestring("admin:" + Pro800Turbo_password)
3273        h1.putheader('Authorization', 'Basic ' + authstring)
3274      # print ipdir
3275      h1.endheaders()
3276      errcode, errmsg, headers = h1.getreply()
3277      # print errcode
3278      # print errmsg
3279      fp = h1.getfile()
3280      ipdata = fp.read()
3281      fp.close()
3282    except:
3283      logline = "No address found on router at " + iphost
3284      logger.logexit(logline)
3285      sys.exit(-1)
3286
3287    # create an output file of the response
3288    filename = "pro800turbo.out"
3289    if opt_directory:
3290      filename = opt_directory + filename
3291    fp = open(filename, "w")
3292    fp.write(ipdata)
3293    fp.close()
3294    logger.logit("pro800turbo.out file created")
3295
3296    p1 = 0
3297    local_ips = []
3298    connected = []
3299    while 1:
3300      p2 = string.find(ipdata[p1:], ">Connection Status<")
3301      if p2 == -1:
3302        break
3303      p1 = p1 + p2 + 1
3304      cmatch = re.search(">([^>]+)</td>",ipdata[p1:])
3305      if cmatch == None:
3306        break
3307      connected.append(cmatch.group(1))
3308      p2 = string.find(ipdata[p1:], "IP Address<")
3309      if p2 == -1:
3310        break
3311      p1 = p1 + p2
3312      if p1 == -1:
3313        break
3314      ipmatch = Addressgrep.search(ipdata, p1)
3315      p1 = p1 + len("IP Address<")
3316      if ipmatch == None:
3317        local_ips.append(None)
3318      else:
3319        local_ips.append(ipmatch.group())
3320
3321    if Pro800Turbo_port == 'force':
3322      if local_ips[Pro800Turbo_port_number] != '0.0.0.0':
3323        # if forced, don't even check connection.  We might as well use
3324        # the IP we get, even it it isn't currently working.
3325        localip = local_ips[Pro800Turbo_port_number]
3326    else:
3327      if     local_ips[Pro800Turbo_port_number] != '0.0.0.0' \
3328         and connected[Pro800Turbo_port_number] == 'Connected':
3329        localip = local_ips[Pro800Turbo_port_number]
3330      else:
3331        for i in range(len(local_ips)):
3332          if local_ips[i] != '0.0.0.0':
3333            localip = local_ips[i]
3334            if connected[i] == 'Connected':
3335              break
3336            # Else keep looking for one that is "Connected".  If we don't find
3337            # one, might as well use the an ip address, even if not
3338            # "Connected".  I've had situations where that was still usable.
3339    if localip:
3340      logger.logit("IP matched: " + localip)
3341
3342  elif opt_SMC_router:
3343    #
3344    # SMC barricade router ip detection
3345    #
3346    ipdir = SMC_page
3347
3348    #
3349    # determine the router host address
3350    #
3351    if routerIP:
3352      logger.logit("SMC_host set explicitly.")
3353      iphost = routerIP
3354    else:
3355      iphost = DefaultRoute(logger, Tempfile)
3356
3357    if iphost:
3358      logline = "Trying router at " + iphost
3359      logger.logit(logline)
3360    else:
3361      logger.logit("No router ip detected.  Assuming 192.168.0.254")
3362      iphost = "192.168.0.254"
3363
3364    # connect to the router's admin webpage
3365    try:
3366      if opt_WBR != "":
3367        logger.logit("Trying SMC WBR with password")
3368        if opt_7004VWBR:
3369          # 2005-02-15 djlauk@users.sourceforge.net:
3370          # quick hack for SMC7004VWBRV.2
3371          logger.logit("Trying DJ's hack for model SMC7004VWBRV.2")
3372          SMC_page = "/login.htm?pws=" + opt_WBR
3373        else:
3374          SMC_page = "/login.cgi?pws=" + opt_WBR
3375        ipurl = "http://" + iphost + SMC_page
3376        urlfp = urllib.urlopen(ipurl)
3377        ipdata = urlfp.read()
3378        urlfp.close()
3379        SMC_page = "/status_main.htm"
3380        ipurl = "http://" + iphost + SMC_page
3381        urlfp = urllib.urlopen(ipurl)
3382        ipdata = urlfp.read()
3383        urlfp.close()
3384      else:
3385        logger.logit("Trying SMC")
3386        ipurl = "http://" + iphost + SMC_page
3387        urlfp = urllib.urlopen(ipurl)
3388        ipdata = urlfp.read()
3389        urlfp.close()
3390    except:
3391      logline = "No address found on router at " + iphost
3392      logger.logexit(logline)
3393      sys.exit(-1)
3394
3395    # create an output file of the response
3396    filename = "smc.out"
3397    if opt_directory:
3398      filename = opt_directory + filename
3399    fp = open(filename, "w")
3400    fp.write(ipdata)
3401    fp.close()
3402    logger.logit("smc.out file created")
3403
3404    # grab first thing that looks like an IP address
3405    ipmatch = Addressgrep.search(ipdata)
3406    if ipmatch != None:
3407      localip = ipmatch.group()
3408      logger.logit("IP matched: " + localip)
3409
3410  elif opt_Netvanta_password != "":
3411    #
3412    # Adtran Netvanta router ip detection
3413    #
3414    #
3415    # determine the router host address
3416    #
3417    iphost = ""
3418    if routerIP:
3419      logger.logit("Netvanta_host set explicitly.")
3420      iphost = routerIP
3421    else:
3422      iphost = DefaultRoute(logger, Tempfile)
3423
3424    if iphost == "":
3425      logger.logit("No router ip detected.  Assuming 192.168.1.1")
3426      iphost = "192.168.1.1"
3427    else:
3428      logline = "Trying router at " + iphost
3429      logger.logit(logline)
3430
3431    # connect to the router's telnet interface
3432    # first try to talk to a Netvanta Series router
3433    try:
3434      logger.logit("Trying Netvanta router (AOS!)")
3435      tn = telnetlib.Telnet(iphost)
3436      logger.logit("Creating telnetlib obj done")
3437      tn.read_until("assword:")
3438      logger.logit("Password prompt found")
3439      tn.write(opt_Netvanta_password + "\r\n")
3440      logger.logit("Netvanta password sent")
3441      tn.write("enable\r\n")
3442      tn.read_until("assword:")
3443      logger.logit("enable Password prompt found")
3444      tn.write(opt_Netvanta_password + "\r\n")
3445      logger.logit("Netvanta password sent")
3446      tn.write("show interface ethernet 0/1\r\n")
3447      logger.logit("show interface command sent")
3448      ipdata = tn.read_until(", netmask", 1000)
3449      ipdata = string.replace(ipdata, ", netmask", "")
3450      logger.logit("ipdata read")
3451      tn.write("logo\r\n")
3452      logger.logit("logoff sent")
3453    except:
3454      logline = "No address found on router at " + iphost
3455      logger.logexit(logline)
3456      sys.exit(-1)
3457
3458    # create an output file of the response
3459    filename = "netvanta.out"
3460    if opt_directory != "":
3461      filename = opt_directory + filename
3462    fp = open(filename, "w")
3463    fp.write(ipdata)
3464    fp.close()
3465    logger.logit("netvanta.out file created")
3466
3467    # look for the last (rfind) negotiated IP in the log
3468    p1 = string.rfind(ipdata, "Internet address is ")
3469    if p1 != -1:
3470      ipmatch = Addressgrep.search(ipdata, p1)
3471      if ipmatch != None:
3472        localip = ipmatch.group()
3473        logger.logit("IP matched: " + localip)
3474
3475  elif opt_Cisco_password != "":
3476    #
3477    # Cisco router ip detection
3478    #
3479    #
3480    # determine the router host address
3481    #
3482    iphost = ""
3483    if routerIP:
3484      logger.logit("Cisco_host set explicitly.")
3485      iphost = Cisco_host
3486    else:
3487      iphost = DefaultRoute(logger, Tempfile)
3488    iphost = DefaultRoute(logger, Tempfile)
3489
3490    if iphost == "":
3491      logger.logit("No router ip detected.  Assuming 192.168.10.5")
3492      iphost = "192.168.10.5"
3493    else:
3494      logline = "Trying router at " + iphost
3495      logger.logit(logline)
3496
3497    # connect to the router's admin webpage
3498    # first try to talk to a Cisco 800-series
3499    try:
3500      logger.logit("Trying Cisco DSL 800 series (IOS!)")
3501      tn = telnetlib.Telnet(iphost)
3502      logger.logit("Creating telnetlib obj done")
3503      tn.read_until("assword:")
3504      logger.logit("Password prompt found")
3505      tn.write(opt_Cisco_password + "\r\n")
3506      logger.logit("Cisco password sent")
3507      tn.write("show ip interface | incl /32\r\n")
3508      logger.logit("show ip interface command sent")
3509      ipdata = tn.read_until("/32", 1000)
3510      logger.logit("unwanted stuff read")
3511      ipdata = tn.read_until("/32", 1000)
3512      ipdata = string.replace(ipdata, "/32", "")
3513      logger.logit("ipdata read")
3514      tn.write("logo\r\n")
3515      logger.logit("logoff sent")
3516    except:
3517      logline = "No address found on router at " + iphost
3518      logger.logexit(logline)
3519      sys.exit(-1)
3520
3521    # create an output file of the response
3522    filename = "cisco.out"
3523    if opt_directory != "":
3524      filename = opt_directory + filename
3525    fp = open(filename, "w")
3526    fp.write(ipdata)
3527    fp.close()
3528    logger.logit("cisco.out file created")
3529
3530    # look for the last (rfind) negotiated IP in the log
3531    p1 = string.rfind(ipdata, "Internet address is ")
3532    if p1 != -1:
3533      ipmatch = Addressgrep.search(ipdata, p1)
3534      if ipmatch != None:
3535        localip = ipmatch.group()
3536        logger.logit("IP matched: " + localip)
3537
3538
3539  elif opt_ISDNCisco_password:
3540    #
3541    # ISDNCisco router ip detection
3542    #
3543
3544    #
3545    # determine the router host address
3546    #
3547    if routerIP:
3548      logger.logit("ISDNCisco_host set explicitly.")
3549      iphost = routerIP
3550    else:
3551      iphost = DefaultRoute(logger, Tempfile)
3552
3553    if iphost:
3554      logline = "Trying router at " + iphost
3555      logger.logit(logline)
3556    else:
3557      logger.logit("No router ip detected.  Assuming 192.168.10.5")
3558      iphost = "192.168.10.5"
3559
3560    # connect to the router's admin webpage
3561    # first try to talk to a Cisco 667i
3562    try:
3563      logger.logit("Trying Cisco ISDN 700 series")
3564      tn = telnetlib.Telnet(iphost)
3565      logger.logit("Creating telnetlib obj done")
3566      tn.read_until("assword:")
3567      logger.logit("Password prompt found")
3568      tn.write(opt_ISDNCisco_password + "\r\n")
3569      logger.logit("opt_ISDNCisco_password sent")
3570      tn.write("show ip co\r\n")
3571      logger.logit("show ip co sent")
3572      ipdata = tn.read_until("Profile     PAT", 1000)
3573      logger.logit("ipdata read")
3574      tn.write("bye\r\n")
3575      logger.logit("bye sent")
3576    except:
3577      logline = "No address found on router at " + iphost
3578      logger.logexit(logline)
3579      sys.exit(-1)
3580
3581    # create an output file of the response
3582    filename = "cisco.out"
3583    if opt_directory:
3584      filename = opt_directory + filename
3585    fp = open(filename, "w")
3586    fp.write(ipdata)
3587    fp.close()
3588    logger.logit("cisco.out file created")
3589
3590    # look for the last negotiated IP in the log
3591    # you may have to change this to a user defined profile
3592    p1 = string.rfind(ipdata, "RemoteNet")
3593    if p1 != -1:
3594      ipmatch = Addressgrep.search(ipdata, p1)
3595      if ipmatch != None:
3596        localip = ipmatch.group()
3597        logger.logit("IP matched: " + localip)
3598
3599  elif opt_Netopia_password:
3600    #
3601    # Netopia router ip detection
3602    #
3603    ipdir = Netopia_page
3604
3605    #
3606    # determine the router host address
3607    #
3608    if routerIP:
3609      logger.logit("Netopia_host set explicitly.")
3610      iphost = routerIP
3611    else:
3612      iphost = DefaultRoute(logger, Tempfile)
3613
3614    if iphost:
3615      logline = "Trying router at " + iphost
3616      logger.logit(logline)
3617    else:
3618      logger.logit("No router ip detected.  Assuming 192.168.0.1")
3619      iphost = "192.168.0.1"
3620
3621    logger.logit("Trying Netopia")
3622    filename = "netopia.out"
3623    if opt_directory:
3624      filename = opt_directory + filename
3625    ipdata = BasicAuth(logger, iphost, Netopia_page, Netopia_user, opt_Netopia_password, filename)
3626
3627    # look for local ip in the log
3628    p1 = string.find(ipdata, "local")
3629    if p1 != -1:
3630      ipmatch = Addressgrep.search(ipdata, p1)
3631      if ipmatch != None:
3632        localip = ipmatch.group()
3633        logger.logit("IP matched: " + localip)
3634
3635  elif opt_Draytek_password:
3636    #
3637    # Draytek router ip detection
3638    #
3639    ipdir = Draytek_page
3640
3641    #
3642    # determine the router host address
3643    #
3644    if routerIP:
3645      logger.logit("Draytek_host set explicitly.")
3646      iphost = routerIP
3647    else:
3648      iphost = DefaultRoute(logger, Tempfile)
3649
3650    if iphost:
3651      logline = "Trying router at " + iphost
3652      logger.logit(logline)
3653    else:
3654      logger.logit("No router ip detected.  Assuming 192.168.1.1")
3655      iphost = "192.168.1.1"
3656
3657    logger.logit("Trying Draytek")
3658    filename = "draytek.out"
3659    if opt_directory:
3660      filename = opt_directory + filename
3661    ipdata = BasicAuth(logger, iphost, Draytek_page, Draytek_user, opt_Draytek_password, filename)
3662
3663    # grab first thing that looks like an IP address
3664    ipmatch = Addressgrep.search(ipdata)
3665    if ipmatch != None:
3666      localip = ipmatch.group()
3667      logger.logit("IP matched: " + localip)
3668
3669  elif opt_MotorolaVT1000v_router:
3670    #
3671    # Motorola VT1000v router ip detection
3672    #
3673    ipdir = MotorolaVT1000v_page
3674
3675    #
3676    # determine the router host address
3677    #
3678    if routerIP:
3679      logger.logit("MotorolaVT1000v_host set explicitly.")
3680      iphost = routerIP
3681    else:
3682      iphost = DefaultRoute(logger, Tempfile)
3683
3684    if iphost:
3685      logline = "Trying router at " + iphost
3686      logger.logit(logline)
3687    else:
3688      logger.logit("No router ip detected.  Assuming 192.168.0.1")
3689      iphost = "192.168.0.1"
3690
3691    # connect to the router's admin webpage
3692    try:
3693      logger.logit("Trying Motorola VT1000v")
3694      ipurl = "http://" + iphost + MotorolaVT1000v_page
3695      urlfp = urllib.urlopen(ipurl)
3696      ipdata = urlfp.read()
3697      urlfp.close()
3698    except:
3699      logline = "No address found on router at " + iphost
3700      logger.logexit(logline)
3701      sys.exit(-1)
3702
3703    # create an output file of the response
3704    filename = "motorolaVT1000v.out"
3705    if opt_directory:
3706      filename = opt_directory + filename
3707    fp = open(filename, "w")
3708    fp.write(ipdata)
3709  elif opt_Belkin_f5d7230_router:
3710
3711    if routerIP:
3712      logger.logit("Belkin_f5d7230 router ip set explicitly.")
3713      iphost = routerIP
3714    else:
3715      iphost = DefaultRoute(logger, Tempfile)
3716
3717    if iphost:
3718      logline = "Trying router at " + iphost
3719      logger.logit(logline)
3720    else:
3721      logger.logit("No router ip detected.  Assuming 192.168.1.1")
3722      iphost = "192.168.1.1"
3723
3724    # connect to the router's admin webpage
3725    ipdir = Belkin_f5d7230_page
3726    try:
3727      logger.logit("Trying Belkin f5d7230")
3728      ipurl = "http://" + iphost + ipdir
3729      urlfp = urllib.urlopen(ipurl)
3730      ipdata = urlfp.read()
3731      urlfp.close()
3732    except:
3733      logline = "No address found on router at " + iphost
3734      logger.logexit(logline)
3735      sys.exit(-1)
3736
3737    # create an output file of the response
3738    filename = "belkin_f5d7230.out"
3739    if opt_directory:
3740      filename = opt_directory + filename
3741    fp = open(filename, "w")
3742    fp.write(ipdata)
3743    fp.close()
3744    logger.logit("%s file created" % filename)
3745
3746    p1 = string.find(ipdata, "wan_conn.html")
3747    if p1 != -1:
3748      ipmatch = Addressgrep.search(ipdata, p1)
3749      if ipmatch != None:
3750        localip = ipmatch.group()
3751        logger.logit("IP matched: " + localip)
3752
3753
3754    fp.close()
3755    logger.logit("%s file created" % filename)
3756
3757    # look for the last Default gateway
3758    ipre = re.compile ('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
3759    routerip = ipre.findall(ipdata)
3760    if len(routerip) > 0:
3761      localip = routerip[0]
3762      logger.logit("IP matched: " + localip)
3763
3764  elif opt_Macsense_password:
3765    #
3766    # MacSense router ip detection
3767    #
3768    ipdir = Macsense_page
3769
3770    #
3771    # determine the router host address
3772    #
3773    if routerIP:
3774      logger.logit("Macsense_host set explicitly.")
3775      iphost = routerIP
3776    else:
3777      iphost = DefaultRoute(logger, Tempfile)
3778
3779    if iphost:
3780      logline = "Trying MacSense XRouter Pro router at " + iphost
3781      logger.logit(logline)
3782    else:
3783      logger.logit("No router ip detected.  Assuming 192.168.1.1")
3784      iphost = "192.168.1.1"
3785
3786    # connect to the router's admin webpage
3787    try:
3788      logger.logit("Trying MacSense")
3789      h1 = httplib.HTTP(iphost)
3790
3791      authstring = base64.encodestring(Macsense_user + ":" + opt_Macsense_password)
3792      authstring = string.replace(authstring, "\012", "")
3793      ipdir = Macsense_page + ' \r\n' \
3794        + 'Authorization: Basic ' \
3795        + authstring + '\r\n'
3796      h1.putrequest('GET', ipdir)
3797      h1.endheaders()
3798
3799      errcode, errmsg, headers = h1.getreply()
3800      fp = h1.getfile()
3801      ipdata = fp.read()
3802      fp.close()
3803    except:
3804      logline = "No address found on router at " + iphost
3805      logger.logexit(logline)
3806      sys.exit(-1)
3807
3808    # create an output file of the linksys response
3809    filename = "macsense.out"
3810    if opt_directory:
3811      filename = opt_directory + filename
3812    fp = open(filename, "w")
3813    fp.write(ipdata)
3814    fp.close()
3815    logger.logit("macsense.out file created")
3816
3817    p1 = string.find(ipdata, "Public IP")
3818    if p1 != -1:
3819      ipmatch = Addressgrep.search(ipdata, p1)
3820      if ipmatch != None:
3821        localip = ipmatch.group()
3822        logger.logit("IP matched: " + localip)
3823
3824  elif opt_Netgear_password:
3825    #
3826    # Netgear router ip detection
3827    #
3828    ipdir = Netgear_page
3829
3830    #
3831    # determine the router host address
3832    #
3833    if routerIP:
3834      logger.logit("Netgear_host set explicitly.")
3835      iphost = routerIP
3836    else:
3837      iphost = DefaultRoute(logger, Tempfile)
3838
3839    if iphost:
3840      logline = "Trying router at " + iphost
3841      logger.logit(logline)
3842    else:
3843      logger.logit("No router ip detected.  Assuming 192.168.0.1")
3844      iphost = "192.168.0.1"
3845
3846    logger.logit("Trying Netgear")
3847    filename = "netgear.out"
3848    if opt_directory:
3849      filename = opt_directory + filename
3850    ipdata = BasicAuth(logger, iphost, Netgear_page, Netgear_user, opt_Netgear_password, filename)
3851
3852    # look for the last WAN Port in the log
3853    p1 = string.rfind(ipdata, "WAN")
3854    if p1 == -1:
3855      ipdata = BasicAuth(logger, iphost, Netgear314_page1, Netgear_user, opt_Netgear_password, filename)
3856      p1 = string.rfind(ipdata, "WAN")
3857    if p1 == -1:
3858      ipdata = BasicAuth(logger, iphost, Netgear314_page2, Netgear_user, opt_Netgear_password, filename)
3859      p1 = string.rfind(ipdata, "WAN")
3860    # Gene Cumm--Netgear FVS318	//GRC
3861    if p1 == -1:
3862      ipdata = BasicAuth(logger, iphost, NetgearFVS318_page, Netgear_user, opt_Netgear_password, filename)
3863      p1 = string.rfind(ipdata, "WAN Port")
3864
3865    if p1 != -1:
3866      ipmatch = Addressgrep.search(ipdata, p1)
3867      if ipmatch != None:
3868        localip = ipmatch.group()
3869        logger.logit("IP matched: " + localip)
3870
3871        logger.logit("Logging out on Netgear")
3872        # hit the logout page
3873        filename = "logout.out"
3874        if opt_directory:
3875          filename = opt_directory + filename
3876        ipdata = BasicAuth(logger, iphost, Netgear_logout, Netgear_user, opt_Netgear_password, filename)
3877
3878  elif opt_DInop_router == 1:
3879    #
3880    # DI704 router ip detection
3881    #
3882    ipdir = DI704_page
3883
3884    #
3885    # determine the router host address
3886    #
3887    if routerIP:
3888      logger.logit("DI704_host set explicitly.")
3889      iphost = routerIP
3890    else:
3891      iphost = DefaultRoute(logger, Tempfile)
3892
3893    if iphost:
3894      logline = "Trying router at " + iphost
3895      logger.logit(logline)
3896    else:
3897      logger.logit("No router ip detected.  Assuming 192.168.0.1")
3898      iphost = "192.168.0.1"
3899
3900    logger.logit("Trying DI704 no password")
3901
3902    try:
3903      logger.logit("Retrieving menu.htm...")
3904      ipurl = "http://" + iphost + "/menu.htm?RC=@"
3905      urlfp = urllib.urlopen(ipurl)
3906      menudata = urlfp.read()
3907      urlfp.close()
3908
3909      filename = "di704_menu.out"
3910      if opt_directory != "":
3911        filename = opt_directory + filename
3912      fp = open(filename, "w")
3913      fp.write(menudata)
3914      fp.close()
3915      logger.logit("di704menu.out file created")
3916    except:
3917      logline = "Failed while fetching menu.htm page "
3918      logger.logexit(logline)
3919      sys.exit(-1)
3920
3921    logline = "Parsing menu... "
3922    logger.logit("Parsing menu")
3923    menud = {}
3924    p1 = 0;
3925    p2 = 0;
3926    while 1:
3927      p1 = string.find(menudata, "VALUE=", p2)
3928      p2 = string.find(menudata, "NAME=", p1)
3929      if p1 == -1 or p2 == -1:
3930          break
3931      p3 = string.find(menudata, '"', p1)
3932      p4 = string.find(menudata, '"', p3 + 1)
3933      p5 = string.find(menudata, '>', p2)
3934      if p3 == -1 or p4 == -1 or p5 == -1:
3935          break
3936
3937      rhs = menudata[p3+1:p4]
3938      lhs = menudata[p2+6:p5]
3939
3940      logline = lhs + " = " + rhs
3941      logger.logit(logline)
3942      menud[lhs] = rhs
3943
3944    logger.logit("Adding password")
3945    menud["URL"] = opt_DI704_password
3946
3947    try:
3948      logger.logit("Now try to access status.htm now")
3949      ipurl = "http://" + iphost + "/status.htm"
3950      urlfp = urllib.urlopen(ipurl)
3951      ipdata = urlfp.read()
3952      urlfp.close()
3953
3954      filename = "di704.out"
3955      if opt_directory:
3956        filename = opt_directory + filename
3957      fp = open(filename, "w")
3958      fp.write(ipdata)
3959      fp.close()
3960      logger.logit("di704.out file created")
3961    except:
3962      logline = "Failed accessing status page "
3963      logger.logexit(logline)
3964      sys.exit(-1)
3965
3966    # look for the first WAN Port in the log
3967    p1 = string.find(ipdata, "WAN")
3968
3969    if p1 != -1:
3970      ipmatch = Addressgrep.search(ipdata, p1)
3971      if ipmatch != None:
3972        localip = ipmatch.group()
3973        logger.logit("IP matched: " + localip)
3974
3975  elif opt_DI704_password:
3976    #
3977    # DI704 router ip detection
3978    #
3979    ipdir = DI704_page
3980
3981    #
3982    # determine the router host address
3983    #
3984    if routerIP:
3985      logger.logit("DI704_host set explicitly.")
3986      iphost = routerIP
3987    else:
3988      iphost = DefaultRoute(logger, Tempfile)
3989
3990    if iphost:
3991      logline = "Trying router at " + iphost
3992      logger.logit(logline)
3993    else:
3994      logger.logit("No router ip detected.  Assuming 192.168.0.1")
3995      iphost = "192.168.0.1"
3996
3997    logger.logit("Trying DI704")
3998
3999    try:
4000      logger.logit("Retrieving menu.htm...")
4001      ipurl = "http://" + iphost + "/menu.htm?RC=@"
4002      urlfp = urllib.urlopen(ipurl)
4003      menudata = urlfp.read()
4004      urlfp.close()
4005
4006      filename = "di704_menu.out"
4007      if opt_directory != "":
4008        filename = opt_directory + filename
4009      fp = open(filename, "w")
4010      fp.write(menudata)
4011      fp.close()
4012      logger.logit("di704menu.out file created")
4013    except:
4014      logline = "Failed while fetching menu.htm page "
4015      logger.logexit(logline)
4016      sys.exit(-1)
4017
4018    logline = "Parsing menu... "
4019    logger.logit("Parsing menu")
4020    menud = {}
4021    p1 = 0;
4022    p2 = 0;
4023    while 1:
4024      p1 = string.find(menudata, "VALUE=", p2)
4025      p2 = string.find(menudata, "NAME=", p1)
4026      if p1 == -1 or p2 == -1:
4027          break
4028      p3 = string.find(menudata, '"', p1)
4029      p4 = string.find(menudata, '"', p3 + 1)
4030      p5 = string.find(menudata, '>', p2)
4031      if p3 == -1 or p4 == -1 or p5 == -1:
4032          break
4033
4034      rhs = menudata[p3+1:p4]
4035      lhs = menudata[p2+6:p5]
4036
4037      logline = lhs + " = " + rhs
4038      logger.logit(logline)
4039      menud[lhs] = rhs
4040
4041    logger.logit("Adding password")
4042    menud["URL"] = opt_DI704_password
4043
4044    try:
4045      logger.logit("Try to post to form")
4046      params = urllib.urlencode( menud )
4047      ipurl = "http://" + iphost + "/cgi-bin/logi"
4048      logger.logit("urlopen " + ipurl)
4049      urlfp = urllib.urlopen(ipurl, params)
4050      logger.logit("urlfp.read")
4051      ipdata = urlfp.read()
4052      logger.logit("urlfp.close")
4053      urlfp.close()
4054      filename = "post.out"
4055      if opt_directory:
4056        filename = opt_directory + filename
4057      fp = open(filename, "w")
4058      fp.write(ipdata)
4059      fp.close()
4060      logger.logit("post.out file created")
4061    except:
4062      logline = "Failed to post password to login form"
4063      logger.logexit(logline)
4064      sys.exit(-1)
4065
4066    try:
4067      logger.logit("Now try to access status.htm now")
4068      ipurl = "http://" + iphost + "/status.htm"
4069      urlfp = urllib.urlopen(ipurl)
4070      ipdata = urlfp.read()
4071      urlfp.close()
4072
4073      filename = "di704.out"
4074      if opt_directory:
4075        filename = opt_directory + filename
4076      fp = open(filename, "w")
4077      fp.write(ipdata)
4078      fp.close()
4079      logger.logit("di704.out file created")
4080    except:
4081      logline = "Failed accessing status page "
4082      logger.logexit(logline)
4083      sys.exit(-1)
4084
4085    # look for the first WAN Port in the log
4086    p1 = string.find(ipdata, "IP Address")
4087
4088    if p1 != -1:
4089      ipmatch = Addressgrep.search(ipdata, p1)
4090      if ipmatch != None:
4091        localip = ipmatch.group()
4092        logger.logit("IP matched: " + localip)
4093
4094  elif opt_DI713P_password != "":
4095    #
4096    # DI713P router ip detection
4097    #
4098    # Tested with DI713P firmware 2.57 build 3a1
4099    # Based on DI704 code. The router appears to expect certain
4100    # values for the hidden variables {PSWD, KEY, htm} on the login page.
4101    # So we first get the values from the login page (menu.htm) then
4102    # feed them back via the POST
4103
4104    ipdir = DI713P_page
4105
4106    #
4107    # determine the router host address
4108    #
4109    if routerIP:
4110      logger.logit("DI713P_host set explicitly.")
4111      iphost = routerIP
4112    else:
4113      iphost = DefaultRoute(logger, Tempfile)
4114
4115    if iphost == "":
4116      logger.logit("No router ip detected.  Assuming 192.168.0.1")
4117      iphost = "192.168.0.1"
4118    else:
4119      logline = "Trying router at " + iphost
4120      logger.logit(logline)
4121
4122    logger.logit("Trying DI713P")
4123
4124    # fetch the menu page and retrieve the hidden values
4125    try:
4126      logger.logit("Retrieving menu.htm...")
4127      ipurl = "http://" + iphost + "/menu.htm"
4128      urlfp = urllib.urlopen(ipurl)
4129      ipdata = urlfp.read()
4130      urlfp.close()
4131
4132      filename = "di713P_menu.out"
4133      if opt_directory != "":
4134        filename = opt_directory + filename
4135      fp = open(filename, "w")
4136      fp.write(ipdata)
4137      fp.close()
4138      logger.logit("di713P_menu.out file created")
4139    except:
4140      logline = "Failed while fetching menu.htm page "
4141      logger.logexit(logline)
4142      sys.exit(-1)
4143
4144    # match for values of KEY, PSWD, htm
4145    di713P_logged_in = False  # default
4146    try:
4147      search_result = re.search('(")([^"]*)(") NAME=KEY', ipdata)
4148      if search_result == None: # If KEY not present then we are
4149        # already logged in. Don't do further string searching
4150        di713P_logged_in = True
4151      else:
4152        di713P_key = search_result.group(2)
4153        # logger.logit("KEY = " + di713P_key)
4154        search_result = re.search('(")([^"]*)(") NAME=PSWD', ipdata)
4155        di713P_pswd = search_result.group(2)
4156        # logger.logit("PSWD = " + di713P_pswd)
4157        search_result = re.search('(")([^"]*)(") NAME=htm', ipdata)
4158        di713P_htm = search_result.group(2)
4159        # logger.logit("htm = " + di713P_htm)
4160    except:
4161      logline = "Failed while matching for KEY, PSWD, htm page "
4162      logger.logexit(logline)
4163      sys.exit(-1)
4164
4165    if di713P_logged_in:
4166      logger.logit("Already logged in to the DLink gateway")
4167    else:
4168      try:
4169        logger.logit("POSTing to login form")
4170        # params = urllib.urlencode({'RC': '@D', 'ACCT': "root", 'PSWD': di713P_pswd, 'URL': opt_DI713P_password, 'KEY': di713P_key, 'htm': di713P_htm })
4171
4172        # The device seems to want the POST parameters in a specific
4173        # order. Unfortunately the order in the urlencode statement is
4174        # NOT carried through to the data packet (despite documentation to
4175        # the contrary. Sigh.) So we build up the data string a piece
4176        # at a time...
4177        params = urllib.urlencode({'RC':'@D'})
4178        params = params + "&" + urllib.urlencode({'ACCT':"root"})
4179        params = params + "&" + urllib.urlencode({'PSWD':di713P_pswd})
4180        params = params + "&" + urllib.urlencode({'URL':opt_DI713P_password})
4181        params = params + "&" + urllib.urlencode({'KEY':di713P_key})
4182        params = params + "&" + urllib.urlencode({'htm': di713P_htm})
4183
4184        ipurl = "http://" + iphost + "/cgi-bin/logi"
4185        # logger.logit("urlopen " + ipurl + " ["+params+"]")
4186        urlfp = urllib.urlopen(ipurl, params)
4187        logger.logit("urlfp.read")
4188        ipdata = urlfp.read()
4189        logger.logit("urlfp.close")
4190        urlfp.close()
4191        filename = "di713P_post.out"
4192        if opt_directory != "":
4193          filename = opt_directory + filename
4194        fp = open(filename, "w")
4195        fp.write(ipdata)
4196        fp.close()
4197        logger.logit("di713P_post.out file created")
4198      except:
4199        logline = "Failed to post password to login form"
4200        logger.logexit(logline)
4201        sys.exit(-1)
4202
4203    try:
4204      logger.logit("Fetching status.htm...")
4205      ipurl = "http://" + iphost + "/status.htm"
4206      urlfp = urllib.urlopen(ipurl)
4207      ipdata = urlfp.read()
4208      urlfp.close()
4209
4210      filename = "di713P_status.out"
4211      if opt_directory != "":
4212        filename = opt_directory + filename
4213      fp = open(filename, "w")
4214      fp.write(ipdata)
4215      fp.close()
4216      logger.logit("di713P_status.out file created")
4217    except:
4218      logline = "Failed to get status page "
4219      logger.logexit(logline)
4220      sys.exit(-1)
4221
4222    # look for the first WAN Port in the log
4223    p1 = string.find(ipdata, "IP Address")
4224
4225    if p1 != -1:
4226      ipmatch = Addressgrep.search(ipdata, p1)
4227      if ipmatch != None:
4228        localip = ipmatch.group()
4229        logger.logit("Success! Found IP address " + localip)
4230
4231  elif opt_DI804_password:
4232    #
4233    # DI804/DI-614+ router ip detection
4234    #
4235    ipdir = DI804_page
4236
4237    #
4238    # determine the router host address
4239    #
4240    if routerIP:
4241      logger.logit("DI804_host set explicitly.")
4242      iphost = routerIP
4243    else:
4244      iphost = DefaultRoute(logger, Tempfile)
4245
4246    if iphost:
4247      logline = "Trying router at " + iphost
4248      logger.logit(logline)
4249    else:
4250      logger.logit("No router ip detected.  Assuming 192.168.1.1")
4251      iphost = "192.168.1.1"
4252
4253    logger.logit("Trying DI804/DI-614+")
4254    filename = "di804.out"
4255    if opt_directory:
4256      filename = opt_directory + filename
4257    ipdata = BasicAuth(logger, iphost, DI804_page, DI804_user, opt_DI804_password, filename)
4258
4259    # look for the first WAN Port in the log
4260    p1 = string.find(ipdata, "Current IP")
4261
4262    if p1 != -1:
4263      ipmatch = Addressgrep.search(ipdata, p1)
4264      if ipmatch != None:
4265        localip = ipmatch.group()
4266        logger.logit("IP matched: " + localip)
4267    else:
4268      logger.logit("Trying DI614+")
4269      filename = "di614.out"
4270      if opt_directory:
4271        filename = opt_directory + filename
4272      ipdata = BasicAuth(logger, iphost, DI614_page, DI804_user, opt_DI804_password, filename)
4273      p1 = string.find(ipdata, "PPPoE")
4274      if p1 == -1:
4275        p1 = string.find(ipdata, "WAN")
4276      if p1 != -1:
4277        ipmatch = Addressgrep.search(ipdata, p1)
4278        if ipmatch != None:
4279          localip = ipmatch.group()
4280          logger.logit("IP matched: " + localip)
4281
4282  elif opt_DSL504_password:
4283    #
4284    # DSL504 router ip detection
4285    #
4286    ipdir = DSL504_page
4287
4288    #
4289    # determine the router host address
4290    #
4291    if routerIP:
4292      logger.logit("DSL504_host set explicitly.")
4293      iphost = routerIP
4294    else:
4295      iphost = DefaultRoute(logger, Tempfile)
4296
4297    if iphost:
4298      logline = "Trying router at " + iphost
4299      logger.logit(logline)
4300    else:
4301      logger.logit("No router ip detected.  Assuming 192.168.0.1")
4302      iphost = "192.168.0.1"
4303
4304    # connect to the router's admin webpage
4305    try:
4306      logger.logit("Trying DLink DSL504")
4307      tn = telnetlib.Telnet(iphost)
4308      logger.logit("Creating telnetlib obj done")
4309      tn.read_until("assword: ")
4310      #logger.logit("Password prompt found")
4311      tn.write(opt_DSL504_password + "\r")
4312      logger.logit("opt_DSL504_password sent")
4313      tn.read_until(">")
4314      tn.write("home\r\n")
4315      logger.logit("home command sent sent")
4316      tn.read_until(">")
4317      tn.write("nat interfaces\r\n")
4318      logger.logit("nat interfaces command sent")
4319      tn.read_until("ppp_device     Enabled               ", 2000)
4320      ip2 = tn.read_until(" ",2000)
4321      logger.logit("ip read")
4322      tn.write("@close\r\n")
4323      logger.logit("@close command sent")
4324      ipdata = ip2[:-1]
4325    except:
4326      logline = "No address found on router at " + iphost
4327      logger.logexit(logline)
4328      sys.exit(-1)
4329
4330    # create an output file of the response
4331    filename = "dsl504.out"
4332    if opt_directory:
4333      filename = opt_directory + filename
4334    open(filename, "w").write(ipdata)
4335    logger.logit("dsl504.out file created")
4336
4337    localip = ipdata
4338    logger.logit("IP matched: " + localip)
4339
4340
4341  elif opt_Linksys_router != 0:
4342    #
4343    # Linksys router ip detection
4344    #
4345    ipdir = Linksys_page
4346
4347    #
4348    # determine the linksys router host address
4349    #
4350    iphost = ""
4351    if routerIP:
4352      logger.logit("Linksys_host set explicitly.")
4353      iphost = routerIP
4354    else:
4355      iphost = DefaultRoute(logger, Tempfile)
4356
4357    if iphost == "":
4358      logger.logit("No router ip detected.  Assuming 192.168.1.1")
4359      iphost = "192.168.1.1"
4360    else:
4361      logline = "Trying linksys router at " + iphost
4362      logger.logit(logline)
4363
4364    # connect to the router's admin webpage
4365    try:
4366      logger.logit("Trying Linksys")
4367      h1 = httplib.HTTP(iphost)
4368
4369      #
4370      # Hack from Bobby Griggs for authorization.
4371      #
4372      # For some reason the router won't authenticate when
4373      # using standard headers for authorization.  Like this:
4374      #
4375      #h1.putrequest('GET', ipdir)
4376      #authstring = base64.encodestring(Linksys_user + ":" + opt_Linksys_password)
4377      #h1.putheader("Authorization", "Basic " + authstring)
4378      #
4379      # It may be looking for lines that end with just \n not \r\n.
4380      #
4381      # Note:  Modified by Greg Bentz.
4382      #        Linksys firmware 1.37, doesn't like the trailing \n on the authstring.
4383      #        Also requires "\r\n".
4384      #        My theory concerning the standard headers is that the Linksys header
4385      #        parsing requires all the header info to appear in one packet.
4386      #        Use of an extra putheader() call puts the authorization information into
4387      #        a second packet which is not read by the Linksys device.
4388      #
4389      authstring = base64.encodestring(Linksys_user + ":" + opt_Linksys_password)
4390      authstring = string.replace(authstring, "\012", "")
4391      ipdir = Linksys_page + ' HTTP/1.1 \r\n' \
4392        + 'Authorization: Basic ' \
4393        + authstring + '\r\n'
4394      h1.putrequest('GET', ipdir)
4395
4396      h1.endheaders()
4397
4398      errcode, errmsg, headers = h1.getreply()
4399      fp = h1.getfile()
4400      ipdata = fp.read()
4401      fp.close()
4402    except:
4403      logline = "No address found on router at " + iphost
4404      logger.logexit(logline)
4405      sys.exit(-1)
4406
4407
4408    #
4409    # replacing findall to support older python 1.5.1 sites
4410    #
4411    #ipmatch = Addressgrep.findall(ipdata)
4412    #if ipmatch != None:
4413    #  if len(ipmatch) > 2:
4414    #    localip = ipmatch[2]
4415
4416    p1 = string.find(ipdata, "WAN")
4417    if p1 != -1:
4418      p2 = string.find(ipdata, "IP", p1)
4419      if p2 != -1:
4420        ipmatch = Addressgrep.search(ipdata, p2)
4421        if ipmatch != None:
4422          localip = ipmatch.group()
4423          logger.logit("IP matched: " + localip)
4424
4425    if localip == "":
4426      try:
4427        logger.logit("Trying Linksys")
4428        h1 = httplib.HTTP(iphost)
4429        authstring = base64.encodestring(Linksys_user + ":" + opt_Linksys_password)
4430        authstring = string.replace(authstring, "\012", "")
4431        ipdir = "/Status_Router.htm" + ' HTTP/1.1 \r\n' \
4432          + 'Authorization: Basic ' \
4433          + authstring + '\r\n'
4434        h1.putrequest('GET', ipdir)
4435        h1.endheaders()
4436        errcode, errmsg, headers = h1.getreply()
4437        fp = h1.getfile()
4438        ipdata = fp.read()
4439        fp.close()
4440      except:
4441        logline = "No address found on router at " + iphost
4442        logger.logexit(logline)
4443        sys.exit(-1)
4444
4445      p1 = string.find(ipdata, "Internet IP")
4446      if p1 != -1:
4447        ipmatch = Addressgrep.search(ipdata, p1)
4448        if ipmatch != None:
4449          localip = ipmatch.group()
4450          logger.logit("IP matched: " + localip)
4451
4452
4453    # Support for Linksys WRT54G Wireless Router
4454    # Modified by David Bresson
4455
4456    if localip == "":
4457      try:
4458        logger.logit("Trying Linksys")
4459        h1 = httplib.HTTP(iphost)
4460        authstring = base64.encodestring(Linksys_user + ":" + opt_Linksys_password)
4461        authstring = string.replace(authstring, "\012", "")
4462        ipdir = "/Status_Router.asp" + ' HTTP/1.1 \r\n' \
4463          + 'Authorization: Basic ' \
4464          + authstring + '\r\n'
4465        h1.putrequest('GET', ipdir)
4466        h1.endheaders()
4467        errcode, errmsg, headers = h1.getreply()
4468        fp = h1.getfile()
4469        ipdata = fp.read()
4470        fp.close()
4471      except:
4472        logline = "No address found on router at " + iphost
4473        logger.logexit(logline)
4474        sys.exit(-1)
4475
4476      p1 = string.find(ipdata, "wan_ip = ")
4477      if p1 != -1:
4478        ipmatch = Addressgrep.search(ipdata, p1)
4479        if ipmatch != None:
4480          localip = ipmatch.group()
4481          logger.logit("IP matched: " + localip)
4482
4483
4484    # Support for Linksys RT31P2 Vonage VoIP Gateway Router
4485    # Default IP is 192.168.15.1.  Could support that later.
4486    if localip == "":
4487      try:
4488        logger.logit("Trying Linksys RT31P2")
4489        h1 = httplib.HTTP(iphost)
4490        authstring = base64.encodestring(Linksys_user + ":" + opt_Linksys_password)
4491        authstring = string.replace(authstring, "\012", "")
4492        ipdir = "/RouterStatus.htm" + ' HTTP/1.1 \r\n' \
4493          + 'Authorization: Basic ' \
4494          + authstring + '\r\n'
4495        h1.putrequest('GET', ipdir)
4496        h1.endheaders()
4497        errcode, errmsg, headers = h1.getreply()
4498        fp = h1.getfile()
4499        ipdata = fp.read()
4500        fp.close()
4501      except:
4502        logline = "No address found on router at " + iphost
4503        logger.logexit(logline)
4504        sys.exit(-1)
4505
4506      p1 = string.find(ipdata, "Internet IP")
4507      if p1 != -1:
4508        ipmatch = Addressgrep.search(ipdata, p1)
4509        if ipmatch != None:
4510          localip = ipmatch.group()
4511          logger.logit("IP matched: " + localip)
4512
4513    # create an output file of the linksys response
4514    filename = "linksys.out"
4515    if opt_directory != "":
4516      filename = opt_directory + filename
4517    fp = open(filename, "w")
4518    fp.write(ipdata)
4519    fp.close()
4520    logger.logit("linksys.out file created")
4521
4522
4523
4524
4525
4526  elif opt_Watchguard_password:
4527    #
4528    # Watchguard firewall/router ip detection
4529    #
4530    ipdir = Watchguard_page
4531
4532    #
4533    # determine the watchguard soho router host address
4534    #
4535    if routerIP:
4536      logger.logit("Watchguard_host set explicitly.")
4537      iphost = routerIP
4538    else:
4539      iphost = DefaultRoute(logger, Tempfile)
4540
4541    if iphost:
4542      logline = "Trying Watchguard SOHO firewall at " + iphost
4543      logger.logit(logline)
4544    else:
4545      logger.logit("No router ip detected.  Assuming 192.168.111.1")
4546      iphost = "192.168.111.1"
4547
4548    # connect to the router's admin webpage
4549    try:
4550      logger.logit("Trying Watchguard")
4551      h1 = httplib.HTTP(iphost)
4552
4553      authstring = base64.encodestring(Watchguard_user + ":" + opt_Watchguard_password)
4554      authstring = string.replace(authstring, "\012", "")
4555      ipdir = Watchguard_page + ' \r\n' \
4556        + 'Authorization: Basic ' \
4557        + authstring + '\r\n'
4558      h1.putrequest('GET', ipdir)
4559      h1.putheader("AUTHORIZATION", "Basic " + authstring)
4560
4561      h1.endheaders()
4562
4563      errcode, errmsg, headers = h1.getreply()
4564      fp = h1.getfile()
4565      ipdata = fp.read()
4566      fp.close()
4567    except:
4568      logline = "No address found on router at " + iphost
4569      logger.logexit(logline)
4570      sys.exit(-1)
4571
4572    ipmatch = Addressgrep.search(ipdata)
4573    if ipmatch != None:
4574      localip = ipmatch.group()
4575      logger.logit("IP matched: " + localip)
4576    else:
4577      logger.logit("Trying Watchguard new firmware")
4578      h1 = httplib.HTTP(iphost)
4579
4580      authstring = base64.encodestring(Watchguard_user + ":" + opt_Watchguard_password)
4581      authstring = string.replace(authstring, "\012", "")
4582      ipdir = Watchguard_page2 + ' \r\n' \
4583        + 'Authorization: Basic ' \
4584        + authstring + '\r\n'
4585      h1.putrequest('GET', ipdir)
4586      h1.putheader("AUTHORIZATION", "Basic " + authstring)
4587      h1.endheaders()
4588
4589      errcode, errmsg, headers = h1.getreply()
4590      fp = h1.getfile()
4591      ipdata = fp.read()
4592      fp.close()
4593
4594    # create an output file of the watchguard response
4595    filename = "watchguard.out"
4596    if opt_directory:
4597      filename = opt_directory + filename
4598    fp = open(filename, "w")
4599    fp.write(ipdata)
4600    fp.close()
4601    logger.logit("watchguard.out file created")
4602
4603    ipmatch = Addressgrep.search(ipdata)
4604    if ipmatch != None:
4605      localip = ipmatch.group()
4606      logger.logit("IP matched: " + localip)
4607
4608  elif opt_DI701_password:
4609
4610    #
4611    # determine the router host address
4612    #
4613    if routerIP:
4614      logger.logit("DI701_host set explicitly.")
4615      iphost = routerIP
4616    else:
4617      iphost = DefaultRoute(logger, Tempfile)
4618
4619    if iphost:
4620      logline = "Trying router at " + iphost
4621      logger.logit(logline)
4622    else:
4623      logger.logit("No router ip detected.  Assuming 192.168.1.1")
4624      iphost = "192.168.1.1"
4625
4626    # connect to the router's admin webpage
4627    try:
4628      logger.logit("Trying DLink DI701")
4629      tn = telnetlib.Telnet(iphost,333)
4630      logger.logit("Creating telnetlib obj done")
4631      tn.read_until("assword : ")
4632      logger.logit("Password prompt found")
4633      tn.write(opt_DI701_password + "\r")
4634      logger.logit("opt_DI701_password sent")
4635      tn.read_until("command>")
4636      tn.write("show\r")
4637      logger.logit("show command sent")
4638      tn.read_until("address of global port : [", 2000)
4639      ip2 = tn.read_until("]", 2000)
4640      logger.logit("ip read")
4641      #tn.write("exit\r\n")
4642      #logger.logit("exit sent")
4643      ipdata = ip2[:-1]
4644    except:
4645      logline = "No address found on router at " + iphost
4646      logger.logexit(logline)
4647      sys.exit(-1)
4648
4649    # create an output file of the response
4650    filename = "di701.out"
4651    if opt_directory:
4652      filename = opt_directory + filename
4653    open(filename, "w").write(ipdata)
4654    logger.logit("di701.out file created")
4655
4656    localip = ipdata
4657    logger.logit("IP matched: " + localip)
4658
4659  elif opt_AlcatelSTP_password:
4660
4661    #
4662    # determine the router host address
4663    #
4664    if routerIP:
4665      logger.logit("AlcatelSTP_host set explicitly.")
4666      iphost = routerIP
4667    else:
4668      iphost = DefaultRoute(logger, Tempfile)
4669
4670    if iphost:
4671      logline = "Trying router at " + iphost
4672      logger.logit(logline)
4673    else:
4674      logger.logit("No router ip detected.  Assuming 10.0.0.138")
4675      iphost = "10.0.0.138"
4676
4677    # connect to the router's admin webpage
4678    try:
4679      logger.logit("Trying Alcatel STP")
4680      # disables negotiation to prevent the connection being dropped
4681      telnetlib.IAC="\021"
4682      tn = telnetlib.Telnet(iphost)
4683      logger.logit("Creating telnetlib obj done")
4684      tn.read_until(" : ")
4685      logger.logit("User prompt found")
4686      tn.write(Alcatel_user + "\r")
4687      tn.write(opt_AlcatelSTP_password + "\r")
4688      logger.logit("opt_AlcatelSTP_password sent")
4689      tn.read_until("=>")
4690      tn.write("ip aplist\r")
4691      logger.logit("ip aplist sent")
4692      ret=tn.read_until("SERIAL",5)
4693      if string.find(ret,"SERIAL")==-1:
4694        # is an Alcatel version 4.3.2.6 ?
4695        tn.write("\r")
4696        tn.read_until("=>")
4697        tn.write("ip iplist\r")
4698        logger.logit("ip iplist sent")
4699        ret=tn.read_until("Serial          ",5)
4700        if string.find(ret,"Serial          ")==-1:
4701           raise "not connected"
4702      else:
4703        tn.read_until("addr:")
4704      ip2 = tn.read_until(" ")
4705      logger.logit("ip read")
4706      ipdata = ip2[:-1]
4707      if len(opt_forward) != 0:
4708        for opt_forwardportprotocol in opt_forward:
4709          tn.read_until("=>")
4710          logline="nat create protocol=%s inside_addr=%s inside_port=%s outside_addr=%s outside_port=%s "
4711          logline=logline % ( opt_forwardportprotocol[1], tn.sock.getsockname()[0],
4712            opt_forwardportprotocol[0], ipdata, opt_forwardportprotocol[0] )
4713          tn.write(logline+"\r")
4714          logger.logit(logline)
4715          tn.read_until(logline)
4716        tn.read_until("=>")
4717      # no exit needed
4718      tn.close()
4719    except:
4720      logline = "No address found on router at " + iphost
4721      logger.logexit(logline)
4722      sys.exit(-1)
4723
4724    # create an output file of the response
4725    filename = "alcatel_stp.out"
4726    if opt_directory:
4727      filename = opt_directory + filename
4728    open(filename, "w").write(ipdata)
4729    logger.logit("alcatel_stp.out file created")
4730
4731    localip = ipdata
4732    logger.logit("IP matched: " + localip)
4733
4734  elif opt_router:
4735    logger.logit("web based ip detection for localip")
4736    ipurl = ""
4737
4738    # check for deprecated url
4739    if string.find(opt_router, "cgi-bin/check_ip.cgi") != -1:
4740      logger.logexit("You should be using -r checkip.dyndns.org ")
4741      logger.logexit("Continuing with new URL.")
4742      opt_router = "checkip.dyndns.org:8245"
4743
4744    # strip off the http part, if any
4745    if opt_router[:7] == "HTTP://" or opt_router[:7] == "http://":
4746      ipurl = opt_router[7:]
4747    else:
4748      ipurl = opt_router
4749
4750    # stick it back on for urllib usage
4751    ipurl = "http://" + ipurl
4752
4753    # grab the data
4754    try:
4755      logger.logit("Trying URL " + ipurl)
4756      urlfp = urllib.urlopen(ipurl)
4757      ipdata = urlfp.read()
4758      urlfp.close()
4759    except:
4760      logline = "Unable to open url " + ipurl
4761      logger.logexit(logline)
4762      logger.logexit("Exception: " + `sys.exc_info()[0]`)
4763      sys.exit(-1)
4764
4765
4766    # create an output file of the ip detection response
4767    filename = "webip.out"
4768    if opt_directory:
4769      filename = opt_directory + filename
4770    fp = open(filename, "w")
4771    fp.write(ipdata)
4772    fp.close()
4773    logger.logit("webip.out file created")
4774
4775    # grab first thing that looks like an IP address
4776    ipmatch = Addressgrep.search(ipdata)
4777    if ipmatch != None:
4778      localip = ipmatch.group()
4779      logger.logit("webip detected = " + localip)
4780
4781  else:
4782    logger.logit("Interface ip detection on sys.platform = " + sys.platform)
4783    if sys.platform == "win32":
4784      logger.logit("win32 interface ip detection for localip")
4785      getip = Win32ip
4786      os.system (getip + " > " + Tempfile)
4787      fp = open(Tempfile, "r")
4788      ipdata = fp.read()
4789      fp.close()
4790      # grab the first dotted quad after the interface
4791      p1 = string.find(ipdata, opt_interface)
4792      if p1 != -1:
4793        ipmatch = Addressgrep.search(ipdata, p1)
4794        if ipmatch != None:
4795          localip = ipmatch.group()
4796          logger.logit("IP matched: " + localip)
4797
4798    elif string.find(sys.platform, "sunos") != -1:
4799      logger.logit("Sunos interface ip detection for localip (untested)")
4800      fp = os.popen(Sunip + " " + opt_interface, "r")
4801      ipdata = fp.read()
4802      fp.close()
4803      # grab the first dotted quad after the interface
4804      p1 = string.find(ipdata, opt_interface)
4805      if p1 != -1:
4806        ipmatch = Addressgrep.search(ipdata, p1)
4807        if ipmatch != None:
4808          localip = ipmatch.group()
4809          logger.logit("IP matched: " + localip)
4810
4811    elif string.find(sys.platform, "linux") != -1:
4812      logger.logit("linux interface ip detection for localip")
4813      fp = os.popen(Linuxip + " " + opt_interface, "r")
4814      ipdata = fp.read()
4815      fp.close()
4816      # grab the first dotted quad after the interface
4817      p1 = string.find(ipdata, opt_interface)
4818      if p1 != -1:
4819        ipmatch = Addressgrep.search(ipdata, p1)
4820        if ipmatch != None:
4821          localip = ipmatch.group()
4822          logger.logit("IP matched: " + localip)
4823
4824    elif string.find(sys.platform, "Darwin") != -1:
4825      logger.logit("Darwin interface ip detection for localip")
4826      fp = os.popen(Macip + " " + opt_interface , "r")
4827      ipdata = fp.read()
4828      fp.close()
4829      # grab the first dotted quad after the LAST inet (to avoid dead routes)
4830      p1 = string.rfind(ipdata, "inet ")
4831      if p1 != -1:
4832        ipmatch = Addressgrep.search(ipdata, p1)
4833        if ipmatch != None:
4834          localip = ipmatch.group()
4835          logger.logit("IP matched: " + localip)
4836
4837    elif string.find(sys.platform, "os2") != -1:
4838      logger.logit("OS2 interface ip detection for localip")
4839      getip = Os2ip + " " + opt_interface
4840      os.system (getip + " > " + Tempfile)
4841      fp = open(Tempfile, "r")
4842      ipdata = fp.read()
4843      fp.close()
4844      # grab the first dotted quad after the LAST inet (to avoid dead routes)
4845      p1 = string.rfind(ipdata, "inet ")
4846      if p1 != -1:
4847        ipmatch = Addressgrep.search(ipdata, p1)
4848        if ipmatch != None:
4849          localip = ipmatch.group()
4850          logger.logit("IP matched: " + localip)
4851
4852    elif string.find(sys.platform, "beos") != -1:
4853      logger.logit("BeOS interface ip detection for localip")
4854      getip = Beosip
4855      os.system (getip + " > " + Tempfile)
4856      fp = open(Tempfile, "r")
4857      ipdata = fp.read()
4858      fp.close()
4859      # grab the first dotted quad after interface text
4860      p1 = string.rfind(ipdata, opt_interface + ":")
4861      if p1 != -1:
4862        ipmatch = Addressgrep.search(ipdata, p1)
4863        if ipmatch != None:
4864          localip = ipmatch.group()
4865          logger.logit("IP matched: " + localip)
4866
4867    elif string.find(sys.platform, "bsd") != -1:
4868      logger.logit("*BSD* interface ip detection for localip")
4869      fp = os.popen(BSDip + " " + opt_interface + " | grep -v 192.168 ", "r")
4870      ipdata = fp.read()
4871      fp.close()
4872      # grab the first dotted quad after the LAST inet (to avoid dead routes)
4873      p1 = string.rfind(ipdata, "inet ")
4874      if p1 != -1:
4875        ipmatch = Addressgrep.search(ipdata, p1)
4876        if ipmatch != None:
4877          localip = ipmatch.group()
4878          logger.logit("IP matched: " + localip)
4879
4880    elif string.find(sys.platform, "sco_") != -1:
4881      logger.logit("SCO interface ip detection for localip")
4882      getip = Scoip + " " + opt_interface
4883      os.system (getip + " > " + Tempfile)
4884      fp = open(Tempfile, "r")
4885      ipdata = fp.read()
4886      fp.close()
4887      # grab the first dotted quad after the LAST inet (to avoid dead routes)
4888      p1 = string.rfind(ipdata, "inet ")
4889      if p1 != -1:
4890        ipmatch = Addressgrep.search(ipdata, p1)
4891        if ipmatch != None:
4892          localip = ipmatch.group()
4893          logger.logit("IP matched: " + localip)
4894
4895    else:
4896      logger.logit("Default interface ip detection for localip (untested)")
4897      getip = Otherip + " " + opt_interface
4898      os.system (getip + " > " + Tempfile)
4899      fp = open(Tempfile, "r")
4900      ipdata = fp.read()
4901      fp.close()
4902      # grab the first dotted quad after the LAST inet (to avoid dead routes)
4903      p1 = string.rfind(ipdata, "inet ")
4904      if p1 != -1:
4905        ipmatch = Addressgrep.search(ipdata, p1)
4906        if ipmatch != None:
4907          localip = ipmatch.group()
4908          logger.logit("IP matched: " + localip)
4909
4910    # check if we have a localip from all the above elifs
4911    if not localip:
4912      logline = "No address found on interface " + opt_interface + " use -i"
4913      logger.logexit(logline)
4914      sys.exit(-1)
4915
4916
4917  # end of all determining localip cases
4918  logline = check_ip(localip)
4919  if logline:
4920    logger.logexit(logline)
4921    sys.exit(-1)
4922
4923  #
4924  # create the dat file from dns lookup if specified
4925  #
4926  if opt_makedat:
4927    logger.logit("DNS lookups to create data file.")
4928
4929    if datfile.exists():
4930      logger.logexit("There is already an ipcheck.dat file existing.")
4931      logger.logexit("Remove this file first before running --makedat")
4932      sys.exit(0)
4933    else:
4934      logger.logit("Good, no ipcheck.dat file found.")
4935
4936    ip1 = ""
4937    ip2 = ""
4938    h = ""
4939    try:
4940      for h in hostnames:
4941        if string.find(h, "recursivedns.com") != 0:
4942          logger.logit("detected recursivedns.com host")
4943          logger.logit("setting opt_force and skipping of dns lookup")
4944          opt_force = 1
4945          ip1 = "99.99.99.99"
4946          break
4947
4948        if not ip1:
4949          logger.logexit("ip1 looking up " + h)
4950          (a, b, c) = socket.gethostbyname_ex(h)
4951          line = `a` + `b` + `c`
4952          logger.logexit("result: " + line)
4953          ip1 = c[0]
4954          logger.logit("ip1 = " + ip1)
4955          ip2 = ip1
4956        else:
4957          logger.logexit("ip2 looking up " + h)
4958          (a, b, c) = socket.gethostbyname_ex(h)
4959          line = `a` + `b` + `c`
4960          logger.logexit("result: " + line)
4961          ip2 = c[0]
4962          logger.logit("ip2 = " + ip2)
4963
4964        # check if not same
4965        if ip1 != ip2:
4966          logger.logexit("WARNING: hostnames have different ips.")
4967          logger.logexit("I'm going to set the force option so all hosts")
4968          logger.logexit("will be synchronized to the same IP address.")
4969          opt_force = 1
4970
4971    except:
4972      logger.logexit("Problems looking up hostname " + h)
4973      logger.logexit("Make sure the hostname is correct, is setup at Dyndns,")
4974      logger.logexit("and that local DNS lookups are working fine.")
4975      logger.logexit("Exception: " + `sys.exc_info()[0]`)
4976      sys.exit(-1)
4977
4978
4979    logger.logit("Writing the new dat file.")
4980    datfile.write(ip1, hostnames)
4981
4982  #
4983  # read the data from file of last update, if any
4984  #
4985  if datfile.exists():
4986    (fileip, filehosts) = datfile.read()
4987    fileage = datfile.getAge()
4988  else:
4989    # do not create the file automatically cause people could get
4990    # into loops and use up a lot of bandwidth doing dns lookup
4991    logger.logexit("No ipcheck.dat file found.")
4992    logger.logexit("Use same command+options ONCE with --makedat to create from DNS lookup.")
4993    sys.exit(0)
4994
4995  dnslookupip = ""
4996  if opt_checkDNS:
4997    ip2 = ""
4998    h = ""
4999    try:
5000      for h in hostnames:
5001        if not dnslookupip:
5002          logger.logexit("dnslookupip looking up " + h)
5003          (a, b, c) = socket.gethostbyname_ex(h)
5004          line = `a` + `b` + `c`
5005          logger.logexit("result: " + line)
5006          dnslookupip = c[0]
5007          logger.logit("dnslookupip = " + dnslookupip)
5008          ip2 = dnslookupip
5009        else:
5010          logger.logexit("ip2 looking up " + h)
5011          (a, b, c) = socket.gethostbyname_ex(h)
5012          line = `a` + `b` + `c`
5013          logger.logexit("result: " + line)
5014          ip2 = c[0]
5015          logger.logit("ip2 = " + ip2)
5016
5017        # check if not same
5018        if dnslookupip != ip2:
5019          logger.logexit("WARNING: hostnames have different ips.")
5020          logger.logexit("I'm going to set the force option so all hosts")
5021          logger.logexit("will be synchronized to the same IP address.")
5022          opt_force = 1
5023
5024    except:
5025      logger.logexit("Problems looking up hostname " + h)
5026      logger.logexit("Make sure the hostname is correct, is setup at Dyndns,")
5027      logger.logexit("and that local DNS lookups are working fine.")
5028      logger.logexit("Exception: " + `sys.exc_info()[0]`)
5029      sys.exit(-1)
5030
5031  #
5032  # check filehosts list versus hostnames list
5033  #
5034  mismatch = 0
5035  for h in filehosts:
5036    if h not in hostnames:
5037      mismatch = 1
5038  for h in hostnames:
5039    if h not in filehosts:
5040      mismatch = 1
5041  if not mismatch:
5042    logger.logit("Good, filehosts and hostnames are the same.")
5043  else:
5044    # do not create the file automatically cause people could get
5045    # into loops and use up a lot of bandwidth doing dns lookup
5046    logger.logexit("The hostnames listed do not match the ipcheck.dat file.")
5047    logger.logexit("Remove the dat file and use same command ONCE with --makedat.")
5048    logger.logexit("Note that if you are maintaining both a custom domain and")
5049    logger.logexit("a dyndns domain, you should be using the -d option and")
5050    logger.logexit("keeing the data files in separate directories.")
5051    sys.exit(0)
5052
5053
5054
5055  #
5056  # read the data from error file, if any
5057  #
5058  if not errfile.exists():
5059    logger.logit("Good, no ipcheck.err file.")
5060  elif not opt_force:
5061    logger.logit("Handling errors in ipcheck.err file.")
5062    fatal = errfile.analyze(opt_username,opt_password,hostnames)
5063    if fatal:
5064      sys.exit(-1)
5065  #
5066  # read the data from wait file, if any
5067  #
5068  waitcode = ""
5069  waitdate = ""
5070  try:
5071    fp = open (Waitfile, "r")
5072    waitcode = fp.readline()
5073    if waitcode[-1] == "\n":
5074      waitcode = waitcode[:-1]
5075    waitdate = fp.readline()
5076    if waitdate[-1] == "\n":
5077      waitdate = waitdate[:-1]
5078    fp.close()
5079  except:
5080    logger.logit("Good, no ipcheck.wait file.")
5081
5082  if waitcode and not opt_force:
5083
5084    logger.logit("Found wait entry.")
5085    logger.logit(waitcode)
5086    logger.logit(waitdate)
5087
5088    #
5089    # first line is the code
5090    # second line is time.time() when the code was received
5091    # now determine whether we should continue or abort
5092    # remove the file if the wait is no longer needed
5093    #
5094    try:
5095      waitnum = float(waitdate)
5096    except:
5097      waitnum = 0.0
5098
5099    if waitnum == 0.0:
5100      logger.logit("Invalid wait date in ipcheck.wait file.")
5101      logger.logit("ipcheck.wait file removed and continuing.")
5102      os.unlink (Waitfile)
5103
5104    elif waitcode[0] == 'u':
5105      # wait until GMT
5106      logger.logit("Decoding wait until entry in ipcheck.wait file.")
5107
5108      # First we check the age of the file.
5109      currtime = time.time()
5110      mtime = os.stat(Waitfile)[stat.ST_MTIME]
5111      if (currtime - mtime) / (60*60) > 24:
5112        # the file is older than 24 hours and should be ignored
5113        logger.logit("Stale ipcheck.wait file removed and continuing.")
5114        os.unlink (Waitfile)
5115      elif (currtime - waitnum) / (60*60) > 24:
5116        # the code is older than 24 hours and should be ignored
5117        logger.logit("Stale code in file removed and continuing.")
5118        os.unlink (Waitfile)
5119      else:
5120        try:
5121          waitsec = int(waitcode[2:])
5122        except:
5123          waitsec = 0
5124
5125        currtime = time.time()
5126        if currtime > waitnum + waitsec:
5127          logger.logit("until wait entry expired.")
5128          logger.logit("ipcheck.wait file removed and continuing.")
5129          os.unlink (Waitfile)
5130        else:
5131          logger.logit("until wait entry in effect: quietly aborting.")
5132          sys.exit(-1)
5133
5134    else:
5135      # wait h, m or s
5136      logger.logit("Decoding hms entry in ipcheck.wait file.")
5137      try:
5138        waitsec = int(waitcode[1:3])
5139        if waitcode[3] == 'h' or waitcode[3] == 'H':
5140          waitsec = waitsec * 60 * 60
5141        elif waitcode[3] == 'm' or waitcode[3] == 'M':
5142          waitsec = waitsec * 60
5143      except:
5144        waitsec = 0
5145
5146      currtime = time.time()
5147      if currtime > waitnum + waitsec:
5148        logger.logit("hms wait entry expired.")
5149        logger.logit("ipcheck.wait file removed and continuing.")
5150        os.unlink (Waitfile)
5151      else:
5152        logger.logit("hms wait entry in effect: quietly aborting.")
5153        sys.exit(-1)
5154
5155  #
5156  # determine whether and which hosts need updating
5157  #
5158  updatehosts = []
5159
5160  # if opt_force is set then update all hosts
5161  # or offline mode selected
5162  if opt_force or opt_offline:
5163    logger.logit("Updates forced by -f option.")
5164    for host in hostnames:
5165      updatehosts.append(host)
5166
5167  # else if file age is older than update all hosts
5168  # Touchage == 0 means don't update
5169  elif fileage > Touchage and Touchage > 0:
5170    logger.logit("Updates required by stale ipcheck.dat file.")
5171    for host in hostnames:
5172      updatehosts.append(host)
5173
5174  # else check the address from dns lookup
5175  elif opt_checkDNS and localip != dnslookupip:
5176    logger.logit("Updates required by ip lookup address mismatch.")
5177    logger.logit("localip = " + localip + " dnslookupip = " + dnslookupip)
5178    for host in hostnames:
5179      updatehosts.append(host)
5180
5181  # else check the address used in last update
5182  elif localip != fileip:
5183    logger.logit("Updates required by ipcheck.dat address mismatch.")
5184    for host in hostnames:
5185      updatehosts.append(host)
5186
5187  # This case is probably deprecated but will leave it in
5188  # case I missed something.  When reading the dat file,
5189  # I'm going to now only proceed if hostnames == filehosts.
5190  # Otherwise, a message will be printed out and an option
5191  # to create a dat file from dns lookups will be recommended.
5192
5193  else:
5194    logger.logit("Checking hosts in file vs command line.")
5195    updateflag = 0
5196    for host in hostnames:
5197      if host not in filehosts:
5198        updateflag = 1
5199
5200    # If anyone of the hosts on the command line needs updating,
5201    # put them all in the updatehosts list so they will get the
5202    # same last updated timestamp at dyndns.  This way they all
5203    # won't need to be touched again for Touchage days, instead
5204    # of having multiple touches for different last updated dates.
5205    if updateflag:
5206      for host in hostnames:
5207        updatehosts.append(host)
5208
5209  if updatehosts == []:
5210    # Quietly log this message then exit too.
5211    logger.logit("The database matches local address.  No hosts update.")
5212    sys.exit(0)
5213
5214  #
5215  # build the query strings
5216  #
5217  updateprefix = Updatepage
5218  if opt_static:
5219    updateprefix = updateprefix + "?system=statdns&hostname="
5220  elif opt_custom:
5221    updateprefix = updateprefix + "?system=custom&hostname="
5222  else:
5223    updateprefix = updateprefix + "?system=dyndns&hostname="
5224
5225  hostlist = ""
5226  for host in updatehosts:
5227    hostlist = hostlist + host + ","
5228    logger.logit(host + " needs updating")
5229  if len(hostlist) > 0:
5230    hostlist = hostlist[:-1]
5231
5232  if opt_offline:
5233    if opt_static:
5234      logger.logexit("offline and static mode not allowed together.")
5235      sys.exit(-1)
5236
5237  updatesuffix = ""
5238  if opt_offline:
5239    #updatesuffix = updatesuffix + "&myip=1.0.0.0"
5240    updatesuffix = updatesuffix + "&offline=YES"
5241  else:
5242    # only do these other things if not setting offline mode
5243    if opt_guess:
5244      logger.logit("Letting dyndns guess the IP.")
5245      localip = ""
5246    else:
5247      updatesuffix = updatesuffix + "&myip=" + localip
5248
5249    # custom domains do not have wildcard or mx records
5250    if not opt_custom:
5251
5252      if opt_wildcard != "":
5253        updatesuffix = updatesuffix + "&wildcard=" + opt_wildcard
5254      else:
5255        updatesuffix = updatesuffix + "&wildcard=OFF"
5256
5257      if opt_backupmx != "":
5258        updatesuffix = updatesuffix + "&backmx=" + opt_backupmx
5259      else:
5260        updatesuffix = updatesuffix + "&backmx=NO"
5261
5262      if opt_mxhost:
5263        updatesuffix = updatesuffix + "&mx=" + opt_mxhost
5264
5265  logger.logit("Prefix = " + updateprefix)
5266  logger.logit("Hosts  = " + hostlist)
5267  logger.logit("Suffix = " + updatesuffix)
5268
5269  if opt_testrun:
5270    logger.logit("test run exits here")
5271    sys.exit()
5272
5273  #
5274  # check which version of python we are using
5275  #
5276  # apache2 ssl returns EOF too soon for python2's ssl library
5277  # and causes an exception.  apache1 with mod_ssl worked fine.
5278  # Python 1.5.x works fine also.
5279  #
5280  for py_ver in ["2.2", "2.1"]:
5281    python2 = string.find(sys.version, py_ver)
5282    if python2 == 0:
5283      logger.logit("Using python " + py_ver +", https disabled")
5284      opt_no_https = 1
5285
5286  #
5287  # update those hosts
5288  #
5289  if not opt_no_https:
5290    logline = "trying to open HTTPS connection"
5291    logger.logit(logline)
5292    try:
5293      if not opt_proxy:
5294        h2 = httplib.HTTPS(Updatehost)
5295        logline = "HTTPS connection successful"
5296        logger.logit(logline)
5297      else:
5298        h2 = httplib.HTTPS(Updatehost, 8245)
5299        logline = "HTTPS connection successful"
5300        logger.logit(logline)
5301    except:
5302      logline = "trying to open normal HTTP connection"
5303      logger.logit(logline)
5304      if not opt_proxy:
5305        h2 = httplib.HTTP(Updatehost)
5306        logline = "normal HTTP connection successful"
5307        logger.logit(logline)
5308      else:
5309        h2 = httplib.HTTP(Updatehost, 8245)
5310        logline = "normal HTTP connection successful"
5311        logger.logit(logline)
5312  else:
5313    logline = "trying to open normal HTTP connection"
5314    logger.logit(logline)
5315    if not opt_proxy:
5316      h2 = httplib.HTTP(Updatehost)
5317      logline = "normal HTTP connection successful"
5318      logger.logit(logline)
5319    else:
5320      h2 = httplib.HTTP(Updatehost, 8245)
5321      logline = "normal HTTP connection successful"
5322      logger.logit(logline)
5323
5324  httpdata = "No output from http request."
5325  errmsg = ""
5326  errcode = 200
5327  try:
5328    logline = "Trying to end headers and get reply with httplib"
5329    logger.logit(logline)
5330
5331    h2.putrequest("GET", updateprefix + hostlist + updatesuffix)
5332    h2.putheader("HOST", Updatehost)
5333    h2.putheader("USER-AGENT", Fakeagent)
5334    authstring = base64.encodestring(opt_username + ":" + opt_password)
5335    authstring = string.replace(authstring, "\012", "")
5336    h2.putheader("AUTHORIZATION", "Basic " + authstring)
5337    h2.endheaders()
5338    errcode, errmsg, headers = h2.getreply()
5339
5340    # log the result
5341    logline = "http code = " + `errcode`
5342    logger.logit(logline)
5343    logline = "http msg  = " + errmsg
5344    logger.logit(logline)
5345
5346    # try to get the html text
5347    try:
5348      fp = h2.getfile()
5349      httpdata = fp.read()
5350      fp.close()
5351    except:
5352      httpdata = "No output from http request."
5353
5354    fp.close()
5355
5356  except:
5357    logline = "Trying to end headers and get reply with urllib2"
5358    logger.logit(logline)
5359
5360    protocol = "http://"
5361    theurl = Updatehost + Updatepage
5362
5363    passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
5364    passman.add_password(None, theurl, opt_username, opt_password)
5365    authhandler = urllib2.HTTPBasicAuthHandler(passman)
5366    opener = urllib2.build_opener(authhandler)
5367    urllib2.install_opener(opener)
5368    try:
5369      response = urllib2.urlopen(protocol + theurl)
5370    except IOError, e:
5371      if hasattr(e, 'reason'):
5372        errmsg = e.reason
5373      elif hasattr(e, 'code'):
5374        errcode = e.code
5375
5376    # try to get the html text
5377    try:
5378      httpdata = response.read()
5379    except:
5380      httpdata = "No output from http request."
5381
5382
5383  # create the output file
5384  fp = open (Htmlfile, "w")
5385  fp.write(httpdata)
5386  fp.close()
5387  logger.logit("ipcheck.html file created")
5388
5389  #
5390  # check the result for fatal errors
5391  #
5392
5393  # badauth may appear anywhere when errcode is 401
5394  if string.find(httpdata, "badauth") != -1 and errcode == 401:
5395    logline = "Invalid username and password specified on command line."
5396    logger.logexit(logline)
5397
5398    #
5399    # save the error to an ipcheck.err file
5400    #
5401    errfile.write("badauth " + opt_username + " " + opt_password, fatal=1)
5402    sys.exit(-1)
5403
5404  elif errcode == 404:
5405    logger.logexit("404 Not Found returned by dyndns server.")
5406    logger.logexit("Please try again in a few minutes.")
5407    sys.exit(-1)
5408
5409  # badsys must begin the resulting text and errcode is 200
5410  elif httpdata[:6] == "badsys" and errcode == 200:
5411    logline = "Bad system parameter specified (not dyndns or statdns)."
5412    logger.logexit(logline)
5413
5414    #
5415    # save the error to an ipcheck.err file
5416    #
5417    if opt_static:
5418      errfile.write("badsys statdns", fatal=1)
5419    elif opt_custom:
5420      errfile.write("badsys custom", fatal=1)
5421    else:
5422      errfile.write("badsys dyndns", fatal=1)
5423    sys.exit(-1)
5424
5425  # badagent must begin the resulting text and errcode is 200
5426  elif httpdata[:8] == "badagent" and errcode == 200:
5427    logger.logexit("Badagent contact author at kal@users.sourceforge.net.")
5428    errfile.write("badagent", fatal=1)
5429    sys.exit(-1)
5430
5431  # 911 may appear anywhere when errcode is 500
5432  elif string.find(httpdata, "911") != -1 and errcode == 500:
5433    logline = "Dyndns 911 result.  Dyndns emergency shutdown."
5434    logger.logexit(logline)
5435    errfile.write("shutdown", fatal=1)
5436    sys.exit(-1)
5437
5438  # 999 may appear anywhere when errcode is 500
5439  elif string.find(httpdata, "999") != -1 and errcode == 500:
5440    logline = "Dyndns 999 result.  Dyndns emergency shutdown."
5441    logger.logexit(logline)
5442    errfile.write("shutdown", fatal=1)
5443    sys.exit(-1)
5444
5445  #
5446  # don't really know what codes go with numhost, dnserr and wxxxx
5447  # probably errcode 200 but no need to assume this instead
5448  # assume they will be sent at the beginning of a line
5449  # we check those codes below
5450  #
5451
5452  elif errcode == 200:
5453
5454    # build the results list
5455    results = []
5456    fp = open (Htmlfile, "r")
5457    for host in hostnames:
5458      resultline = fp.readline()
5459      if resultline[-1:] == "\n":
5460        resultline = resultline[:-1]
5461      results.append(resultline)
5462    fp.close()
5463
5464    # check if we have one result per updatehosts
5465    if len(results) == len(updatehosts):
5466      idx = 0
5467      success = 0
5468      for host in updatehosts:
5469        #
5470        # use logexit to generate output (email if ran from a cronjob)
5471        #
5472        if results[idx][:4] == "good":
5473          logline = host + " " + results[idx] + " -update successful"
5474          if opt_quiet:
5475            logger.logit(logline)
5476          else:
5477            logger.logexit(logline)
5478
5479          # update the localip dyndns found if guess was used
5480          if opt_guess and not localip:
5481            p1 = string.find(results[idx], " ")
5482            localip = string.rstrip(results[idx][p1+1:])
5483            logger.logit("Dyndns guessed IP: " + localip)
5484
5485          # set the success update flag
5486          success = 1
5487
5488        elif results[idx][:5] == "nochg":
5489          logline = host + " " + results[idx] + " -abusive if continually repeated"
5490          logger.logexit(logline)
5491
5492          # update the localip dyndns found if guess was used
5493          if opt_guess and not localip:
5494            p1 = string.find(results[idx], " ")
5495            localip = string.rstrip(results[idx][p1+1:])
5496            logger.logit("Dyndns guessed IP: " + `localip`)
5497
5498        elif results[idx][:7] == "!active":
5499          logline = host + " " + results[idx] + " -zone not active yet"
5500          logger.logexit(logline)
5501          logger.logexit("Try again in an hour")
5502
5503          # clear localip to remove ipcheck.dat file
5504          localip = ""
5505
5506        elif results[idx][:5] == "abuse":
5507          logline = host + " " + results[idx] + " -hostname blocked for abuse"
5508          logger.logexit(logline)
5509          logger.logexit("Use the form at http://support.dyndns.org/dyndns/abuse.shtml")
5510          logger.logexit("Erase the ipcheck.err file when dyndns notifies you (by email).")
5511
5512          # update the localip dyndns found if guess was used
5513          if opt_guess and not localip:
5514            p1 = string.find(results[idx], " ")
5515            localip = string.rstrip(results[idx][p1+1:])
5516            logger.logit("Dyndns guessed IP: " + `localip`)
5517
5518          #
5519          # save the error to an ipcheck.err file
5520          #
5521          errfile.write("abuse " + host)
5522        elif results[idx][:7] == "notfqdn":
5523          logline = host + " " + results[idx] + " -FQDN hostnames needed"
5524          logger.logexit(logline)
5525          errfile.write("notfqdn " + host)
5526          # set the localip so next update will be made
5527          localip = "0.0.0.0"
5528
5529        elif results[idx][:6] == "nohost":
5530          logline = host + " " + results[idx] + " -hostname not found"
5531          logger.logexit(logline)
5532          errfile.write("nohost " + host)
5533          # set the localip so next update will be made
5534          localip = "0.0.0.0"
5535
5536        elif results[idx][:7] == "!active":
5537          logline = host + " " + results[idx] + " -hostname not activated yet"
5538          logger.logexit(logline)
5539          errfile.write("!active " + host)
5540          # set the localip so next update will be made
5541          localip = "0.0.0.0"
5542
5543        elif results[idx][:6] == "!yours":
5544          logline = host + " " + results[idx] + " -hostname not yours"
5545          logger.logexit(logline)
5546          errfile.write("!yours " + host)
5547          # set the localip so next update will be made
5548          localip = "0.0.0.0"
5549
5550        elif results[idx][:7] == "numhost":
5551          logline = host + " " + results[idx] + " -send ipcheck.html to support@dyndns.org"
5552          logger.logexit(logline)
5553          errfile.write("numhost " + host)
5554          # set the localip so next update will be made
5555          localip = "0.0.0.0"
5556
5557        elif results[idx][:6] == "dnserr":
5558          logline = host + " " + results[idx] + " -send ipcheck.html to support@dyndns.org"
5559          logger.logexit(logline)
5560          errfile.write("dnserr " + host)
5561          # set the localip so next update will be made
5562          localip = "0.0.0.0"
5563
5564        elif results[idx][:2] == "wu":
5565          logline = host + " " + results[idx] + " -wait until entry created"
5566          logger.logexit(logline)
5567
5568          # get the wait code HH MM
5569          try:
5570            codeHH = int(results[idx][2:4])
5571            codeMM = int(results[idx][4:6])
5572          except:
5573            codeHH = 0
5574            codeMM = 0
5575          codeHHMM = codeHH * 100 + codeMM
5576
5577          # try to get the current time from the HTTP headers at dyndns
5578          datetuple = headers.getdate("Date")
5579          if datetuple == None:
5580            logger.logit("Date header not found.  Using local clock.")
5581            datetuple = gmtime(time.time())
5582          currHH = datetuple[3]
5583          currMM = datetuple[4]
5584          currHHMM = currHH * 100 + currMM
5585
5586          # compute the HHMM we need to wait
5587          if (codeHHMM <= currHHMM):
5588            # The codeHHMM is smaller than GMT of when we received the code.
5589            # Example: NIC returned 02:30 (codeHHMM) when we tried to update
5590            # at 21:30 (currHHMM).  So we should be waiting 21:30 to 24:00
5591            # plus 00:00 to 02:30 seconds.
5592            waitHH = (23 - currHH) + codeHH
5593            waitMM = (60 - currMM) + codeMM
5594            logger.logit("Wraparound calculation.")
5595          else:
5596            waitHH = codeHH - currHH
5597            waitMM = codeMM - currMM
5598            logger.logit("Normal calculation.")
5599
5600          # convert to seconds
5601          waitval = (waitHH * 60 + waitMM) * 60
5602
5603          logger.logit("currHHMM = " + `currHHMM`)
5604          logger.logit("codeHHMM = " + `codeHHMM`)
5605          logger.logit("waitval  = " + `waitval`)
5606
5607          # convert back to seconds
5608          #
5609          # save the until calculation to an ipcheck.wait file
5610          #
5611          fp = open (Waitfile, "a")
5612          fp.write("u " + `waitval` + "\n")
5613          currtime = time.time()
5614          fp.write(`time.time()` + "\n")
5615          fp.close()
5616          logger.logit("ipcheck.wait file created.")
5617
5618          # set the localip so next update will be made
5619          localip = "0.0.0.0"
5620
5621        elif results[idx][0] == "w":
5622          logline = host + " " + results[idx] + " -wait entry created"
5623          logger.logexit(logline)
5624
5625          #
5626          # save the waitcode to an ipcheck.wait file
5627          #
5628          fp = open (Waitfile, "a")
5629          fp.write(results[idx] + "\n")
5630          currtime = time.time()
5631          fp.write(`time.time()` + "\n")
5632          fp.close()
5633          logger.logit("ipcheck.wait file created.")
5634
5635          # set the localip so next update will be made
5636          localip = "0.0.0.0"
5637
5638        elif results[idx][:8] == "!donator":
5639          logline = host + " " + results[idx] + " -trying donator only feature"
5640          logger.logexit(logline)
5641          errfile.write("!donator " + host)
5642          # set the localip so next update will be made
5643          localip = "0.0.0.0"
5644
5645        # looks like the homeip.net domain gives blank lines sometimes???
5646        elif results[idx]:
5647          logline = host + " " + results[idx] + " -unknown result line"
5648          logger.logexit(logline)
5649        else:
5650          logger.logexit("BLANK RESULT LINE!  Please forward the following output")
5651          logger.logexit("(and logfile if you have one) to kal@users.sourceforge.net:")
5652          logger.logexit("updatehosts:")
5653          logger.logexit(`updatehosts`)
5654          logger.logexit("results:")
5655          logger.logexit(`results`)
5656          continue
5657
5658        idx = idx + 1
5659
5660      if success and opt_execute:
5661        os.system (opt_execute)
5662
5663    else:
5664      logger.logexit("Unrecognized result page in ipcheck.html.")
5665
5666    #
5667    # write the update data to file
5668    #
5669    if localip:
5670      if opt_offline:
5671        datfile.setIP("1.0.0.0")
5672      else:
5673        datfile.setIP(localip)
5674
5675      # hostnames == updatehosts in the current version
5676      # but that may change in future versions of the client
5677      datfile.write(hostnames = hostnames)
5678      logger.logit("ipcheck.dat file updated.")
5679
5680  elif errcode == 302:
5681    logger.logexit("302 Temporarily Moved result.  Something is wrong.")
5682    logger.logexit("Please send the ipcheck.html file and this message to")
5683    logger.logexit("kal@users.sourceforge.net")
5684    logger.logexit("=== 302 debug headers ===")
5685    logger.logexit(`headers.getplist()`)
5686    sys.exit(-1)
5687
5688  else:
5689    logger.logexit("Unrecognized errcode returned by dyndns server.")
5690    logger.logexit("Please send me the ipcheck.html file.")
5691    logger.logexit("kal@users.sourceforge.net")
5692    sys.exit(-1)
5693
5694
5695if __name__=="__main__":
5696
5697  _main(sys.argv)
5698
5699
5700