Example #1
0
def convert_if_announcemsg(msg):
    ret = ifinfmsg()
    ret['header']['type'] = RTNL_DELLINK if msg['ifan_what'] else RTNL_NEWLINK
    ret['index'] = msg['ifan_index']
    ret['attrs'] = [['IFLA_IFNAME', msg['ifan_name']]]
    del ret['value']
    return ret
Example #2
0
    def _GetAdaptersInfo(self):
        ret = {'interfaces': [], 'addresses': []}

        # prepare buffer
        buf = ctypes.create_string_buffer(15000)
        buf_len = ctypes.c_ulong(15000)
        (
            ctypes.windll.iphlpapi.GetAdaptersInfo(
                ctypes.byref(buf), ctypes.byref(buf_len)
            )
        )
        adapter = IP_ADAPTER_INFO.from_address(ctypes.addressof(buf))
        while True:
            mac = ':'.join(['%02x' % x for x in adapter.Address][:6])
            ifname = ctypes.string_at(
                ctypes.addressof(adapter.AdapterName)
            ).decode('utf-8')
            spec = {
                'index': adapter.Index,
                'attrs': (['IFLA_ADDRESS', mac], ['IFLA_IFNAME', ifname]),
            }

            msg = ifinfmsg().load(spec)
            del msg['value']
            ret['interfaces'].append(msg)

            ipaddr = adapter.IpAddressList
            while True:
                addr = ctypes.string_at(
                    ctypes.addressof(ipaddr.IpAddress)
                ).decode('utf-8')
                mask = ctypes.string_at(
                    ctypes.addressof(ipaddr.IpMask)
                ).decode('utf-8')
                spec = {
                    'index': adapter.Index,
                    'family': AF_INET,
                    'prefixlen': dqn2int(mask),
                    'attrs': (
                        ['IFA_ADDRESS', addr],
                        ['IFA_LOCAL', addr],
                        ['IFA_LABEL', ifname],
                    ),
                }
                msg = ifaddrmsg().load(spec)
                del msg['value']
                ret['addresses'].append(msg)
                if ipaddr.Next:
                    ipaddr = ipaddr.Next.contents
                else:
                    break

            if adapter.Next:
                adapter = adapter.Next.contents
            else:
                break
        return ret
Example #3
0
 def _flush_mnl(self):
     if self.mnl is not None:
         # terminate the main loop
         for t in range(3):
             try:
                 msg = ifinfmsg()
                 msg['index'] = 1
                 msg.reset()
                 self.mnl.put(msg, RTM_GETLINK)
             except Exception as e:
                 log.error("shutdown error: %s", e)
Example #4
0
 def fake_zero_if(self):
     url = 'https://github.com/svinota/pyroute2/issues/737'
     zero_if = ifinfmsg()
     zero_if['index'] = 0
     zero_if['state'] = 'up'
     zero_if['flags'] = 1
     zero_if['header']['flags'] = 2
     zero_if['header']['type'] = 16
     zero_if['header']['target'] = self.target
     zero_if['event'] = 'RTM_NEWLINK'
     zero_if['attrs'] = [('IFLA_IFNAME', url),
                         ('IFLA_ADDRESS', '00:00:00:00:00:00')]
     zero_if.encode()
     self.evq.put([
         zero_if,
     ])
Example #5
0
 def get_links(self, *argv, **kwarg):
     ret = []
     data = self._ifc.run()
     parsed = self._ifc.parse(data)
     for name, spec in parsed['links'].items():
         msg = ifinfmsg().load(spec)
         msg['header']['type'] = RTM_NEWLINK
         del msg['value']
         flags = msg['flags']
         new_flags = 0
         for value, name in IFF_VALUES.items():
             if value & flags and name in IFF_NAMES:
                 new_flags |= IFF_NAMES[name]
         msg['flags'] = new_flags
         ret.append(msg)
     return ret
Example #6
0
def proxy_dellink(imsg, nl):
    orig_msg = ifinfmsg(imsg.data)
    orig_msg.decode()

    # get full interface description
    msg = nl.get_links(orig_msg['index'])[0]
    msg['header']['type'] = orig_msg['header']['type']

    # get the interface kind
    kind = None
    li = msg.get_attr('IFLA_LINKINFO')
    if li is not None:
        kind = li.get_attr('IFLA_INFO_KIND')

    # team interfaces can be stopped by a normal RTM_DELLINK
    if kind == 'bond' and not nl.capabilities['create_bond']:
        return compat_del_bond(msg)
    elif kind == 'bridge' and not nl.capabilities['create_bridge']:
        return compat_del_bridge(msg)

    return {'verdict': 'forward', 'data': imsg.data}
Example #7
0
def proxy_newlink(imsg, nl):
    msg = ifinfmsg(imsg.data)
    msg.decode()
    kind = None

    # get the interface kind
    linkinfo = msg.get_attr('IFLA_LINKINFO')
    if linkinfo is not None:
        kind = [x[1] for x in linkinfo['attrs'] if x[0] == 'IFLA_INFO_KIND']
        if kind:
            kind = kind[0]

    if kind == 'tuntap':
        return manage_tuntap(msg)
    elif kind == 'team':
        return manage_team(msg)
    elif kind == 'bond' and not nl.capabilities['create_bond']:
        return compat_create_bond(msg)
    elif kind == 'bridge' and not nl.capabilities['create_bridge']:
        return compat_create_bridge(msg)

    return {'verdict': 'forward', 'data': imsg.data}
Example #8
0
def proxy_setlink(imsg, nl):
    def get_interface(index):
        msg = nl.get_links(index)[0]
        try:
            kind = msg.get_attr('IFLA_LINKINFO').get_attr('IFLA_INFO_KIND')
        except AttributeError:
            kind = 'unknown'
        return {
            'ifname': msg.get_attr('IFLA_IFNAME'),
            'master': msg.get_attr('IFLA_MASTER'),
            'kind': kind,
        }

    msg = ifinfmsg(imsg.data)
    msg.decode()
    forward = True

    kind = None
    infodata = None

    ifname = (msg.get_attr('IFLA_IFNAME')
              or get_interface(msg['index'])['ifname'])
    linkinfo = msg.get_attr('IFLA_LINKINFO')
    if linkinfo:
        kind = linkinfo.get_attr('IFLA_INFO_KIND')
        infodata = linkinfo.get_attr('IFLA_INFO_DATA')

    if kind in ('bond', 'bridge') and infodata is not None:
        code = 0
        #
        if kind == 'bond':
            func = compat_set_bond
        elif kind == 'bridge':
            func = compat_set_bridge
        #
        for (cmd, value) in infodata.get('attrs', []):
            cmd = infodata.nla2name(cmd)
            code = func(ifname, cmd, value) or code
        #
        if code:
            err = OSError()
            err.errno = code
            raise err

    # is it a port setup?
    master = msg.get_attr('IFLA_MASTER')
    if master is not None:

        if master == 0:
            # port delete
            # 1. get the current master
            iface = get_interface(msg['index'])
            master = get_interface(iface['master'])
            cmd = 'del'
        else:
            # port add
            # 1. get the master
            master = get_interface(master)
            cmd = 'add'

        # 2. manage the port
        forward_map = {
            'team': manage_team_port,
            'bridge': compat_bridge_port,
            'bond': compat_bond_port,
        }
        if master['kind'] in forward_map:
            func = forward_map[master['kind']]
            forward = func(cmd, master['ifname'], ifname, nl)

    if forward is not None:
        return {'verdict': 'forward', 'data': imsg.data}