Exemplo n.º 1
0
    def refresh(self):
        '''Gets information about this device from the Linux kernel'''
        # Open a netlink socket
        netlink = IPRoute()
        raw_ifaces = netlink.get_links()

        for raw_iface in raw_ifaces:
            if raw_iface.get_attr('IFLA_ADDRESS') == self.mac_address:
                index = raw_iface['index']
                self.state = raw_iface.get_attr('IFLA_OPERSTATE')
                self.current_name = raw_iface.get_attr('IFLA_IFNAME')
                self.mac_address = raw_iface.get_attr('IFLA_ADDRESS')

                # Get the addrs per interface
                addrs = netlink.get_addr(index=index)
                for addr in addrs:
                    nic_ip_address = ipaddress.ip_address(
                        addr.get_attr('IFA_ADDRESS'))

                    # Getting the netmask is somewhat more involved unfortunately. Under Linux
                    # the netmask is NOT stored with the interface, but in the routing table
                    # which is not connected to the interface at all. We need the netmask
                    # to know which hosts we can see on a level 2 segment scan with nmap, as well
                    # as what we should expect to see on a ND probe with NMAP.

                    # To do this, we need to pull the network routing table, and walk it. For every
                    # configured IP address, we'll find multiple routing entries:
                    #
                    # The first will be a /32 (v4) or /128 (v6) referring to ourselves so that
                    # loopback works. We'll also find a broadcast route like this
                    #
                    # Secondly, we'll also have one entry per gateway with a dst_len of 0. We'll
                    # ignore these as these are global and not per interface
                    #
                    # Thirdly, we'll have our network and it's netmask
                    #
                    # Routing table entries have a preferred src (PREFSRC) value which may or may
                    # not be set saying which IP is preferred when using this route. This is a
                    # trap, we can't use this value because in multihoming scenarios, this won't
                    # get the information we want

                    if nic_ip_address.version == 4:
                        self_prefixlen = 32
                        routing_table = netlink.get_routes(family=AF_INET)
                    else:  # v6
                        self_prefixlen = 128
                        routing_table = netlink.get_routes(family=AF_INET6)

                    for route in routing_table:
                        # Filter out gateway routes
                        if route.get_attr('RTA_GATEWAY') is not None:
                            continue

                        if 'dst_len' not in route:
                            continue

                        dst_len = route['dst_len']
                        if dst_len == self_prefixlen or dst_len == 0:
                            continue  # Self or default

                        # Filter out the network if its a self address, or len of 0
                        rta_dst = route.get_attr('RTA_DST')
                        if rta_dst is None:
                            continue

                        rta_dst += "/" + str(dst_len)
                        route_ipnet = ipaddress.ip_network(rta_dst,
                                                           strict=True)

                        # Filter out link local addresses
                        if route_ipnet.is_link_local:
                            continue

                        if nic_ip_address in route_ipnet:
                            # We've got a winner!
                            #print("Got network match. Interface", self.name, " ", str(rta_dst))

                            # Create an IP address object and store it
                            ip_obj = IPAddressConfig(str(nic_ip_address),
                                                     dst_len)
                            self.current_ip_addresses.append(ip_obj)

        # And clean up after ourselves
        netlink.close()
Exemplo n.º 2
0
 def setup(self):
     self.ip = IPRoute()
Exemplo n.º 3
0
from pyroute2.netlink import NLM_F_REQUEST
from pyroute2.netlink import NLM_F_DUMP
from pyroute2.netlink.nl80211 import nl80211cmd
from pyroute2.netlink.nl80211 import NL80211_NAMES

logging.basicConfig(level=logging.DEBUG)

logger = logging.getLogger("scandump")
logger.setLevel(level=logging.INFO)

# interface name to dump scan results
ifname = sys.argv[1]

iw = IW()

ip = IPRoute()
ifindex = ip.link_lookup(ifname=ifname)[0]
ip.close()

# CMD_GET_SCAN doesn't require root privileges.
# Can use 'nmcli device wifi' or 'nmcli d w' to trigger a scan which will fill
# the scan results cache for ~30 seconds.
# See also 'iw dev $yourdev scan dump'
msg = nl80211cmd()
msg['cmd'] = NL80211_NAMES['NL80211_CMD_GET_SCAN']
msg['attrs'] = [['NL80211_ATTR_IFINDEX', ifindex]]

scan_dump = iw.nlm_request(msg,
                           msg_type=iw.prid,
                           msg_flags=NLM_F_REQUEST | NLM_F_DUMP)
