Source code for switchyard.lib.address

__author__ = 'jsommers@colgate.edu'

from ipaddress import IPv4Address, IPv4Network, IPv6Address, IPv6Network, ip_address
from enum import Enum

import struct
import socket

# EthAddr class modified from POX code, license below.

# Copyright 2011,2012,2013 James McCauley
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

[docs] class EthAddr (object): """ An Ethernet (MAC) address type. """ __slots__ = ['__value'] def __init__ (self, addr=None): """ Understands Ethernet address is various forms. Hex strings, raw byte strings, etc. """ # Always stores as a bytes object of length 6 self.__value = None if isinstance(addr, bytes): self.__value = bytes(addr[:6]) elif isinstance(addr, EthAddr): self.__value = addr.raw elif addr is None: self.__value = b'\x00' * 6 elif isinstance(addr, str): possible_separators = (':','-') for sep in possible_separators: if addr.count(sep) == 5: self.__value = bytes([ int(val,base=16) for val in addr.split(sep)]) break if not self.__value: raise RuntimeError("Expected ethernet address string to be 6 raw " "bytes or some hex")
[docs] def isBridgeFiltered (self): """ Checks if address is an IEEE 802.1D MAC Bridge Filtered MAC Group Address This range is 01-80-C2-00-00-00 to 01-80-C2-00-00-0F. MAC frames that have a destination MAC address within this range are not relayed by bridges conforming to IEEE 802.1D """ return ((self.__value[0] == 0x01) and (self.__value[1] == 0x80) and (self.__value[2] == 0xC2) and (self.__value[3] == 0x00) and (self.__value[4] == 0x00) and (self.__value[5] <= 0x0F))
@property def is_bridge_filtered (self): return self.isBridgeFiltered()
[docs] def isGlobal (self): """ Returns True if this is a globally unique (OUI enforced) address. """ return not self.isLocal()
[docs] def isLocal (self): """ Returns True if this is a locally-administered (non-global) address. """ return True if (self.__value[0] & 2) else False
@property def is_local (self): return self.isLocal() @property def is_global (self): return self.isGlobal()
[docs] def isMulticast (self): """ Returns True if this is a multicast address. """ return True if (self.__value[0] & 1) else False
@property def is_multicast (self): return self.isMulticast()
[docs] def toRaw (self): return self.raw
@property def raw (self): """ Returns the address as a 6-long bytes object. """ return self.__value @property def packed(self): return self.raw
[docs] def toTuple (self): """ Returns a 6-entry long tuple where each entry is the numeric value of the corresponding byte of the address. """ return tuple(self.__value)
[docs] def toStr (self, separator = ':'): """ Returns the address as string consisting of 12 hex chars separated by separator. """ return separator.join(('{:02x}'.format(x) for x in self.__value))
def __str__ (self): return self.toStr() def __eq__(self, other): other = EthAddr(other) return self.raw == other.raw def __lt__(self, other): other = EthAddr(other) return self.raw < other.raw def __hash__ (self): return hash(self.__value) def __repr__ (self): return self.__class__.__name__ + "('" + self.toStr() + "')" def __len__ (self): return 6
ethaddr = EthAddr macaddr = EthAddr
[docs] class SpecialIPv6Addr(Enum): UNDEFINED = ip_address('::') ALL_NODES_LINK_LOCAL = ip_address('ff02::1') ALL_ROUTERS_LINK_LOCAL = ip_address('ff02::2') ALL_NODES_INTERFACE_LOCAL = ip_address('ff01::1') ALL_ROUTERS_INTERFACE_LOCAL = ip_address('ff01::2')
#ff02::1:3 link local multicast name resolution #ff02::1:ff00:0/104 solicited-node #ff02::2:ff00:0/104 node information query
[docs] class SpecialIPv4Addr(Enum): IP_ANY = ip_address("0.0.0.0") IP_BROADCAST = ip_address("255.255.255.255")
class SpecialEthAddr(Enum): ETHER_ANY = EthAddr(b'\x00\x00\x00\x00\x00\x00') ETHER_BROADCAST = EthAddr(b'\xff\xff\xff\xff\xff\xff') BRIDGE_GROUP_ADDRESS = EthAddr(b'\x01\x80\xC2\x00\x00\x00') LLDP_MULTICAST = EthAddr(b'\x01\x80\xc2\x00\x00\x0e') PAE_MULTICAST = EthAddr(b'\x01\x80\xc2\x00\x00\x03') # 802.1x Port Access Entity NDP_MULTICAST = EthAddr(b'\x01\x23\x20\x00\x00\x01') # Nicira discovery multicast