Exemplo n.º 1
0
    def validate_service(self, node: CoreNode, service: "CoreService") -> int:
        """
        Run the validation command(s) for a service.

        :param node: node to validate service for
        :param service: service to validate
        :return: service validation status
        """
        logging.debug("validating node(%s) service(%s)", node.name, service.name)
        cmds = service.validate
        if not service.custom:
            cmds = service.get_validate(node)

        status = 0
        for cmd in cmds:
            logging.debug("validating service(%s) using: %s", service.name, cmd)
            try:
                node.cmd(cmd)
            except CoreCommandError as e:
                logging.debug(
                    "node(%s) service(%s) validate failed", node.name, service.name
                )
                logging.debug("cmd(%s): %s", e.cmd, e.output)
                status = -1
                break

        return status
Exemplo n.º 2
0
Arquivo: obj.py Projeto: yanhc519/core
 def __init__(self, *args, **kwds):
     ns.network.Node.__init__(self)
     # ns-3 ID starts at 0, CORE uses 1
     _id = self.GetId() + 1
     if '_id' not in kwds:
         kwds['_id'] = _id
     CoreNode.__init__(self, *args, **kwds)
Exemplo n.º 3
0
    def create_service_files(self, node: CoreNode, service: "CoreService") -> None:
        """
        Creates node service files.

        :param node: node to reconfigure service for
        :param service: service to reconfigure
        :return: nothing
        """
        # get values depending on if custom or not
        config_files = service.configs
        if not service.custom:
            config_files = service.get_configs(node)

        for file_name in config_files:
            logging.debug(
                "generating service config custom(%s): %s", service.custom, file_name
            )
            if service.custom:
                cfg = service.config_data.get(file_name)
                if cfg is None:
                    cfg = service.generate_config(node, file_name)

                # cfg may have a file:/// url for copying from a file
                try:
                    if self.copy_service_file(node, file_name, cfg):
                        continue
                except IOError:
                    logging.exception("error copying service file: %s", file_name)
                    continue
            else:
                cfg = service.generate_config(node, file_name)

            node.nodefile(file_name, cfg)
Exemplo n.º 4
0
def ping(from_node: CoreNode, to_node: CoreNode, ip_prefixes: IpPrefixes):
    address = ip_prefixes.ip4_address(to_node.id)
    try:
        from_node.cmd(f"ping -c 1 {address}")
        status = 0
    except CoreCommandError as e:
        status = e.returncode
    return status
Exemplo n.º 5
0
 def emanerunning(self, node: CoreNode) -> bool:
     """
     Return True if an EMANE process associated with the given node is running,
     False otherwise.
     """
     args = "pkill -0 -x emane"
     try:
         node.cmd(args)
         result = True
     except CoreCommandError:
         result = False
     return result
Exemplo n.º 6
0
 def custom_iface(self, node: CoreNode, iface_data: InterfaceData) -> CoreInterface:
     # TUN/TAP is not ready for addressing yet; the device may
     #   take some time to appear, and installing it into a
     #   namespace after it has been bound removes addressing;
     #   save addresses with the interface now
     iface_id = node.newtuntap(iface_data.id, iface_data.name)
     node.attachnet(iface_id, self)
     iface = node.get_iface(iface_id)
     iface.set_mac(iface_data.mac)
     for ip in iface_data.get_ips():
         iface.add_ip(ip)
     if self.session.state == EventTypes.RUNTIME_STATE:
         self.session.emane.start_iface(self, iface)
     return iface
Exemplo n.º 7
0
    def generate_config(cls, node: CoreNode, filename: str) -> str:
        """
        Generate a startpcap.sh traffic logging script.
        """
        cfg = """
#!/bin/sh
# set tcpdump options here (see 'man tcpdump' for help)
# (-s snap length, -C limit pcap file length, -n disable name resolution)
DUMPOPTS="-s 12288 -C 10 -n"

if [ "x$1" = "xstart" ]; then

"""
        for iface in node.get_ifaces():
            if hasattr(iface, "control") and iface.control is True:
                cfg += "# "
            redir = "< /dev/null"
            cfg += "tcpdump ${DUMPOPTS} -w %s.%s.pcap -i %s %s &\n" % (
                node.name,
                iface.name,
                iface.name,
                redir,
            )
        cfg += """

elif [ "x$1" = "xstop" ]; then
    mkdir -p ${SESSION_DIR}/pcap
    mv *.pcap ${SESSION_DIR}/pcap
fi;
"""
        return cfg