for network in scan_dump:
Exemplo n.º 4
0
    def __init__(self, log, inv_file):
        inv = Inventory(log, inv_file)
        self.log = log
        self.ext_label_dev = inv.get_mgmt_switch_external_dev_label()

        if inv.is_passive_mgmt_switches():
            if self.ext_label_dev:
                self.log.info('Passive Management Switch(es) Detected')
                print(self.ext_label_dev)
                sys.exit(0)
            else:
                self.log.error('Management switch not found')
                sys.exit(1)

        for self.ipv4 in inv.yield_mgmt_switch_ip():
            pass
        mgmt_network = inv.get_ipaddr_mgmt_network()
        self.broadcast = str(netaddr.IPNetwork(mgmt_network).broadcast)
        self.mask = str(netaddr.IPNetwork(mgmt_network).netmask)

        if self.ext_label_dev:
            self.log.debug('External dev label %s was specified' %
                           self.ext_label_dev)
        else:
            self.log.debug('External dev label was not specified')
        self.ext_ip_dev = inv.get_mgmt_switch_external_dev_ip()
        self.ext_prefix = inv.get_mgmt_switch_external_prefix()
        for self.ext_ip_switch in inv.yield_mgmt_switch_external_switch_ip():
            pass

        self.ext_broadcast = str(
            netaddr.IPNetwork(self.ext_ip_dev + '/' +
                              self.ext_prefix).broadcast)
        self.ext_mask = str(
            netaddr.IPNetwork(self.ext_ip_dev + '/' + self.ext_prefix).netmask)

        self.ipr = IPRoute()
        for link in self.ipr.get_links():
            kind = None
            try:
                self.label = (link.get_attr('IFLA_IFNAME'))
                kind = (
                    link.get_attr('IFLA_LINKINFO').get_attr('IFLA_INFO_KIND'))
            except:
                pass
            if kind == self.BRIDGE:
                if self.ipr.get_addr(label=self.label,
                                     broadcast=self.broadcast):
                    self.log.info('Bridge %s on management subnet %s found' %
                                  (self.label, mgmt_network))
                    if self._ping(self.ipv4, self.label):
                        self.log.info('Management switch found on %s' %
                                      self.label)
                        sys.exit(0)
                    else:
                        self.log.debug('Management switch not found on %s' %
                                       self.label)

        if self.ext_label_dev:
            self.dev = self.ipr.link_lookup(ifname=self.ext_label_dev)[0]
            self._add_ip()

            # Print to stdout for Ansible playbook to register
            print(self.ext_label_dev)
        else:
            switch_found = False
            for link in self.ipr.get_links():
                kind = None
                try:
                    self.label = (link.get_attr('IFLA_IFNAME'))
                    kind = (link.get_attr('IFLA_LINKINFO').get_attr(
                        'IFLA_INFO_KIND'))
                except:
                    pass
                if self.label != self.LOCAL and not kind:
                    self.dev = self.ipr.link_lookup(ifname=self.label)[0]
                    self._add_ip()

                    if self._ping(self.ext_ip_switch, self.label):
                        switch_found = True
                        self.log.info('Management switch found on %s' %
                                      self.label)
                        self._configure_switch()
                    else:
                        self.log.debug('Management switch not found on %s' %
                                       self.label)

                    self._del_ip()

                    if switch_found:
                        break

            if not switch_found:
                self.log.error('Management switch not found')
                sys.exit(1)

            # Print to stdout for Ansible playbook to register
            print(self.label)
Exemplo n.º 5
0
 def test_multiple_instances(self):
     ip1 = IPRoute()
     ip2 = IPRoute()
     ip1.close()
     ip2.close()
Exemplo n.º 6
0
 def __init__(self):
     Base.__init__(self)
     self.ipr = IPRoute()
     self.nodes = []
Exemplo n.º 7
0
    def remove_bridge(self):
        """Destroy the bridge."""
        ipr = IPRoute()

        logger.debug('Remove bridge %s', self.bridge_name)
        ipr.link('del', ifname=self.bridge_name)
import argparse
import sys
import os
import re
import platform
from pyroute2 import IPRoute
from docker import errors

from lib.config import Config
from lib.genesis import GEN_PATH
from lib.container import Container
import lib.logger as logger
from lib.utilities import sub_proc_exec, remove_line, get_netmask

IPR = IPRoute()
OPSYS = platform.dist()[0]
IFCFG_PATH = '/etc/sysconfig/network-scripts/'


def teardown_deployer_network(config_path=None):
    """Teardown the network elements on the deployer.
    This function is idempotent.
    """
    cfg = Config(config_path)
    global LOG
    LOG = logger.getlogger()
    LOG.debug('----------------------------------------')
    LOG.info('Teardown Docker networks')
    _remove_docker_networks(cfg)
    LOG.info('Teardown deployer management networks')
Exemplo n.º 9
0
 def __init__(self):
     self.ip_route = IPRoute()
Exemplo n.º 10
0
def _get_ip_route(dst_ip: str) -> Any:
    """Get ip next hop."""
    return IPRoute().route("get", dst=dst_ip)
Exemplo n.º 11
0
 def __init__(self, *args, **kwargs):
     super(VrrpPlugin, self).__init__(*args, **kwargs)
     self.plugin = NAME
     self.ip_addresses = []
     self.ipr = IPRoute()
Exemplo n.º 12
0
 def test_scan(self):
     require_user('root')
     with IPRoute() as ipr:
         ipr.link('set', index=self.ifindex, state='up')
     self.iw.scan(self.ifindex)
Exemplo n.º 13
0
 def setup(self):
     require_user('root')
     self.ip = IPRoute()
     self.ifname = uifname()
     self.ip.link('add', ifname=self.ifname, kind='dummy')
     self.interface = self.ip.link_lookup(ifname=self.ifname)[0]
