Initial commit: mwhois with SCION AS support and decimal AS conversion

Based on mwhois by Antonios A. Chariton
Modifications for SCION AS support by Olaf Baumert, Axpo Systems AG
This commit is contained in:
Olaf Baumert
2025-06-03 11:01:02 +00:00
commit 34c631a06d
340 changed files with 212460 additions and 0 deletions

223
netaddr/core.py Normal file
View File

@@ -0,0 +1,223 @@
#-----------------------------------------------------------------------------
# Copyright (c) 2008-2015, David P. D. Moss. All rights reserved.
#
# Released under the BSD license. See the LICENSE file for details.
#-----------------------------------------------------------------------------
"""Common code shared between various netaddr sub modules"""
import sys as _sys
import pprint as _pprint
from netaddr.compat import _callable, _iter_dict_keys
#: True if platform is natively big endian, False otherwise.
BIG_ENDIAN_PLATFORM = _sys.byteorder == 'big'
#: Use inet_pton() semantics instead of inet_aton() when parsing IPv4.
P = INET_PTON = 1
#: Remove any preceding zeros from IPv4 address octets before parsing.
Z = ZEROFILL = 2
#: Remove any host bits found to the right of an applied CIDR prefix.
N = NOHOST = 4
#-----------------------------------------------------------------------------
# Custom exceptions.
#-----------------------------------------------------------------------------
class AddrFormatError(Exception):
"""
An Exception indicating a network address is not correctly formatted.
"""
pass
class AddrConversionError(Exception):
"""
An Exception indicating a failure to convert between address types or
notations.
"""
pass
class NotRegisteredError(Exception):
"""
An Exception indicating that an OUI or IAB was not found in the IEEE
Registry.
"""
pass
try:
a = 42
a.bit_length()
# No exception, must be Python 2.7 or 3.1+ -> can use bit_length()
def num_bits(int_val):
"""
:param int_val: an unsigned integer.
:return: the minimum number of bits needed to represent value provided.
"""
return int_val.bit_length()
except AttributeError:
# a.bit_length() excepted, must be an older Python version.
def num_bits(int_val):
"""
:param int_val: an unsigned integer.
:return: the minimum number of bits needed to represent value provided.
"""
numbits = 0
while int_val:
numbits += 1
int_val >>= 1
return numbits
class Subscriber(object):
"""
An abstract class defining the interface expected by a Publisher.
"""
def update(self, data):
"""
A callback method used by a Publisher to notify this Subscriber about
updates.
:param data: a Python object containing data provided by Publisher.
"""
raise NotImplementedError('cannot invoke virtual method!')
class PrettyPrinter(Subscriber):
"""
A concrete Subscriber that employs the pprint in the standard library to
format all data from updates received, writing them to a file-like
object.
Useful as a debugging aid.
"""
def __init__(self, fh=_sys.stdout, write_eol=True):
"""
Constructor.
:param fh: a file-like object to write updates to.
Default: sys.stdout.
:param write_eol: if ``True`` this object will write newlines to
output, if ``False`` it will not.
"""
self.fh = fh
self.write_eol = write_eol
def update(self, data):
"""
A callback method used by a Publisher to notify this Subscriber about
updates.
:param data: a Python object containing data provided by Publisher.
"""
self.fh.write(_pprint.pformat(data))
if self.write_eol:
self.fh.write("\n")
class Publisher(object):
"""
A 'push' Publisher that maintains a list of Subscriber objects notifying
them of state changes by passing them update data when it encounter events
of interest.
"""
def __init__(self):
"""Constructor"""
self.subscribers = []
def attach(self, subscriber):
"""
Add a new subscriber.
:param subscriber: a new object that implements the Subscriber object
interface.
"""
if hasattr(subscriber, 'update') and \
_callable(eval('subscriber.update')):
if subscriber not in self.subscribers:
self.subscribers.append(subscriber)
else:
raise TypeError('%r does not support required interface!' \
% subscriber)
def detach(self, subscriber):
"""
Remove an existing subscriber.
:param subscriber: a new object that implements the Subscriber object
interface.
"""
try:
self.subscribers.remove(subscriber)
except ValueError:
pass
def notify(self, data):
"""
Send update data to to all registered Subscribers.
:param data: the data to be passed to each registered Subscriber.
"""
for subscriber in self.subscribers:
subscriber.update(data)
class DictDotLookup(object):
"""
Creates objects that behave much like a dictionaries, but allow nested
key access using object '.' (dot) lookups.
Recipe 576586: Dot-style nested lookups over dictionary based data
structures - http://code.activestate.com/recipes/576586/
"""
def __init__(self, d):
for k in d:
if isinstance(d[k], dict):
self.__dict__[k] = DictDotLookup(d[k])
elif isinstance(d[k], (list, tuple)):
l = []
for v in d[k]:
if isinstance(v, dict):
l.append(DictDotLookup(v))
else:
l.append(v)
self.__dict__[k] = l
else:
self.__dict__[k] = d[k]
def __getitem__(self, name):
if name in self.__dict__:
return self.__dict__[name]
def __iter__(self):
return _iter_dict_keys(self.__dict__)
def __repr__(self):
return _pprint.pformat(self.__dict__)
def dos2unix(filename):
"""
Replace DOS line endings (CRLF) with UNIX line endings (LF) in file.
"""
fh = open(filename, "rb")
data = fh.read()
fh.close()
if '\0' in data:
raise ValueError('file contains binary data: %s!' % filename)
newdata = data.replace("\r\n".encode(), "\n".encode())
if newdata != data:
f = open(filename, "wb")
f.write(newdata)
f.close()