Exemplo n.º 8
0
    def generate_config(cls, node: CoreNode, filename: str) -> str:
        """
        Generate a RADVD router advertisement daemon config file
        using the network address of each interface.
        """
        cfg = "# auto-generated by RADVD service (utility.py)\n"
        for iface in node.get_ifaces(control=False):
            prefixes = list(map(cls.subnetentry, iface.ips()))
            if len(prefixes) < 1:
                continue
            cfg += ("""\
interface %s
{
        AdvSendAdvert on;
        MinRtrAdvInterval 3;
        MaxRtrAdvInterval 10;
        AdvDefaultPreference low;
        AdvHomeAgentFlag off;
""" % iface.name)
            for prefix in prefixes:
                if prefix == "":
                    continue
                cfg += ("""\
        prefix %s
        {
                AdvOnLink on;
                AdvAutonomous on;
                AdvRouterAddr on;
        };
""" % prefix)
            cfg += "};\n"
        return cfg
Exemplo n.º 9
0
Arquivo: obj.py Projeto: yanhc519/core
    def newnetif(self,
                 net=None,
                 addrlist=None,
                 hwaddr=None,
                 ifindex=None,
                 ifname=None):
        """
        Add a network interface. If we are attaching to a CoreNs3Net, this
        will be a TunTap. Otherwise dispatch to CoreNode.newnetif().
        """
        if not addrlist:
            addrlist = []

        if not isinstance(net, CoreNs3Net):
            return CoreNode.newnetif(self, net, addrlist, hwaddr, ifindex,
                                     ifname)
        ifindex = self.newtuntap(ifindex=ifindex, ifname=ifname, net=net)
        self.attachnet(ifindex, net)
        netif = self.netif(ifindex)
        netif.sethwaddr(hwaddr)
        for addr in make_tuple(addrlist):
            netif.addaddr(addr)

        addrstr = netif.addrlist[0]
        (addr, mask) = addrstr.split('/')
        tap = net._tapdevs[netif]
        tap.SetAttribute(
            "IpAddress",
            ns.network.Ipv4AddressValue(ns.network.Ipv4Address(addr)))
        tap.SetAttribute(
            "Netmask",
            ns.network.Ipv4MaskValue(ns.network.Ipv4Mask("/" + mask)))
        ns.core.Simulator.Schedule(ns.core.Time('0'), netif.install)
        return ifindex
Exemplo n.º 10
0
 def generate_frr_config(cls, node: CoreNode) -> str:
     cfg = "router ospf6\n"
     rtrid = cls.router_id(node)
     cfg += "  router-id %s\n" % rtrid
     for iface in node.get_ifaces(control=False):
         cfg += "  interface %s area 0.0.0.0\n" % iface.name
     cfg += "!\n"
     return cfg
Exemplo n.º 11
0
def create_interface(node: CoreNode, network: CoreNetworkBase,
                     interface_data: InterfaceData):
    """
    Create an interface for a node on a network using provided interface data.

    :param node: node to create interface for
    :param network: network to associate interface with
    :param interface_data: interface data
    :return: created interface
    """
    node.newnetif(
        network,
        addrlist=interface_data.get_addresses(),
        hwaddr=interface_data.mac,
        ifindex=interface_data.id,
        ifname=interface_data.name,
    )
    return node.netif(interface_data.id)
Exemplo n.º 12
0
 def generate_config(cls, node: CoreNode, filename: str) -> str:
     cfg = "#!/bin/sh\n"
     cfg += "# auto-generated by StaticRoute service (utility.py)\n#\n"
     cfg += "# NOTE: this service must be customized to be of any use\n"
     cfg += "#       Below are samples that you can uncomment and edit.\n#\n"
     for iface in node.get_ifaces(control=False):
         cfg += "\n".join(map(cls.routestr, iface.ips()))
         cfg += "\n"
     return cfg
