def put_dellink(self, msg, *argv, **kwarg): if self.ancient: # get the interface kind kind = compat_get_type(msg.get_attr('IFLA_IFNAME')) # not covered types pass to the system if kind not in ('bridge', 'bond'): return NetlinkSocket.put(self, msg, *argv, **kwarg) ## # otherwise, create a valid answer -- # NLMSG_ERROR with code 0 (no error) ## # FIXME: intercept and return valid RTM_NEWLINK ## seq = kwarg.get('msg_seq', 0) response = ifinfmsg() response['header']['type'] = NLMSG_ERROR response['header']['sequence_number'] = seq # route the request if kind == 'bridge': compat_del_bridge(msg.get_attr('IFLA_IFNAME')) elif kind == 'bond': compat_del_bond(msg.get_attr('IFLA_IFNAME')) # while RTM_NEWLINK is not intercepted -- sleep time.sleep(_ANCIENT_BARRIER) response.encode() self.backlog[seq] = [response] else: # else just send the packet NetlinkSocket.put(self, msg, *argv, **kwarg)
def put_setlink(self, msg, *argv, **kwarg): # is it a port setup? master = msg.get_attr('IFLA_MASTER') if self.ancient and master is not None: seq = kwarg.get('msg_seq', 0) response = ifinfmsg() response['header']['type'] = NLMSG_ERROR response['header']['sequence_number'] = seq ifname = self.name_by_id(msg['index']) if master == 0: # port delete # 1. get the current master m = self.name_by_id(compat_get_master(ifname)) # 2. get the type of the master kind = compat_get_type(m) # 3. delete the port if kind == 'bridge': compat_del_bridge_port(m, ifname) elif kind == 'bond': compat_del_bond_port(m, ifname) else: # port add # 1. get the name of the master m = self.name_by_id(master) # 2. get the type of the master kind = compat_get_type(m) # 3. add the port if kind == 'bridge': compat_add_bridge_port(m, ifname) elif kind == 'bond': compat_add_bond_port(m, ifname) response.encode() self.backlog[seq] = [response] NetlinkSocket.put(self, msg, *argv, **kwarg)
def tunnel_listp(devname): s = NetlinkSocket() s.bind() msg = ifinfmsg() nonce = 123 # fill the protocol-specific fields msg['index'] = 85 # index of the interface msg['family'] = 18 # address family # attach NLA -- it MUST be a list / mutable msg['attrs'] = [['CTRL_ATTR_FAMILY_NAME', "gtp0"]] # fill generic netlink fields msg['header']['sequence_number'] = nonce # an unique seq number msg['header']['pid'] = os.getpid() msg['header']['type'] = GENL_ID_CTRL msg['header']['flags'] = NLM_F_REQUEST |\ NLM_F_ACK # encode the packet msg.encode() # send the buffer s.sendto(msg.data, (0, 0)) s.get() s.close() l = 1 print("tthis is a list; {}".format(l)) return list
def put(self, *argv, **kwarg): ''' Proxy `put()` request ''' if argv[1] in self.put_map: self.put_map[argv[1]](*argv, **kwarg) else: NetlinkSocket.put(self, *argv, **kwarg)
def bind(self, proto, msg_class, groups=0, pid=0): ''' Bind the socket and performs generic netlink proto lookup. The `proto` parameter is a string, like "TASKSTATS", `msg_class` is a class to parse messages with. ''' NetlinkSocket.bind(self, groups, pid) self.marshal.msg_map[GENL_ID_CTRL] = ctrlmsg self.prid = self.get_protocol_id(proto) self.marshal.msg_map[self.prid] = msg_class
def __init__(self): NetlinkSocket.__init__(self, NETLINK_ROUTE) self.marshal = MarshalRtnl() self.get_map = {RTM_NEWLINK: self.get_newlink} self.put_map = {RTM_NEWLINK: self.put_newlink, RTM_SETLINK: self.put_setlink, RTM_DELLINK: self.put_dellink, RTM_SETBRIDGE: self.put_setbr, RTM_GETBRIDGE: self.put_getbr, RTM_SETBOND: self.put_setbo, RTM_GETBOND: self.put_getbo} self.ancient = ANCIENT
def test_ports_auto(self): # create two sockets s1 = NetlinkSocket() s2 = NetlinkSocket() # both bind() should succeed s1.bind() s2.bind() # check that ports are different assert s1.port != s2.port s1.close() s2.close()
def bind(self, mode=IPQ_COPY_PACKET): ''' Bind the socket and performs IPQ mode configuration. The only parameter is mode, the default value is IPQ_COPY_PACKET (copy all the packet data). ''' NetlinkSocket.bind(self, groups=0, pid=0) self.register_policy(MarshalIPQ.msg_map) msg = ipq_mode_msg() msg['value'] = mode msg['range'] = IPQ_MAX_PAYLOAD msg['header']['type'] = IPQM_MODE msg['header']['flags'] = NLM_F_REQUEST msg.encode() self.sendto(msg.data, (0, 0))
def bind(self, proto, msg_class, groups=0, pid=None, **kwarg): ''' Bind the socket and performs generic netlink proto lookup. The `proto` parameter is a string, like "TASKSTATS", `msg_class` is a class to parse messages with. ''' NetlinkSocket.bind(self, groups, pid, **kwarg) self.marshal.msg_map[GENL_ID_CTRL] = ctrlmsg msg = self.discovery(proto) self.prid = msg.get_attr('CTRL_ATTR_FAMILY_ID') self.mcast_groups = \ dict([(x.get_attr('CTRL_ATTR_MCAST_GRP_NAME'), x.get_attr('CTRL_ATTR_MCAST_GRP_ID')) for x in msg.get_attr('CTRL_ATTR_MCAST_GROUPS', [])]) self.marshal.msg_map[self.prid] = msg_class
def get(self, *argv, **kwarg): ''' Proxy `get()` request ''' msgs = NetlinkSocket.get(self, *argv, **kwarg) for msg in msgs: mtype = msg['header']['type'] if mtype in self.get_map: self.get_map[mtype](msg) return msgs
def test_ports_fail(self): s1 = NetlinkSocket(port=0x10) s2 = NetlinkSocket(port=0x10) # check if ports are set assert s1.port == s2.port # bind the first socket, must succeed s1.bind() # bind the second, must fail try: s2.bind() except socket.error as e: # but it must fail only with errno == 98 if e.errno == 98: pass # check the first socket is bound assert s1.getsockname()[0] != 0 # check the second socket is not bound assert s2.getsockname()[0] == 0 s1.close()
def test_no_free_ports(self): require_user("root") # create and bind 1024 sockets ports = [NetlinkSocket() for x in range(1024)] for port in ports: port.bind() # create an extra socket fail = NetlinkSocket() try: # bind must fail with KeyError: no free ports available fail.bind() except KeyError: pass # cleanup for port in ports: port.close() try: # failed socket shouldn't permit close() fail.close() except AssertionError: pass
def test_no_free_ports(self): require_user('root') # create and bind 1024 sockets ports = [NetlinkSocket() for x in range(1024)] for port in ports: port.bind() # create an extra socket fail = NetlinkSocket() try: # bind must fail with KeyError: no free ports available fail.bind() except KeyError: pass # cleanup for port in ports: port.close() try: # failed socket shouldn't permit close() fail.close() except AssertionError: pass