Exemplo n.º 14
0
 def __init__(self, params):
     self.params = params
     self.core_api = client.CoreV1Api()
     self.obj_api = client.CustomObjectsApi()
     self.iproute = IPRoute()
     self.iproute_ns = None
Exemplo n.º 15
0
class Interface():
    """ Define ethernet interface using low level RAW sockets.
	NOTE: To create RAW sockets, you must be superuser or have 'cap_net_raw' capabilities.
	      You can set the capabilities to python using:
	      $ sudo setcap cap_mac_admin,cap_net_raw,cap_net_admin=eip /usr/bin/python2.6
	"""

    netlink = IPRoute()

    def __init__(self, name, eth_type=ETH_P_ALL):
        """ Initialize interface. Open socket and set interface in promiscuous mode.
		@param name          Name of the interface. Ex: 'eth0'
		@param eth_type      Ethernet protocols read by this interface. Default: ALL PROTOCOLS.
		"""
        self.logger = logging.getLogger("PC eth")
        self.eth_type = eth_type
        self.name = name
        self.added_ips = []
        self.is_vlan = False

        # If the interface is not part of IPDB, it can be a VLAN
        if not self.netlink.link_lookup(ifname=self.name):
            vlan_match = re.match(
                "^(?P<base_interface>eth\d+)\.(?P<vlan_id>[1-9]\d{1,3})$",
                self.name)
            if vlan_match is None:
                raise Exception("Invalid interface name " + self.name)
            base = vlan_match.group('base_interface')
            vid = int(vlan_match.group('vlan_id'))

            base_idx = self.netlink.link_lookup(ifname=base)
            if not base_idx:
                raise Exception("Invalid base interface name " + self.name)

            try:
                request = {
                    'index': 0,
                    'ipaddr': [],
                    'link': base_idx[0],
                    'flags': 0,
                    'ifname': self.name,
                    'ports': [],
                    'IFLA_LINKINFO': {
                        'attrs': [[
                            'IFLA_INFO_DATA', {
                                'attrs': [['IFLA_VLAN_ID', vid]]
                            }
                        ], ['IFLA_INFO_KIND', 'vlan']]
                    }
                }
                # Send request to create new interface with VLAN
                self.netlink.link('add', **request)
                self.is_vlan = True

            except:
                self.logger.critical("Couldn't create interface %s", self.name)
                raise

        # Get Interface Index, set to UP, get MTU and MAC Address
        self.if_index = self.netlink.link_lookup(ifname=self.name)[0]
        self.netlink.link('set', index=self.if_index, state='up')
        info = dict(self.netlink.get_links(self.if_index)[0]['attrs'])
        self.mac_address = info['IFLA_ADDRESS'].upper()
        self.mtu = info['IFLA_MTU']

        # Create socket to receive/send frames:
        self.sockfd = socket.socket(socket.AF_PACKET, socket.SOCK_RAW,
                                    socket.htons(self.eth_type))
        self.sockfd.bind((self.name, self.eth_type))

        # Enable promiscuous mode:
        self.set_promiscuous(True)

        # By default, start using auto-negotiation
        self.using_forced_speed_duplex = False

    def __del__(self):
        """ Destructor. Disable promiscuous mode on interface.
		"""

        # Clean added IP addresses.
        for ip in self.added_ips:
            self.__set_ip_address(ip[0], ip[1], 'delete')

        # Remove VLAN if it was created.
        if self.is_vlan:
            self.netlink.link('delete', index=self.if_index)

        # Disable promiscuous mode:
        self.set_promiscuous(False)

        # Leave interface with auto-negotiation enabled:
        if self.using_forced_speed_duplex:
            self.enable_auto_negotiation()

    def recv(self):
        """ Receive a packet. If it's an outgoing packet ignore it.
		"""
        packet, address = self.sockfd.recvfrom(self.mtu)
        return packet if address[2] != socket.PACKET_OUTGOING else None

    def send(self, packet):
        """ Send a packet through this interface.
		"""
        self.sockfd.sendto(str(packet), 0, (self.name, self.eth_type))

    def flush(self):
        """ Remove all packets from read buffer.
		"""
        self.sockfd.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0)
        while True:
            r, w, e = select([self.sockfd.fileno()], [], [], 0)
            if r:
                os.read(self.sockfd.fileno(), self.mtu)
            else:
                break
        self.sockfd.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)

    def set_promiscuous(self, enable):
        """ Enable/Disable promiscuous mode on interface.
		@param enable        True to enable, False to disable.
		"""
        cmd = PACKET_ADD_MEMBERSHIP if enable else PACKET_DROP_MEMBERSHIP
        mreq = struct.pack('IHH8s', self.if_index, PACKET_MR_PROMISC, 0, "")
        self.sockfd.setsockopt(SOL_PACKET, cmd, mreq)

    def add_ip_address(self, ip_address):
        """ Adds an IP address/network mask (the default prefix is 24)
		@param ip_address    The IP address followed optionally by mask size. Ex: 192.168.0.24/24
		"""
        self.__set_ip_address(ip_address, socket.AF_INET, 'add')
        self.added_ips.append((ip_address, socket.AF_INET))

    def del_ip_address(self, ip_address):
        """ Deletes an IP address/network mask (the default prefix is 24)
		@param ip_address    The IP address followed optionally by mask size. Ex: 192.168.0.24/24
		"""
        self.__set_ip_address(ip_address, socket.AF_INET, 'delete')
        self.added_ips.remove((ip_address, socket.AF_INET))

    def add_ipv6_address(self, ipv6_address):
        """ Adds an IPv6 address/network mask (the default prefix is 24)
		@param ip_address    The IPv6 address followed optionally by mask size. Ex: 56::1/24
		"""
        self.__set_ip_address(ipv6_address, socket.AF_INET6, 'add')
        self.added_ips.append((ipv6_address, socket.AF_INET6))

    def del_ipv6_address(self, ipv6_address):
        """ Deletes an IPv6 address/network mask (the default prefix is 24)
		@param ip_address    The IPv6 address followed optionally by mask size. Ex: 56::1/24
		"""
        self.__set_ip_address(ipv6_address, socket.AF_INET6, 'delete')
        self.added_ips.remove((ipv6_address, socket.AF_INET6))

    def enable_auto_negotiation(self):
        """ Enable auto-negotiation for Ethernet link.
		"""
        ethtool = Ethtool(self.name)
        ethtool.get()
        ethtool.advertising = ethtool.supported
        ethtool.autoneg = 1
        ethtool.set()

        self.using_forced_speed_duplex = False
        self.logger.info("[%s] Enabled Auto-negotiation.", self.name)

    def force_speed_duplex(self, speed, duplex):
        """ Configure interface speed/duplex disabling auto-negotiation.
		@param speed         Set forced speed. Values: 10, 100, 1000, 2500, 10000.
		@param duplex        Set forced duplex.
		"""

        if not speed in [10, 100, 1000, 2500, 10000]:
            raise ValueError(
                "Speed can only be: 10, 100, 1000, 2500 or 10000 Mbps.")

        ethtool = Ethtool(self.name)
        ethtool.get()
        ethtool.speed = speed
        ethtool.duplex = 1 if duplex else 0
        ethtool.autoneg = 0
        ethtool.set()

        self.using_forced_speed_duplex = True
        self.logger.info("[%s] Configured forced speed: %d Mbps / %s duplex",
                         self.name, speed, "full" if duplex else "half")

    def has_ip_address(self, ip_address):
        """ Returns True if the address is already configured in the interface, and False otherwise
		@param ip_address The IP address to be checked
		"""
        return (self.__check_ip_address(ip_address, socket.AF_INET)
                or self.__check_ip_address(ip_address, socket.AF_INET6))

    def set_mtu(self, mtu):
        """ Configure interface MTU.
		@param mtu           New value for MTU.
		"""
        self.netlink.link('set', index=self.if_index, mtu=mtu)

    def set_mac_address(self, mac_address):
        """ Configure a new MAC address at this interface
		@param mac_address The MAC address to be set
		"""
        self.netlink.link('set', index=self.if_index, address=mac_address)
        self.mac_address = mac_address

    def __check_ip_address(self, ip_address, ip_family):
        """ Returns True if the address is already configured in the interface, and False otherwise
		@param ip_address The IP address to be checked
		@param ip_family socket.AF_INET if ip_address is an IPv4 address; socket.AF_INET6 otherwise
		"""
        address_types = [
            'IFA_ADDRESS', 'IFA_LOCAL', 'IFA_BROADCAST', 'IFA_ANYCAST',
            'IFA_MULTICAST'
        ]
        for interface in self.netlink.get_addr(family=ip_family):
            if interface['index'] != self.if_index:
                continue
            for address in interface['attrs']:
                if address[0] in address_types and address[1] == ip_address:
                    return True
        return False

    def __set_ip_address(self, ip_address, ip_family, action):
        """ Adds or deletes an IP address/network mask (optional)
		@param ip_address    The IP address followed optionally by mask size. Ex: 192.168.0.24/24; 56::1/24
		@param ip_family     socket.AF_INET to IPv4 addresses; socket.AF_INET6 to IPv6 addresses
		@param action        'add' or 'del', to add or delete an IP address, respectively
		"""

        ip_and_mask = ip_address.split('/')
        ip_version = 4 if ip_family == socket.AF_INET else 6
        network_mask = 24 if len(ip_and_mask) < 2 else int(ip_and_mask[1])
        exists = self.__check_ip_address(ip_and_mask[0], ip_family)

        if (action == 'add' and exists) or (action == 'delete' and not exists):
            self.logger.info(
                'No need to %s the IP%d address %s/%d from/to %s because it already %sexists',
                action, ip_version, ip_and_mask[0], network_mask, self.name,
                '' if exists else 'does not ')
            return

        self.logger.info("%s IPv%d address %s/%d in %s", action, ip_version,
                         ip_and_mask[0], network_mask, self.name)
        self.netlink.addr(action,
                          self.if_index,
                          address=ip_and_mask[0],
                          mask=network_mask,
                          family=ip_family)