Exemplo n.º 13
0
 def router_id(node: CoreNode) -> str:
     """
     Helper to return the first IPv4 address of a node as its router ID.
     """
     for iface in node.get_ifaces(control=False):
         ip4 = iface.get_ip4()
         if ip4:
             return str(ip4.ip)
     return "0.0.0.0"
Exemplo n.º 14
0
    def copy_service_file(self, node: CoreNode, filename: str, cfg: str) -> bool:
        """
        Given a configured service filename and config, determine if the
        config references an existing file that should be copied.
        Returns True for local files, False for generated.

        :param node: node to copy service for
        :param filename: file name for a configured service
        :param cfg: configuration string
        :return: True if successful, False otherwise
        """
        if cfg[:7] == "file://":
            src = cfg[7:]
            src = src.split("\n")[0]
            src = utils.expand_corepath(src, node.session, node)
            # TODO: glob here
            node.nodefilecopy(filename, src, mode=0o644)
            return True
        return False
Exemplo n.º 15
0
 def generate_frr_config(cls, node: CoreNode) -> str:
     cfg = "router ospf\n"
     rtrid = cls.router_id(node)
     cfg += "  router-id %s\n" % rtrid
     # network 10.0.0.0/24 area 0
     for iface in node.get_ifaces(control=False):
         for ip4 in iface.ip4s:
             cfg += f"  network {ip4} area 0\n"
     cfg += "!\n"
     return cfg
Exemplo n.º 16
0
 def generate_bird_iface_config(cls, node: CoreNode) -> str:
     """
     Use only bare interfaces descriptions in generated protocol
     configurations. This has the slight advantage of being the same
     everywhere.
     """
     cfg = ""
     for iface in node.get_ifaces(control=False):
         cfg += '        interface "%s";\n' % iface.name
     return cfg
Exemplo n.º 17
0
 def firstipv4prefix(node: CoreNode, prefixlen: int = 24) -> str:
     """
     Similar to QuaggaService.routerid(). Helper to return the first IPv4
     prefix of a node, using the supplied prefix length. This ignores the
     interface's prefix length, so e.g. '/32' can turn into '/24'.
     """
     for iface in node.get_ifaces(control=False):
         ip4 = iface.get_ip4()
         if ip4:
             return f"{ip4.ip}/{prefixlen}"
     return "0.0.0.0/%s" % prefixlen
Exemplo n.º 18
0
    def generatehtml(cls, node: CoreNode, filename: str) -> str:
        body = ("""\
<!-- generated by utility.py:HttpService -->
<h1>%s web server</h1>
<p>This is the default web page for this server.</p>
<p>The web server software is running but no content has been added, yet.</p>
""" % node.name)
        for iface in node.get_ifaces(control=False):
            body += "<li>%s - %s</li>\n" % (iface.name,
                                            [str(x) for x in iface.ips()])
        return "<html><body>%s</body></html>" % body
Exemplo n.º 19
0
 def get_startup(cls, node: CoreNode) -> Tuple[str, ...]:
     """
     Generate the appropriate command-line based on node interfaces.
     """
     cmd = cls.startup[0]
     ifaces = node.get_ifaces(control=False)
     if len(ifaces) > 0:
         iface_names = map(lambda x: x.name, ifaces)
         cmd += " -i "
         cmd += " -i ".join(iface_names)
     return (cmd, )
Exemplo n.º 20
0
    def generate_quagga_conf(cls, node: CoreNode) -> str:
        """
        Returns configuration file text. Other services that depend on zebra
        will have hooks that are invoked here.
        """
        # we could verify here that filename == Quagga.conf
        cfg = ""
        for iface in node.get_ifaces():
            cfg += "interface %s\n" % iface.name
            # include control interfaces in addressing but not routing daemons
            if iface.control:
                cfg += "  "
                cfg += "\n  ".join(map(cls.addrstr, iface.ips()))
                cfg += "\n"
                continue
            cfgv4 = ""
            cfgv6 = ""
            want_ipv4 = False
            want_ipv6 = False
            for s in node.services:
                if cls.name not in s.dependencies:
                    continue
                if not (isinstance(s, QuaggaService)
                        or issubclass(s, QuaggaService)):
                    continue
                iface_config = s.generate_quagga_iface_config(node, iface)
                if s.ipv4_routing:
                    want_ipv4 = True
                if s.ipv6_routing:
                    want_ipv6 = True
                    cfgv6 += iface_config
                else:
                    cfgv4 += iface_config

            if want_ipv4:
                cfg += "  "
                cfg += "\n  ".join(map(cls.addrstr, iface.ip4s))
                cfg += "\n"
                cfg += cfgv4
            if want_ipv6:
                cfg += "  "
                cfg += "\n  ".join(map(cls.addrstr, iface.ip6s))
                cfg += "\n"
                cfg += cfgv6
            cfg += "!\n"

        for s in node.services:
            if cls.name not in s.dependencies:
                continue
            if not (isinstance(s, QuaggaService)
                    or issubclass(s, QuaggaService)):
                continue
            cfg += s.generate_quagga_config(node)
        return cfg
