Skip to content
Snippets Groups Projects
dynip.py 2.46 KiB
Newer Older
  • Learn to ignore specific revisions
  • # Author: Stuart D. Gathman <stuart@bmsi.com>
    # Copyright 2005 Business Management Systems, Inc.
    # This code is under the GNU General Public License.  See COPYING for details.
    
    # Heuristically determine whether a domain name is for a dynamic IP.
    
    
    # examples we don't yet recognize:
    #
    # wiley-268-8196.roadrunner.nf.net at ('205.251.174.46', 4810)
    # cbl-sd-02-79.aster.com.do at ('200.88.62.79', 4153)
    
    import re
    
    ip3 = re.compile('[0-9]{1,3}')
    hpats = (
     'h[0-9a-f]{12}[.]',
     'h\d*n\d*c\d*o\d*\.',
     'pcp\d{6,10}pcs[.]',
     'no-reverse',
     'S[0-9a-f]{16}[.][a-z]{2}[.]',
     'user<3>\.',
     '[Cc]ust<3>\.',
     '^<3>\.',
     'ppp[^.]*<3>\.',
     '-ppp\d*\.',
     '\d*-<3>\.',
     '[0-9a-f]{1,3}-<3>\.',
     'p<3>\.pool',
     'h<3>\.',
     'xdsl-\d*\.',
     '-\d*-\d*\.',
     '\.adsl\.',
     '\.cable\.'
    )
    rehmac = re.compile('|'.join(hpats))
    
    def is_dynip(host,addr):
      """Return True if hostname is for a dynamic ip.
      Examples:
    
      >>> is_dynip('post3.fabulousdealz.com','69.60.99.112')
      False
      >>> is_dynip('adsl-69-208-201-177.dsl.emhril.ameritech.net','69.208.201.177')
      True
      >>> is_dynip('[1.2.3.4]','1.2.3.4')
      True
    
      >>> is_dynip('c-71-63-151-151.hsd1.mn.comcast.net','71.63.151.151')
      True
    
      """
      if host.startswith('[') and host.endswith(']'):
        return True
      if addr:
        if host.find(addr) >= 0: return True
        a = addr.split('.')
        ia = map(int,a)
        h = host
        m = ip3.findall(host)
        if m:
    
          g = map(int,m)[:4]
    
          ia3 = (ia[1:],ia[:3])
          if g[-3:] in ia3: return True
          if g[0] == ia[3] and g[1:3] == ia[:2]: return True
          if g[-2:] == ia[2:]: return True
          g.reverse()
          if g[:3] in ia3: return True
          if g[:2] == ia[2:]: return True
          if ia[2:] in (g[:2],g[-2:]): return True
          for m in ip3.finditer(host):
            if int(m.group()) == ia[3]:
    	  h = host[:m.start()] + '<3>' + host[m.end():]
    	  break
        if rehmac.search(h): return True
        if host.find(''.join(a[:3])) >= 0: return True
        if host.find(''.join(a[1:])) >= 0: return True
        x = "%02x%02x%02x%02x" % tuple(ia)
        if host.lower().find(x) >= 0: return True
      return False
    
    if __name__ == '__main__':
      import fileinput
      import sets
      seen = sets.Set()
      for ln in fileinput.input():
        a = ln.split()
        if a[3:5] == ['connect','from']:
          host = a[5]
          if host.startswith('[') and host.endswith(']'):
    	continue	# no PTR
          ip = a[7][2:-2]
          if ip in seen: continue
          seen.add(ip)
          if is_dynip(host,ip):
            print '%s\t%s DYN' % (ip,host)
          else:
            print '%s\t%s' % (ip,host)