def connectnode(self, ifname, othernode, otherifname): """ Connect a node. :param str ifname: name of interface to connect :param core.nodes.base.CoreNode othernode: node to connect to :param str otherifname: interface name to connect to :return: nothing """ tmplen = 8 tmp1 = "tmp." + "".join( [random.choice(string.ascii_lowercase) for _ in range(tmplen)] ) tmp2 = "tmp." + "".join( [random.choice(string.ascii_lowercase) for _ in range(tmplen)] ) self.net_client.create_veth(tmp1, tmp2) self.net_client.device_ns(tmp1, str(self.pid)) self.node_net_client.device_name(tmp1, ifname) interface = CoreInterface(node=self, name=ifname, mtu=_DEFAULT_MTU) self.addnetif(interface, self.newifindex()) self.net_client.device_ns(tmp2, str(othernode.pid)) othernode.node_net_client.device_name(tmp2, otherifname) other_interface = CoreInterface( node=othernode, name=otherifname, mtu=_DEFAULT_MTU ) othernode.addnetif(other_interface, othernode.newifindex())
def __init__(self, session, _id=None, name=None, mtu=1500, start=True, server=None): """ Create an RJ45Node instance. :param core.emulator.session.Session session: core session instance :param int _id: node id :param str name: node name :param mtu: rj45 mtu :param bool start: start flag :param core.emulator.distributed.DistributedServer server: remote server node will run on, default is None for localhost """ CoreNodeBase.__init__(self, session, _id, name, start, server) CoreInterface.__init__(self, session, self, name, mtu, server) self.up = False self.lock = threading.RLock() self.ifindex = None # the following are PyCoreNetIf attributes self.transport_type = "raw" self.localname = name self.old_up = False self.old_addrs = [] if start: self.startup()
def adoptnetif( self, netif: CoreInterface, ifindex: int, hwaddr: str, addrlist: List[str] ) -> None: """ When a link message is received linking this node to another part of the emulation, no new interface is created; instead, adopt the GreTap netif as the node interface. """ netif.name = f"gt{ifindex}" netif.node = self self.addnetif(netif, ifindex) # use a more reasonable name, e.g. "gt0" instead of "gt.56286.150" if self.up: self.net_client.device_down(netif.localname) self.net_client.device_name(netif.localname, netif.name) netif.localname = netif.name if hwaddr: self.sethwaddr(ifindex, hwaddr) for addr in utils.make_tuple(addrlist): self.addaddr(ifindex, addr) if self.up: self.net_client.device_up(netif.localname)
def __init__( self, session: "Session", _id: int = None, name: str = None, mtu: int = 1500, server: DistributedServer = None, ) -> None: """ Create an RJ45Node instance. :param session: core session instance :param _id: node id :param name: node name :param mtu: rj45 mtu :param server: remote server node will run on, default is None for localhost """ super().__init__(session, _id, name, server) self.iface = CoreInterface(session, self, name, name, mtu, server) self.iface.transport_type = TransportType.RAW self.lock: threading.RLock = threading.RLock() self.iface_id: Optional[int] = None self.old_up: bool = False self.old_addrs: List[Tuple[str, Optional[str]]] = []
def detachnet(self): """ Detach a network. :return: nothing """ CoreInterface.detachnet(self)
def attachnet(self, net): """ Attach a network. :param core.coreobj.PyCoreNet net: network to attach :return: nothing """ CoreInterface.attachnet(self, net)
def attachnet(self, net: CoreNetworkBase) -> None: """ Attach a network. :param net: network to attach :return: nothing """ CoreInterface.attachnet(self, net)
def build_platform_xml( emane_manager: "EmaneManager", control_net: CtrlNet, emane_net: EmaneNet, iface: CoreInterface, nem_id: int, ) -> None: """ Create platform xml for a specific node. :param emane_manager: emane manager with emane configurations :param control_net: control net node for this emane network :param emane_net: emane network associated with interface :param iface: interface running emane :param nem_id: nem id to use for this interface :return: the next nem id that can be used for creating platform xml files """ # build nem xml nem_definition = nem_file_name(iface) nem_element = etree.Element( "nem", id=str(nem_id), name=iface.localname, definition=nem_definition ) # check if this is an external transport, get default config if an interface # specific one does not exist config = emane_manager.get_iface_config(emane_net, iface) if is_external(config): nem_element.set("transport", "external") platform_endpoint = "platformendpoint" add_param(nem_element, platform_endpoint, config[platform_endpoint]) transport_endpoint = "transportendpoint" add_param(nem_element, transport_endpoint, config[transport_endpoint]) else: transport_name = transport_file_name(iface) transport_element = etree.SubElement( nem_element, "transport", definition=transport_name ) add_param(transport_element, "device", iface.name) transport_configs = {"otamanagerdevice", "eventservicedevice"} platform_element = etree.Element("platform") for configuration in emane_manager.emane_config.emulator_config: name = configuration.id if iface.is_raw() and name in transport_configs: value = control_net.brname else: value = emane_manager.get_config(name) add_param(platform_element, name, value) platform_element.append(nem_element) mac = _MAC_PREFIX + ":00:00:" mac += f"{(nem_id >> 8) & 0xFF:02X}:{nem_id & 0xFF:02X}" iface.set_mac(mac) doc_name = "platform" file_name = f"{iface.name}-platform.xml" create_iface_file(iface, platform_element, doc_name, file_name)
def install_iface(self, iface: CoreInterface, config: Dict[str, str]) -> None: external = config.get("external", "0") if isinstance(iface, TunTap) and external == "0": iface.set_ips() # at this point we register location handlers for generating # EMANE location events if self.genlocationevents(): iface.poshook = self.set_nem_position iface.setposition()
def install_iface(self, emane_net: EmaneNet, iface: CoreInterface) -> None: config = self.get_iface_config(emane_net, iface) external = config.get("external", "0") if isinstance(iface, TunTap) and external == "0": iface.set_ips() # at this point we register location handlers for generating # EMANE location events if self.genlocationevents(): iface.poshook = emane_net.setnemposition iface.setposition()
def attach(self, iface: CoreInterface) -> None: """ Attach a network interface. :param iface: network interface :return: nothing """ super().attach(iface) if self.model: iface.poshook = self.model.position_callback iface.setposition()
def deladdr(self, addr: str) -> None: """ Delete address from network interface. :param addr: address to delete :return: nothing :raises CoreCommandError: when there is a command exception """ if self.up: self.net_client.delete_address(self.name, str(addr)) CoreInterface.deladdr(self, addr)
def attach(self, netif: CoreInterface) -> None: """ Attach a network interface. :param netif: network interface :return: nothing """ super().attach(netif) if self.model: netif.poshook = self.model.position_callback netif.setposition()
def setposition(self, x: float = None, y: float = None, z: float = None) -> bool: """ Uses setposition from both parent classes. :param x: x position :param y: y position :param z: z position :return: True if position changed, False otherwise """ result = CoreNodeBase.setposition(self, x, y, z) CoreInterface.setposition(self, x, y, z) return result
def addaddr(self, addr: str) -> None: """ Add address to to network interface. :param addr: address to add :return: nothing :raises CoreCommandError: when there is a command exception """ addr = utils.validate_ip(addr) if self.up: self.net_client.create_address(self.name, addr) CoreInterface.addaddr(self, addr)
def addaddr(self, addr): """ Add address to to network interface. :param str addr: address to add :return: nothing :raises CoreCommandError: when there is a command exception """ if self.up: self.net_client.create_address(self.name, str(addr)) CoreInterface.addaddr(self, addr)
def setposition(self, x=None, y=None, z=None): """ Uses setposition from both parent classes. :param float x: x position :param float y: y position :param float z: z position :return: True if position changed, False otherwise :rtype: bool """ result = CoreNodeBase.setposition(self, x, y, z) CoreInterface.setposition(self, x, y, z) return result
def deladdr(self, addr): """ Delete address from network interface. :param str addr: address to delete :return: nothing :raises CoreCommandError: when there is a command exception """ if self.up: utils.check_cmd( [constants.IP_BIN, "addr", "del", str(addr), "dev", self.name]) CoreInterface.deladdr(self, addr)
def attach(self, netif: CoreInterface) -> None: """ Attach a network interface. :param netif: network interface :return: nothing """ super().attach(netif) if self.model: netif.poshook = self.model.position_callback if netif.node is None: return x, y, z = netif.node.position.get() # invokes any netif.poshook netif.setposition(x, y, z)
def install_iface(self, iface: CoreInterface) -> None: emane_net = iface.net if not isinstance(emane_net, EmaneNet): raise CoreError( f"emane interface not connected to emane net: {emane_net.name}" ) config = self.get_iface_config(emane_net, iface) external = config.get("external", "0") if isinstance(iface, TunTap) and external == "0": iface.set_ips() # at this point we register location handlers for generating # EMANE location events if self.genlocationevents(): iface.poshook = emane_net.setnemposition iface.setposition()
def iface_to_data(iface: CoreInterface) -> InterfaceData: ip4 = iface.get_ip4() ip4_addr = str(ip4.ip) if ip4 else None ip4_mask = ip4.prefixlen if ip4 else None ip6 = iface.get_ip6() ip6_addr = str(ip6.ip) if ip6 else None ip6_mask = ip6.prefixlen if ip6 else None return InterfaceData( id=iface.node_id, name=iface.name, mac=str(iface.mac), ip4=ip4_addr, ip4_mask=ip4_mask, ip6=ip6_addr, ip6_mask=ip6_mask, )
def create_transport_xml(iface: CoreInterface, config: Dict[str, str]) -> None: """ Build transport xml file for node and transport type. :param iface: interface to build transport xml for :param config: all current configuration values :return: nothing """ transport_type = iface.transport_type transport_element = etree.Element( "transport", name=f"{transport_type.value.capitalize()} Transport", library=f"trans{transport_type.value.lower()}", ) add_param(transport_element, "bitrate", "0") # get emane model cnfiguration flowcontrol = config.get("flowcontrolenable", "0") == "1" if iface.is_virtual(): device_path = "/dev/net/tun_flowctl" if not os.path.exists(device_path): device_path = "/dev/net/tun" add_param(transport_element, "devicepath", device_path) if flowcontrol: add_param(transport_element, "flowcontrolenable", "on") doc_name = "transport" transport_name = transport_file_name(iface) create_iface_file(iface, transport_element, doc_name, transport_name)
def connectnode(self, ifname, othernode, otherifname): """ Connect a node. :param str ifname: name of interface to connect :param core.nodes.CoreNodeBase othernode: node to connect to :param str otherifname: interface name to connect to :return: nothing """ tmplen = 8 tmp1 = "tmp." + "".join( [random.choice(string.ascii_lowercase) for _ in range(tmplen)]) tmp2 = "tmp." + "".join( [random.choice(string.ascii_lowercase) for _ in range(tmplen)]) utils.check_cmd([ constants.IP_BIN, "link", "add", "name", tmp1, "type", "veth", "peer", "name", tmp2, ]) utils.check_cmd( [constants.IP_BIN, "link", "set", tmp1, "netns", str(self.pid)]) self.network_cmd( [constants.IP_BIN, "link", "set", tmp1, "name", ifname]) interface = CoreInterface(node=self, name=ifname, mtu=_DEFAULT_MTU) self.addnetif(interface, self.newifindex()) utils.check_cmd([ constants.IP_BIN, "link", "set", tmp2, "netns", str(othernode.pid) ]) othernode.network_cmd( [constants.IP_BIN, "link", "set", tmp2, "name", otherifname]) other_interface = CoreInterface(node=othernode, name=otherifname, mtu=_DEFAULT_MTU) othernode.addnetif(other_interface, othernode.newifindex())
def nem_file_name(iface: CoreInterface) -> str: """ Return the string name for the NEM XML file, e.g. "eth0-nem.xml" :param iface: interface running emane :return: nem xm file name """ append = "-raw" if iface.is_raw() else "" return f"{iface.name}-nem{append}.xml"
def detach(self, netif: CoreInterface) -> None: """ Detach network interface. :param netif: network interface to detach :return: nothing """ del self._netif[netif.netifi] netif.netifi = None with self._linked_lock: del self._linked[netif]
def detach(self, iface: CoreInterface) -> None: """ Detach network interface. :param iface: network interface to detach :return: nothing """ del self.ifaces[iface.net_id] iface.net_id = None with self._linked_lock: del self._linked[iface]
def addnetif(self, netif: CoreInterface, ifindex: int) -> None: """ Add network interface to node and set the network interface index if successful. :param netif: network interface to add :param ifindex: interface index :return: nothing """ if ifindex in self._netif: raise ValueError(f"ifindex {ifindex} already exists") self._netif[ifindex] = netif netif.netindex = ifindex
def adopt_iface(self, iface: CoreInterface, iface_id: int, mac: str, ips: List[str]) -> None: """ When a link message is received linking this node to another part of the emulation, no new interface is created; instead, adopt the GreTap interface as the node interface. """ iface.name = f"gt{iface_id}" iface.node = self self.add_iface(iface, iface_id) # use a more reasonable name, e.g. "gt0" instead of "gt.56286.150" if self.up: self.net_client.device_down(iface.localname) self.net_client.device_name(iface.localname, iface.name) iface.localname = iface.name if mac: self.set_mac(iface_id, mac) for ip in ips: self.add_ip(iface_id, ip) if self.up: self.net_client.device_up(iface.localname)
def add_iface(self, iface: CoreInterface, iface_id: int) -> None: """ Add network interface to node and set the network interface index if successful. :param iface: network interface to add :param iface_id: interface id :return: nothing """ if iface_id in self.ifaces: raise CoreError(f"interface({iface_id}) already exists") self.ifaces[iface_id] = iface iface.node_id = iface_id
def attach(self, iface: CoreInterface) -> None: """ Attach network interface. :param iface: network interface to attach :return: nothing """ i = self.next_iface_id() self.ifaces[i] = iface iface.net_id = i with self._linked_lock: self._linked[iface] = {}