Exemplo n.º 21
0
 def generate_config(cls, node: CoreNode, filename: str) -> str:
     cfg = "#!/bin/sh\n"
     cfg += "# auto-generated by DefaultMulticastRoute service (utility.py)\n"
     cfg += "# the first interface is chosen below; please change it "
     cfg += "as needed\n"
     for iface in node.get_ifaces(control=False):
         rtcmd = "ip route add 224.0.0.0/4 dev"
         cfg += "%s %s\n" % (rtcmd, iface.name)
         cfg += "\n"
         break
     return cfg
Exemplo n.º 22
0
    def service_reconfigure(self, node: CoreNode,
                            service: "CoreService") -> None:
        """
        Reconfigure a node service.

        :param node: node to reconfigure service for
        :param service: service to reconfigure
        :return: nothing
        """
        config_files = service.configs
        if not service.custom:
            config_files = service.get_configs(node)
        for file_name in config_files:
            file_path = Path(file_name)
            if file_name[:7] == "file:///":
                # TODO: implement this
                raise NotImplementedError
            cfg = service.config_data.get(file_name)
            if cfg is None:
                cfg = service.generate_config(node, file_name)
            node.create_file(file_path, cfg)
Exemplo n.º 23
0
 def generate_config(cls, node: CoreNode, filename: str) -> str:
     emane_manager = node.session.emane
     cfg = ""
     for iface in node.get_ifaces():
         if not isinstance(iface.net, EmaneNet):
             continue
         emane_net = iface.net
         config = emane_manager.get_iface_config(emane_net, iface)
         if emanexml.is_external(config):
             nem_id = emane_manager.get_nem_id(iface)
             cfg += f"emanegentransportxml {iface.name}-platform.xml\n"
             cfg += f"emanetransportd -r -l 0 -d transportdaemon{nem_id}.xml\n"
     return cfg
Exemplo n.º 24
0
    def stop_service(self, node: CoreNode, service: "CoreService") -> int:
        """
        Stop a service on a node.

        :param node: node to stop a service on
        :param service: service to stop
        :return: status for stopping the services
        """
        status = 0
        for args in service.shutdown:
            try:
                node.cmd(args)
            except CoreCommandError as e:
                self.session.exception(
                    ExceptionLevels.ERROR,
                    "services",
                    f"error stopping service {service.name}: {e.stderr}",
                    node.id,
                )
                logging.exception("error running stop command %s", args)
                status = -1
        return status
Exemplo n.º 25
0
    def movenode(self, node: CoreNode, dt: float) -> bool:
        """
        Calculate next node location and update its coordinates.
        Returns True if the node's position has changed.

        :param node: node to move
        :param dt: move factor
        :return: True if node was moved, False otherwise
        """
        if node.id not in self.points:
            return False
        x1, y1, z1 = node.getposition()
        x2, y2, z2 = self.points[node.id].coords
        speed = self.points[node.id].speed
        # instantaneous move (prevents dx/dy == 0.0 below)
        if speed == 0:
            self.setnodeposition(node, x2, y2, z2)
            del self.points[node.id]
            return True
        # speed can be a velocity vector or speed value
        if isinstance(speed, (float, int)):
            # linear speed value
            alpha = math.atan2(y2 - y1, x2 - x1)
            sx = speed * math.cos(alpha)
            sy = speed * math.sin(alpha)
        else:
            # velocity vector
            sx = speed[0]
            sy = speed[1]

        # calculate dt * speed = distance moved
        dx = sx * dt
        dy = sy * dt
        # prevent overshoot
        if abs(dx) > abs(x2 - x1):
            dx = x2 - x1
        if abs(dy) > abs(y2 - y1):
            dy = y2 - y1
        if dx == 0.0 and dy == 0.0:
            if self.endtime < (self.lasttime - self.timezero):
                # the last node to reach the last waypoint determines this
                # script's endtime
                self.endtime = self.lasttime - self.timezero
            del self.points[node.id]
            return False
        if (x1 + dx) < 0.0:
            dx = 0.0 - x1
        if (y1 + dy) < 0.0:
            dy = 0.0 - y1
        self.setnodeposition(node, x1 + dx, y1 + dy, z1)
        return True