Exemplo n.º 16
0
 def test_respawn_iproute_async(self):
     for _ in range(RESPAWNS):
         with IPRoute() as i:
             i.bind(async=True)
             i.link_lookup(ifname='lo')
Exemplo n.º 17
0
def Server(cmdch, brdch):
    '''
    A server routine to run an IPRoute object and expose it via
    custom RPC.

    many TODOs:

    * document the protocol
    * provide not only IPRoute

    RPC

    Messages sent via channels are dictionaries with predefined
    structure. There are 4 s.c. stages::

        init        (server <-----> client)
        command     (server <-----> client)
        broadcast   (server ------> client)
        shutdown    (server <------ client)


    Stage 'init' is used during initialization. The client
    establishes connections to the server and announces them
    by sending a single message via each channel::

        {'stage': 'init',
         'domain': ch_domain,
         'client': client.uuid}

    Here, the client uuid is used to group all the connections
    of the same client and `ch_domain` is either 'command', or
    'broadcast'. The latter will become a unidirectional
    channel from the server to the client, all data that
    arrives on the server side via netlink socket will be
    forwarded to the broadcast channel.

    The command channel will be used to make RPC calls and
    to shut the worker thread down before the client
    disconnects from the server.

    When all the registration is done, the server sends a
    single message via the command channel::

        {'stage': 'init',
         'error': exception or None}

    If the `error` field is None, everything is ok. If it
    is an exception, the init is failed and the exception
    should be thrown on the client side.

    In the runtime, all the data that arrives on the netlink
    socket fd, is to be forwarded directly via the
    broadcast channel.

    Commands are handled with the `command` stage::

        # request

        {'stage': 'command',
         'name': str,
         'cookie': cookie,
         'argv': [...],
         'kwarg': {...}}

        # response

        {'stage': 'command',
         'error': exception or None,
         'return': retval,
         'cookie': cookie}

    Right now the protocol is synchronous, so there is not
    need in cookie yet. But in some future it can turn into
    async, and then cookies will be used to match messages.

    The final stage is 'shutdown'. It terminates the worker
    thread, has no response and no messages can passed after.

    '''

    def close(s, frame):
        # just leave everything else as is
        brdch.send({'stage': 'signal',
                    'data': s})

    try:
        ipr = IPRoute()
        lock = ipr._sproxy.lock
        ipr._s_channel = ProxyChannel(brdch, 'broadcast')
        poll = select.poll()
        poll.register(ipr, select.POLLIN | select.POLLPRI)
        poll.register(cmdch, select.POLLIN | select.POLLPRI)
    except Exception as e:
        cmdch.send({'stage': 'init',
                    'error': e})
        return 255

    # all is OK so far
    cmdch.send({'stage': 'init',
                'error': None})
    signal.signal(signal.SIGHUP, close)
    signal.signal(signal.SIGINT, close)
    signal.signal(signal.SIGTERM, close)

    # 8<-------------------------------------------------------------
    while True:
        try:
            events = poll.poll()
        except:
            continue
        for (fd, event) in events:
            if fd == ipr.fileno():
                bufsize = ipr.getsockopt(SOL_SOCKET, SO_RCVBUF) // 2
                with lock:
                    error = None
                    data = None
                    try:
                        data = ipr.recv(bufsize)
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    brdch.send({'stage': 'broadcast',
                                'data': data,
                                'error': error})
            elif fd == cmdch.fileno():
                cmd = cmdch.recv()
                if cmd['stage'] == 'shutdown':
                    poll.unregister(ipr)
                    poll.unregister(cmdch)
                    ipr.close()
                    return
                elif cmd['stage'] == 'reconstruct':
                    error = None
                    try:
                        msg = cmd['argv'][0]()
                        msg.load(pickle.loads(cmd['argv'][1]))
                        msg.encode()
                        ipr.sendto_gate(msg, cmd['argv'][2])
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    cmdch.send({'stage': 'reconstruct',
                                'error': error,
                                'return': None,
                                'cookie': cmd['cookie']})

                elif cmd['stage'] == 'command':
                    error = None
                    try:
                        ret = getattr(ipr, cmd['name'])(*cmd['argv'],
                                                        **cmd['kwarg'])
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    cmdch.send({'stage': 'command',
                                'error': error,
                                'return': ret,
                                'cookie': cmd['cookie']})
Exemplo n.º 18
0
 def initTask(self):
     self.ipr = IPRoute()
     super(TsdLinuxShaper, self).initTask()
    def __init__(self, name, bridge, addr):
        """
        Args:
            name (str): namespace name
            bridge (str): name of bridge to attach to
            addr (str): cidr of namespace address
        """
        self.log = logger.getlogger()
        self.addr = addr
        self.bridge = bridge
        self.vlan = bridge.split('-')[-1]
        self.name = name + self.vlan
        self.ip = IPRoute()
        self._disconnect_container()
        self.log.debug('Creating network namespace {}'.format(self.name))

        stdout, stderr, rc = sub_proc_exec('ip netns add {}'.format(self.name))
        if rc:
            self.log.debug(
                'An error occurred while creating namespace '
                f' {self.name}.\nreturn code: {rc}\nWarning: {stderr}')
        if stderr:
            if 'File exists' in stderr:
                self.log.debug(stderr)
            else:
                self.log.error('Unable to create namespace')
                sys.exit(1)

        self.br_ifc = 'veth-br-' + self.name.split('-')[0] + '-' + self.vlan
        self.peer_ifc = 'veth-' + self.name

        try:
            self.ip.link("add",
                         ifname=self.br_ifc,
                         peer=self.peer_ifc,
                         kind='veth')
        except NetlinkError as exc:
            if 'File exists' not in str(exc):
                self.log.error('Failed creating veth pair. {}'.format(exc))
                sys.exit(1)

        try:
            # peer interface side disappears from host space once attached to
            # the namespace
            idx_ns_ifc = self.ip.link_lookup(ifname=self.peer_ifc)[0]
            self.ip.link('set', index=idx_ns_ifc, net_ns_fd=self.name)
        except IndexError:
            self.log.debug('Peer ifc already attached.')
        except NetlinkError:
            self.log.debug('Peer ifc already attached.')
        idx_br = self.ip.link_lookup(ifname=bridge)[0]
        self.idx_br_ifc = self.ip.link_lookup(ifname=self.br_ifc)[0]
        self.ip.link('set', index=self.idx_br_ifc, master=idx_br)

        # bring up the interfaces
        cmd = 'ip netns exec {} ip link set dev {} up'.format(
            self.name, self.peer_ifc)
        stdout, stderr, rc = sub_proc_exec(cmd)

        cmd = 'ip netns exec {} ip link set dev lo up'.format(self.name)
        stdout, stderr, rc = sub_proc_exec(cmd)

        cmd = 'ip netns exec {} ip addr add {} dev {} brd +' \
            .format(self.name, addr, self.peer_ifc)
        stdout, stderr, rc = sub_proc_exec(cmd)

        # verify address setup
        # cmd = 'ip netns exec {} ip addr show'.format(self.name)
        # proc = Popen(cmd.split(), stdout=PIPE, stderr=PIPE)
        # stdout, stderr = proc.communicate()

        self.ip.link('set', index=self.idx_br_ifc, state='up')
    def process(self, pkt):

        if not hasattr(pkt, 'ip'):
            return

        ip = pkt.ip
        # Ignore non-tcp, non-udp packets
        if type(ip.data) not in (TCP, UDP):
            return

        pload = ip.data
        src, dst, dport, flags = int(struct.unpack('I', ip.src)[0]), int(
            struct.unpack('I', ip.dst)[0]), int(pload.dport), 0
        proto = type(pload)

        if proto == TCP: flags = pload.flags
        key = self.host_hash(src, dst)

        curr = time.time()

        # Keep dropping old entries
        self.recent_scans.collect()

        if key in self.scans:
            scan = self.scans[key]

            if scan.src != src:
                # Skip packets in reverse direction or invalid protocol
                return

            # Update only if not too old, else skip and remove entry
            if curr - scan.timestamp > self.timeout:
                del self.scans[key]
                return

            if scan.logged: return

            # Update TCP flags if existing port
            if dport in scan.ports:
                # Same port, update flags
                scan.tcpflags_or |= flags
                return

            scan.timestamp = curr
            scan.tcpflags_or |= flags
            scan.ports.append(dport)
            #print dport #destination port printed
            # Add weight for port
            if dport < 1024:
                scan.weight += 3
            else:
                scan.weight += 1

            if scan.weight >= self.threshold:
                scan.logged = True
                if proto == TCP:
                    scan.type = self.scan_types.get(scan.tcpflags_or,
                                                    'unknown')
                elif proto == UDP:
                    scan.type = 'UDP'
                    # Reset flags for UDP scan
                    scan.tcpflags_or = 0

                # See if this was logged recently
                scanentry = (key, scan.type, scan.tcpflags_or)

                if scanentry not in self.recent_scans:
                    #ip change code here
                    ipdb = pyroute2.IPDB()
                    with ipdb.interfaces.ens33 as ens33:
                        #print ens33
                        ip = IPRoute()
                        oldip = ip.get_addr()[1]['attrs'][0][1]
                        oldoctet = int(oldip[11:])
                        oldip = oldip + '/24'
                        newoctet = np.random.randint(100, 110)
                        #print (oldoctet,newoctet,type(oldoctet),type(newoctet))
                        while oldoctet == newoctet:
                            #print 'entered while'
                            newoctet = np.random.randint(100, 110)

                        oldoctet = newoctet
                        newip = '192.168.50.' + str(newoctet)  #+'/24'
                        print "**********************************"
                        x = datetime.datetime.now()
                        print(x)
                        print "old ip :" + oldip
                        print "Printing new octet : " + str(newoctet)
                        print "new ip :" + newip
                        print "**********************************"
                        ens33.del_ip(oldip)
                        #ens33.add_ip(newip)
                        index = ip.link_lookup(ifname='ens33')[0]
                        ip.addr('add',
                                index,
                                address=newip,
                                mask=24,
                                broadcast='192.168.50.255',
                                metric=100)
                        ip.close()
                        #ens33.set('broadcast', '192.168.50.255').commit()
                        #ens33['broadcast']='192.168.50.255'
                    self.log_scan(scan)
                    self.recent_scans.append(scanentry)
                else:
                    self.log_scan(scan, True)

        else:
            # Add new entry
            scan = ScanEntry(key)
            scan.src = src
            scan.dst = dst
            scan.timestamp = curr
            scan.tcpflags_or |= flags
            scan.ports.append(dport)
            self.scans[key] = scan