Exemplo n.º 26
0
 def generate_frr_config(cls, node: CoreNode) -> str:
     ifname = "eth0"
     for iface in node.get_ifaces():
         if iface.name != "lo":
             ifname = iface.name
             break
     cfg = "router mfea\n!\n"
     cfg += "router igmp\n!\n"
     cfg += "router pim\n"
     cfg += "  !ip pim rp-address 10.0.0.1\n"
     cfg += "  ip pim bsr-candidate %s\n" % ifname
     cfg += "  ip pim rp-candidate %s\n" % ifname
     cfg += "  !ip pim spt-threshold interval 10 bytes 80000\n"
     return cfg
Exemplo n.º 27
0
    def startup_service(
        self, node: CoreNode, service: "CoreService", wait: bool = False
    ) -> int:
        """
        Startup a node service.

        :param node: node to reconfigure service for
        :param service: service to reconfigure
        :param wait: determines if we should wait to validate startup
        :return: status of startup
        """
        cmds = service.startup
        if not service.custom:
            cmds = service.get_startup(node)

        status = 0
        for cmd in cmds:
            try:
                node.cmd(cmd, wait)
            except CoreCommandError:
                logging.exception("error starting command")
                status = -1
        return status
Exemplo n.º 28
0
 def generate_config(cls, node: CoreNode, filename: str) -> str:
     """
     Generate a script to invoke dhclient on all interfaces.
     """
     cfg = "#!/bin/sh\n"
     cfg += "# auto-generated by DHCPClient service (utility.py)\n"
     cfg += "# uncomment this mkdir line and symlink line to enable client-"
     cfg += "side DNS\n# resolution based on the DHCP server response.\n"
     cfg += "#mkdir -p /var/run/resolvconf/interface\n"
     for iface in node.get_ifaces(control=False):
         cfg += "#ln -s /var/run/resolvconf/interface/%s.dhclient" % iface.name
         cfg += " /var/run/resolvconf/resolv.conf\n"
         cfg += "/sbin/dhclient -nw -pf /var/run/dhclient-%s.pid" % iface.name
         cfg += " -lf /var/run/dhclient-%s.lease %s\n" % (iface.name, iface.name)
     return cfg
Exemplo n.º 29
0
 def generate_config(cls, node: CoreNode, filename: str) -> str:
     """
     Generate a startup script for MgenActor. Because mgenActor does not
     daemonize, it can cause problems in some situations when launched
     directly using vcmd.
     """
     cfg = "#!/bin/sh\n"
     cfg += "# auto-generated by nrl.py:MgenActor.generateconfig()\n"
     comments = ""
     cmd = "mgenBasicActor.py -n %s -a 0.0.0.0" % node.name
     ifaces = node.get_ifaces(control=False)
     if len(ifaces) == 0:
         return ""
     cfg += comments + cmd + " < /dev/null > /dev/null 2>&1 &\n\n"
     return cfg
Exemplo n.º 30
0
 def generate_config(cls, node: CoreNode, filename: str) -> str:
     routes = []
     ifaces = node.get_ifaces()
     if ifaces:
         iface = ifaces[0]
         for ip in iface.ips():
             net = ip.cidr
             if net.size > 1:
                 router = net[1]
                 routes.append(str(router))
     cfg = "#!/bin/sh\n"
     cfg += "# auto-generated by DefaultRoute service (utility.py)\n"
     for route in routes:
         cfg += f"ip route add default via {route}\n"
     return cfg