Exemplo n.º 21
0
 def configure_interface(self, ip4, plen, gw):
     # Set link-up for interface on host-os
     iproute = IPRoute()
     idx = iproute.link_lookup(ifname=self.host_ifname)[0]
     iproute.link('set', index=idx, state='up')
     super(CniVEthPair, self).configure_interface(ip4, plen, gw)
Exemplo n.º 22
0
def destroy_bridge(br_name):

    log.info("Deleting bridge %s." % br_name)

    ipdb = IPDB()

    if br_name not in ipdb.interfaces.keys():
        log.fatal("A bridge/interface with the name %s does not exist!" %
                  br_name)
        return False

    # Guess what the original physical interface could be

    ifnames = [
        ipdb.interfaces[p].ifname for p in ipdb.interfaces['br-clients'].ports
    ]
    ifnames = [i for i in ifnames if i.startswith("enp")]

    phy_eth = None

    if len(ifnames) != 1:
        log.warning(
            "Could not determine which interface is the physical one in the bridge!"
        )
    else:
        phy_eth = ifnames[0]
        log.debug("Assuming %s is the physical interface on the bridge." %
                  phy_eth)

    # Guess what the original physical IP could be
    phy_ip = None

    if phy_eth is not None:
        for ip, netmask in ipdb.interfaces[br_name].ipaddr:
            if ip.startswith('10.') or ip.startswith('192.'):
                phy_ip = (ip, netmask)

        if phy_ip is None:
            log.warning(
                "Could not find a valid IP on the bridge. The physical interface will be without IP!"
            )
        else:
            log.debug("Found IP %s on the bridge." % str(phy_ip))

    #FIXME: Not sure if this is still needed or not
    # Using IPRoute and IPDB at the same time feels very ugly anyway..
    #ipdb.commit()
    #ipdb.release()

    ip = IPRoute()

    ip.link('del', index=ip.link_lookup(ifname=br_name)[0])

    if phy_eth is not None and phy_ip is not None:

        log.info("Setting %s on %s." % ('%s/%s' %
                                        (phy_ip[0], phy_ip[1]), phy_eth))

        with IPDB() as ipdb:
            with ipdb.interfaces[phy_eth] as eth:
                eth.add_ip('%s/%s' % (phy_ip[0], phy_ip[1]))

    ip.close()

    return True
Exemplo n.º 23
0
 def test_simple(self):
     ip = IPRoute()
     ip.close()
Exemplo n.º 24
0
    def __init__(self,
                 log_level: int = INFO,
                 plugins_to_load: List[str] = None,
                 custom_cp: bool = True):
        # Initializing logger
        self.__logger = getLogger(self.__class__.__name__)
        self.__logger.setLevel(log_level)
        ch = StreamHandler()
        ch.setLevel(log_level)
        ch.setFormatter(
            Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
        self.__logger.addHandler(ch)

        # Initializing local variables
        # TODO: add lock to instances map, clusters and programs
        self.__declarations: Dict[str, PluginConfig] = {}
        self.__programs: Dict[int, InterfaceHolder] = {}
        self.__probes: Dict[str, Dict[str, Plugin]] = {}
        self.__clusters: Dict[str, Cluster] = {}
        self.__custom_cp: bool = custom_cp
        self.__is_destroyed: bool = False

        # Initialize IpRoute and check whether there's another instance of the
        # framework running
        self.__ip: IPRoute = IPRoute()

        try:
            self.__ip.link("add", ifname="DeChainy", kind="dummy")
        except NetlinkError as e:
            self.__is_destroyed = True
            err, _ = e.args
            self.__logger.error(
                "Either another instance of DeChainy is running, or the previous one has not terminated correctly."
                "In the latter case, try 'sudo ip link del DeChainy', and 'sudo tc qdisc del dev <interface> clsact'"
                "for every interface you used before." if err ==
                17 else "Need sudo privileges to run.")
            exit(1)

        # Compiling startup program with buffers
        self.__startup: BPF = BPF(text=get_startup_code())
        self.__startup['control_plane'].open_perf_buffer(self.__parse_packet)
        self.__startup['log_buffer'].open_perf_buffer(self.__log_function)
        Thread(target=self.__start_poll, args=(), daemon=True).start()
        register(self.__del__)

        # Verifying received plugins_to_load, else load all plugins
        default_plugins = [
            x.__name__.lower() for x in plugins.Plugin.__subclasses__()
        ]
        if plugins_to_load:
            for plugin in plugins_to_load:
                if plugin not in default_plugins:
                    self.__log_and_raise(
                        f'Plugin {plugin} not found, unable to load',
                        exceptions.PluginNotFoundException)
        else:
            plugins_to_load = default_plugins

        base_dir = dirname(__file__)
        # For each plugin to load, retrieve:
        # - Class declaration
        # - Ingress and Egress code if the probe is not Programmable like Adaptmon
        for plugin_name in plugins_to_load:
            class_def = getattr(plugins, plugin_name.capitalize())
            self.__probes[plugin_name] = {}
            codes = {"ingress": None, "egress": None}
            path = f'{base_dir}/sourcebpf/{plugin_name}.c'
            if not class_def.is_programmable() and isfile(path):
                with open(path, 'r') as fp:
                    code = fp.read()
                for hook in class_def.accepted_hooks():
                    codes[hook] = code
                self.__logger.info(
                    f'Loaded BPF code from file for Plugin {plugin_name}')
            self.__declarations[plugin_name] = PluginConfig(
                class_def, codes["ingress"], codes["egress"])
Exemplo n.º 25
0
 def test_fileno_fail(self):
     require_python(2)
     try:
         IPRoute(fileno=13)
     except NotImplementedError:
         pass
Exemplo n.º 26
0
def remove_rt(sig, fr):
    ipr = IPRoute()
    idx = ipr.link_lookup(ifname=iface)[0]
    ipr.route("del", dst=sid, oif=idx)
    sys.exit(0)
Exemplo n.º 27
0
#!/usr/bin/python
'''
Sample client script.

Connects to a netlink proxy on the port 7000 useng TLS.

You have to generate keys prior to start it. The easiest way is
to use OpnVPN's pkitool
'''

from pyroute2 import IPRoute
from pprint import pprint

ip = IPRoute(host='tls://localhost:7000',
             key='client.key',
             cert='client.crt',
             ca='ca.crt')

pprint(ip.get_addr())
ip.release()
Exemplo n.º 28
0
 def setup(self):
     self.ip = IPRoute()
     self.names = []
Exemplo n.º 29
0
from bcc import BPF
from builtins import input
from ctypes import c_int
from pyroute2 import IPRoute, IPDB
from simulation import Simulation
from netaddr import IPAddress
ipr = IPRoute()
ipdb = IPDB(nl=ipr)

num_hosts = 2
null = open("/dev/null", "w")

class BridgeSimulation(Simulation):
    def __init__(self, ipdb):
        super(BridgeSimulation, self).__init__(ipdb)

    def start(self):
        # Ingress = attached to tc ingress class on bridge
        # Egress = attached to tc engress class on namespace (outside) interface
        # Loading bpf functions/maps.
        bridge_code = BPF(src_file="bridge.c")
        ingress_fn = bridge_code.load_func("handle_ingress", BPF.SCHED_CLS)
        egress_fn  = bridge_code.load_func("handle_egress", BPF.SCHED_CLS)
        mac2host   = bridge_code.get_table("mac2host")
        conf       = bridge_code.get_table("conf")

        # Creating dummy interface behind which ebpf code will do bridging.
        ebpf_bridge = ipdb.create(ifname="ebpf_br", kind="dummy").up().commit()
        ipr.tc("add", "ingress", ebpf_bridge.index, "ffff:")
        ipr.tc("add-filter", "bpf", ebpf_bridge.index, ":1", fd=egress_fn.fd,
           name=egress_fn.name, parent="ffff:", action="drop", classid=1)
Exemplo n.º 30
0
    def test_freeze(self):
        require_user('root')

        interface = self.ip.interfaces[self.ifd]

        # set up the interface
        with interface as i:
            i.add_ip('172.16.0.1/24')
            i.add_ip('172.16.1.1/24')
            i.up()

        # check
        assert ('172.16.0.1', 24) in interface.ipaddr
        assert ('172.16.1.1', 24) in interface.ipaddr
        assert interface.flags & 1

        # assert routine
        def probe():
            # The freeze results are dynamic: it is not a real freeze,
            # it is a restore routine. So it takes time for results
            # to stabilize
            err = None
            for _ in range(3):
                err = None
                interface.ipaddr.set_target(
                    (('172.16.0.1', 24), ('172.16.1.1', 24)))
                interface.ipaddr.target.wait()
                try:
                    assert ('172.16.0.1', 24) in interface.ipaddr
                    assert ('172.16.1.1', 24) in interface.ipaddr
                    assert interface.flags & 1
                    break
                except AssertionError as e:
                    err = e
                    continue
                except Exception as e:
                    err = e
                    break
            if err is not None:
                interface.unfreeze()
                i2.close()
                raise err

        # freeze
        interface.freeze()

        # change the interface somehow
        i2 = IPRoute()
        i2.addr('delete', interface.index, '172.16.0.1', 24)
        i2.addr('delete', interface.index, '172.16.1.1', 24)
        probe()

        # unfreeze
        self.ip.interfaces[self.ifd].unfreeze()

        try:
            i2.addr('delete', interface.index, '172.16.0.1', 24)
            i2.addr('delete', interface.index, '172.16.1.1', 24)
        except:
            pass
        finally:
            i2.close()

        # should be up, but w/o addresses
        interface.ipaddr.set_target(set())
        interface.ipaddr.target.wait(3)
        assert ('172.16.0.1', 24) not in self.ip.interfaces[self.ifd].ipaddr
        assert ('172.16.1.1', 24) not in self.ip.interfaces[self.ifd].ipaddr
        assert self.ip.interfaces[self.ifd].flags & 1