コード例 #1
0
ファイル: install.py プロジェクト: dhondta/rpl-attacks
def modify_rpl_debug(contiki_dir):
    """
    This function checks and modifies, if necessary, the DEBUG constant in
     [CONTIKI]/core/net/ipv6/uip-ds6-route.c in order to enable mote relationships logging.
     This is required for the script.js used in Cooja simulations to catch relationships
     evolution and to plot the sensor network in an animated GIF.

    :param contiki_dir: Contiki's directory
    :return: None
    """
    pattern = '#define DEBUG DEBUG_NONE'
    for module, descr in zip([('ipv6', 'uip-ds6-route.c'), ('rpl', 'rpl.c')], ["IPv6", "RPL"]):
        filepath = join(contiki_dir, 'core', 'net', *module)
        changed = False
        with open(filepath) as f:
            source = f.read()
        buffer = []
        for line in source.split('\n'):
            if pattern in line:
                buffer.append(line.replace(pattern, '#define DEBUG DEBUG_ANNOTATE'))
                changed = True
            else:
                buffer.append(line)
        with open(filepath, 'w') as f:
            f.write('\n'.join(buffer))
        logger.debug((" > {} debug modified" if changed else " > {} debug already up-to-date").format(descr))
コード例 #2
0
ファイル: commands.py プロジェクト: bahmadh/rpl-attacks
def __run(name, **kwargs):
    """
    Run an experiment.

    :param name: experiment name
    :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand'
    """
    path = kwargs['path']
    check_structure(path, remove=True)
    with hide(*HIDDEN_ALL):
        for sim in ["without", "with"]:
            sim_path = join(path, "{}-malicious".format(sim))
            data, results = join(sim_path, 'data'), join(sim_path, 'results')
            # the Makefile is at experiment's root ('path')
            with lcd(sim_path):
                logger.debug(" > Running simulation {} the malicious mote...".format(sim))
                local("make run", capture=True)
            # simulations are in their respective folders ('sim_path')
            remove_files(sim_path, 'COOJA.log', 'COOJA.testlog')
            # once the execution is over, gather the screenshots into a single GIF and keep the first and
            #  the last screenshots ; move these to the results folder
            with lcd(data):
                local('convert -delay 10 -loop 0 network*.png wsn-{}-malicious.gif'.format(sim))
            network_images = {int(fn.split('.')[0].split('_')[-1]): fn for fn in listdir(data)
                              if fn.startswith('network_')}
            move_files(data, results, 'wsn-{}-malicious.gif'.format(sim))
            net_start_old = network_images[min(network_images.keys())]
            net_start, ext = splitext(net_start_old)
            net_start_new = 'wsn-{}-malicious_start{}'.format(sim, ext)
            net_end_old = network_images[max(network_images.keys())]
            net_end, ext = splitext(net_end_old)
            net_end_new = 'wsn-{}-malicious_end{}'.format(sim, ext)
            move_files(data, results, (net_start_old, net_start_new), (net_end_old, net_end_new))
            remove_files(data, *network_images.values())
            parsing_chain(sim_path)
コード例 #3
0
def modify_rpl_debug(contiki_dir):
    """
    This function checks and modifies, if necessary, the DEBUG constant in
     [CONTIKI]/core/net/ipv6/uip-ds6-route.c in order to enable mote relationships logging.
     This is required for the script.js used in Cooja simulations to catch relationships
     evolution and to plot the sensor network in an animated GIF.

    :param contiki_dir: Contiki's directory
    :return: None
    """
    pattern = '#define DEBUG DEBUG_NONE'
    for module, descr in zip([('ipv6', 'uip-ds6-route.c'), ('rpl', 'rpl.c')],
                             ["IPv6", "RPL"]):
        filepath = join(contiki_dir, 'core', 'net', *module)
        changed = False
        with open(filepath) as f:
            source = f.read()
        buffer = []
        for line in source.split('\n'):
            if pattern in line:
                buffer.append(
                    line.replace(pattern, '#define DEBUG DEBUG_ANNOTATE'))
                changed = True
            else:
                buffer.append(line)
        with open(filepath, 'w') as f:
            f.write('\n'.join(buffer))
        logger.debug((" > {} debug modified" if changed else
                      " > {} debug already up-to-date").format(descr))
コード例 #4
0
def modify_cooja(cooja_dir):
    """
    This function inserts a block in the IF statement for parsing Cooja's input arguments.
    It searches for the IF statement pattern containing the '-nogui' case and inserts
     an IF block for a new '-hidden' case (aimed to run a simulation with the GUI hidden).

    :param cooja_dir: Cooja's directory
    :return: None
    """
    pattern = 'if (args.length > 0 && args[0].startsWith("-nogui="))'
    cooja_file = join(cooja_dir, 'java', 'org', 'contikios', 'cooja',
                      'Cooja.java')
    changed = False
    with open(cooja_file) as f:
        source = f.read()
    buffer = []
    for line in source.split('\n'):
        if pattern in line:
            with open('src/Cooja.java.snippet') as f:
                line = line.replace(
                    pattern, '{} else {}'.format(f.read().strip(), pattern))
            changed = True
        buffer.append(line)
    with open(cooja_file, 'w') as f:
        f.write('\n'.join(buffer))
    logger.debug(" > Cooja.java modified"
                 if changed else " > Cooja.java already up-to-date")
コード例 #5
0
ファイル: install.py プロジェクト: bahmadh/rpl-attacks
def update_cooja_build(cooja_dir):
    """
    This function adds a line for the 'visualizer_screenshot' plugin in the 'clean' and 'jar' sections
     of Cooja's build.xml.

    :param cooja_dir: Cooja's directory
    :return: None
    """
    cooja_build = join(cooja_dir, 'build.xml')
    with open(cooja_build) as f:
        source = f.read()
    buffer, tmp, is_in_jar_block, is_in_clean_block = [], [], False, False
    for line in source.split('\n'):
        if '<target name="clean" depends="init">' in line:
            is_in_clean_block = True
        elif '<target name="jar" depends="jar_cooja">' in line:
            is_in_jar_block = True
        if (is_in_clean_block or is_in_jar_block) and '"apps/visualizer_screenshot"' in line:
            return
        # if in 'clean' block, collect '<delete dir=...' lines in a buffer, add the required line then re-append buffer
        if is_in_clean_block and '</target>' in line:
            while buffer[-1].strip().startswith('<delete dir='):
                tmp.append(buffer.pop())
            buffer.append('    <ant antfile="build.xml" dir="apps/visualizer_screenshot"'
                          ' target="clean" inheritAll="false"/>')
            while len(tmp) > 0:
                buffer.append(tmp.pop())
        # if in 'jar' block, just put the required line at the end of the block
        elif is_in_jar_block and '</target>' in line:
            buffer.append('    <ant antfile="build.xml" dir="apps/visualizer_screenshot"'
                          ' target="jar" inheritAll="false"/>')
        buffer.append(line)
    with open(cooja_build, 'w') as f:
        f.write('\n'.join(buffer))
    logger.debug(" > Cooja's build.xml modified")
コード例 #6
0
def update(silent=False, **kwargs):
    """
    Update Contiki-OS and RPL Attacks Framework.
    """
    for folder, repository in zip([CONTIKI_FOLDER, FRAMEWORK_FOLDER],
                                  ["Contiki-OS", "RPL Attacks Framework"]):
        with hide(*HIDDEN_ALL):
            with lcd(folder):
                uptodate = "branch is up-to-date" in local(
                    'git checkout master',
                    capture=True).strip().split('\n')[-1]
                if not uptodate:
                    logger.warn(
                        "You are about to loose any custom change made to {} ;"
                        .format(repository))
                    if silent or std_input(
                            "Proceed anyway ? (yes|no) [default: no] ",
                            'yellow') == 'yes':
                        local('git submodule update --init')
                        local('git fetch --all')
                        local('git reset --hard origin/master')
                        local('git pull')
            logger.debug(" > {} {}".format(repository,
                                           ["updated",
                                            "already up-to-date"][uptodate]))
            if repository == "Contiki-OS" and not uptodate:
                setup(silent=True)
コード例 #7
0
 def wrapper(cmd, *args, **kwargs):
     out = f(cmd + ' 2>&1 /dev/null', *args, **kwargs)
     if out.return_code != 0:
         logger.critical(
             "Command '{}' returned error code {} with the following error:\n"
             .format(cmd, out.return_code) + '\n' + out)
         raise Exception("Command '{}' failed.".format(cmd))
     logger.debug(out)
コード例 #8
0
ファイル: behaviors.py プロジェクト: ycwuaa/rpl-attacks
 def __set_info(self, status, result=None, expires=True):
     logger.debug(' > Process {} is over.'.format(self))
     self.tasklist[self].update({
         'status':
         status,
         'result':
         result or self.tasklist[self]['result']
     })
     if expires:
         self.tasklist[self]['expires'] = datetime.now() + timedelta(
             seconds=TASK_EXPIRATION)
コード例 #9
0
ファイル: commands.py プロジェクト: bahmadh/rpl-attacks
def clean(name, ask=True, **kwargs):
    """
    Remove an experiment.

    :param name: experiment name (or absolute path to experiment)
    :param ask: ask confirmation
    """
    console = kwargs.get('console')
    if console is None or not any([i['name'] == name and i['status'] == 'PENDING' for i in console.tasklist.values()]):
        logger.debug(" > Cleaning folder...")
        with hide(*HIDDEN_ALL):
            local("rm -rf {}".format(kwargs['path']))
コード例 #10
0
def write_template(path, env, name, **kwargs):
    """
    This function fills in a markdown template and copy it to its destination.

    :param path: folder where the template is to be copied
    :param env: template environment
    :param name: template's key in the templates dictionary
    :param kwargs: parameters associated to this template
    """
    logger.debug(" > Setting template file: {}".format(name))
    template = env.get_template(name).render(**kwargs)
    with open(join(path, name), "w") as f:
        f.write(template)
コード例 #11
0
ファイル: rpla.py プロジェクト: dhondta/rpl-attacks
def write_template(path, env, name, **kwargs):
    """
    This function fills in a template and copy it to its destination.

    :param path: folder where the template is to be copied
    :param env: template environment
    :param name: template's key in the templates dictionary
    :param kwargs: parameters associated to this template
    """
    logger.debug(" > Setting template file: {}".format(name))
    template = env.get_template(name).render(**kwargs)
    with open(join(path, name), "w") as f:
        f.write(template)
コード例 #12
0
def apply_debug_flags(contiki, new_old_pair='NONE', logger=None):
    """
    This function replaces debug flags in ContikiRPL files.

    :param contiki_rpl: path to ContikiRPL custom library
    :param new_old_pair: the new value to be set for the debug flag
    """
    for filename in DEBUG_FILES:
        old_pattern = r'^#define DEBUG DEBUG_([A-Z]+)$'
        logger.debug(
            " > Replacing in {} where regex {} with new value: {}".format(
                filename, old_pattern, new_old_pair))
        replace_in_file(join(contiki, filename), (old_pattern, new_old_pair),
                        logger=logger)
コード例 #13
0
def clean(name, ask=True, **kwargs):
    """
    Remove an experiment.

    :param name: experiment name (or absolute path to experiment)
    :param ask: ask confirmation
    """
    console = kwargs.get('console')
    if console is None or not any([
            i['name'] == name and i['status'] == 'PENDING'
            for i in console.tasklist.values()
    ]):
        logger.debug(" > Cleaning folder...")
        with hide(*HIDDEN_ALL):
            local("rm -rf {}".format(kwargs['path']))
コード例 #14
0
ファイル: install.py プロジェクト: dhondta/rpl-attacks
def register_new_path_in_profile():
    """
    This function appends PATH adaptation to user's .profile for support of the last version of msp430-gcc.

    :return: None
    """
    msp430_path_adapted = False
    with open(expanduser('~/.profile')) as f:
        for line in f.readlines():
            if 'export PATH=/usr/local/msp430/bin:$PATH' in line:
                msp430_path_adapted = True
    if not msp430_path_adapted:
        with open(expanduser('~/.profile'), 'a') as f:
            f.write("\n\n# msp430-gcc (GCC) 4.6.3\n# export PATH=/usr/bin/msp430-gcc/bin:$PATH\n"
                    "# msp430-gcc (GCC) 4.7.0\nexport PATH=/usr/local/msp430/bin:$PATH")
    logger.debug(" > PATH adapted for msp430-gcc (GCC) 4.7.0 support")
コード例 #15
0
def register_new_path_in_profile():
    """
    This function appends PATH adaptation to user's .profile for support of the last version of msp430-gcc.

    :return: None
    """
    msp430_path_adapted = False
    with open(expanduser('~/.profile')) as f:
        for line in f.readlines():
            if 'export PATH=/usr/local/msp430/bin:$PATH' in line:
                msp430_path_adapted = True
    if not msp430_path_adapted:
        with open(expanduser('~/.profile'), 'a') as f:
            f.write(
                "\n\n# msp430-gcc (GCC) 4.6.3\n# export PATH=/usr/bin/msp430-gcc/bin:$PATH\n"
                "# msp430-gcc (GCC) 4.7.0\nexport PATH=/usr/local/msp430/bin:$PATH"
            )
    logger.debug(" > PATH adapted for msp430-gcc (GCC) 4.7.0 support")
コード例 #16
0
ファイル: commands.py プロジェクト: bahmadh/rpl-attacks
def __run(name, **kwargs):
    """
    Run an experiment.

    :param name: experiment name
    :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand'
    """
    path = kwargs['path']
    check_structure(path, remove=True)
    with hide(*HIDDEN_ALL):
        for sim in ["without", "with"]:
            sim_path = join(path, "{}-malicious".format(sim))
            data, results = join(sim_path, 'data'), join(sim_path, 'results')
            # the Makefile is at experiment's root ('path')
            with lcd(sim_path):
                logger.debug(
                    " > Running simulation {} the malicious mote...".format(
                        sim))
                local("make run", capture=True)
            # simulations are in their respective folders ('sim_path')
            remove_files(sim_path, 'COOJA.log', 'COOJA.testlog')
            # once the execution is over, gather the screenshots into a single GIF and keep the first and
            #  the last screenshots ; move these to the results folder
            with lcd(data):
                local(
                    'convert -delay 10 -loop 0 network*.png wsn-{}-malicious.gif'
                    .format(sim))
            network_images = {
                int(fn.split('.')[0].split('_')[-1]): fn
                for fn in listdir(data) if fn.startswith('network_')
            }
            move_files(data, results, 'wsn-{}-malicious.gif'.format(sim))
            net_start_old = network_images[min(network_images.keys())]
            net_start, ext = splitext(net_start_old)
            net_start_new = 'wsn-{}-malicious_start{}'.format(sim, ext)
            net_end_old = network_images[max(network_images.keys())]
            net_end, ext = splitext(net_end_old)
            net_end_new = 'wsn-{}-malicious_end{}'.format(sim, ext)
            move_files(data, results, (net_start_old, net_start_new),
                       (net_end_old, net_end_new))
            remove_files(data, *network_images.values())
            parsing_chain(sim_path)
コード例 #17
0
def update_cooja_build(cooja_dir):
    """
    This function adds a line for the 'visualizer_screenshot' plugin in the 'clean' and 'jar' sections
     of Cooja's build.xml.

    :param cooja_dir: Cooja's directory
    :return: None
    """
    cooja_build = join(cooja_dir, 'build.xml')
    with open(cooja_build) as f:
        source = f.read()
    buffer, tmp, is_in_jar_block, is_in_clean_block = [], [], False, False
    for line in source.split('\n'):
        if '<target name="clean" depends="init">' in line:
            is_in_clean_block = True
        elif '<target name="jar" depends="jar_cooja">' in line:
            is_in_jar_block = True
        if (is_in_clean_block
                or is_in_jar_block) and '"apps/visualizer_screenshot"' in line:
            return
        # if in 'clean' block, collect '<delete dir=...' lines in a buffer, add the required line then re-append buffer
        if is_in_clean_block and '</target>' in line:
            while buffer[-1].strip().startswith('<delete dir='):
                tmp.append(buffer.pop())
            buffer.append(
                '    <ant antfile="build.xml" dir="apps/visualizer_screenshot"'
                ' target="clean" inheritAll="false"/>')
            is_in_clean_block = False
            while len(tmp) > 0:
                buffer.append(tmp.pop())
        # if in 'jar' block, just put the required line at the end of the block
        elif is_in_jar_block and '</target>' in line:
            buffer.append(
                '    <ant antfile="build.xml" dir="apps/visualizer_screenshot"'
                ' target="jar" inheritAll="false"/>')
            is_in_jar_block = False
        buffer.append(line)
    with open(cooja_build, 'w') as f:
        f.write('\n'.join(buffer))
    logger.debug(" > Cooja's build.xml modified")
コード例 #18
0
ファイル: install.py プロジェクト: bahmadh/rpl-attacks
def modify_cooja(cooja_dir):
    """
    This function inserts a block in the IF statement for parsing Cooja's input arguments.
    It searches for the IF statement pattern containing the '-nogui' case and inserts
     an IF block for a new '-hidden' case (aimed to run a simulation with the GUI hidden).

    :param cooja_dir: Cooja's directory
    :return: None
    """
    pattern = 'if (args.length > 0 && args[0].startsWith("-nogui="))'
    cooja_file = join(cooja_dir, 'java', 'org', 'contikios', 'cooja', 'Cooja.java')
    with open(cooja_file) as f:
        source = f.read()
    buffer = []
    for line in source.split('\n'):
        if pattern in line:
            with open('src/Cooja.java.snippet') as f:
                line = line.replace(pattern, '{} else {}'.format(f.read().strip(), pattern))
        buffer.append(line)
    with open(cooja_file, 'w') as f:
        f.write('\n'.join(buffer))
    logger.debug(" > Cooja.java modified")
コード例 #19
0
ファイル: install.py プロジェクト: dhondta/rpl-attacks
def update_cooja_user_properties():
    """
    This function updates ~/.cooja.user.properties to include 'visualizer_screenshot' plugin

    :return: None
    """
    cooja_user_properties = join(expanduser('~'), '.cooja.user.properties')
    # if it does not exist, create it from 'src' folder's template
    if not exists(cooja_user_properties):
        with open('src/cooja-user-properties') as tf:
            with open(cooja_user_properties, 'w') as nf:
                nf.write(tf.read())
        logger.debug(" > Cooja user properties created")
        return
    # if it exists, append plugin's reference inside
    with open(cooja_user_properties) as f:
        source = f.read()
    buffer, plugin_appended = [], False
    for line in source.split('\n'):
        if line.startswith('DEFAULT_PROJECTDIRS='):
            if '[APPS_DIR]/visualizer_screenshot' in line:
                return
            else:
                plugin_appended = True
                line += ';[APPS_DIR]/visualizer_screenshot'
        buffer.append(line)
    # if the line with the correct constant name was not found, create it from 'src' folder's template
    if not plugin_appended:
        with open('src/cooja-user-properties') as f:
            for line in f.readlines():
                if 'DEFAULT_PROJECTDIRS=' in line:
                    buffer.append(line)
                    break
    # then write the modified .cooja.user.properties
    with open(cooja_user_properties, 'w') as f:
        f.write('\n'.join(buffer))
    logger.debug(" > Cooja user properties modified")
コード例 #20
0
def update_cooja_user_properties():
    """
    This function updates ~/.cooja.user.properties to include 'visualizer_screenshot' plugin

    :return: None
    """
    cooja_user_properties = join(expanduser('~'), '.cooja.user.properties')
    # if it does not exist, create it from 'src' folder's template
    if not exists(cooja_user_properties):
        with open('src/cooja-user-properties') as tf:
            with open(cooja_user_properties, 'w') as nf:
                nf.write(tf.read())
        logger.debug(" > Cooja user properties created")
        return
    # if it exists, append plugin's reference inside
    with open(cooja_user_properties) as f:
        source = f.read()
    buffer, plugin_appended = [], False
    for line in source.split('\n'):
        if line.startswith('DEFAULT_PROJECTDIRS='):
            if '[APPS_DIR]/visualizer_screenshot' in line:
                return
            else:
                plugin_appended = True
                line += ';[APPS_DIR]/visualizer_screenshot'
        buffer.append(line)
    # if the line with the correct constant name was not found, create it from 'src' folder's template
    if not plugin_appended:
        with open('src/cooja-user-properties') as f:
            for line in f.readlines():
                if 'DEFAULT_PROJECTDIRS=' in line:
                    buffer.append(line)
                    break
    # then write the modified .cooja.user.properties
    with open(cooja_user_properties, 'w') as f:
        f.write('\n'.join(buffer))
    logger.debug(" > Cooja user properties modified")
コード例 #21
0
ファイル: commands.py プロジェクト: bahmadh/rpl-attacks
def __remake(name, build=False, **kwargs):
    """
    Remake the malicious mote of an experiment.
     (meaning that it lets all simulation's files unchanged except ./motes/malicious.[target])

    :param name: experiment name
    :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand'
    """
    path = kwargs['path']
    logger.debug(" > Retrieving parameters...")
    params = read_config(path)
    ext_lib = params.get("ext_lib")
    if ext_lib and not exists(ext_lib):
        logger.error("External library does not exist !")
        logger.critical("Make aborted.")
        return False
    logger.debug(" > Recompiling malicious mote...")
    # remove former compiled malicious mote and prepare the template
    templates = get_path(path, 'templates', create=True)
    get_path(templates, 'motes', create=True)
    copy_files((TEMPLATES_FOLDER, 'experiment'), templates,
               ('motes/{}.c'.format(params["mtype_malicious"]), 'motes/malicious.c'))
    # recreate malicious C file from template and clean the temporary template
    replacements = render_templates(path, only_malicious=True, **params)
    # then clean the temporary folder with templates
    remove_folder(templates)
    # now recompile
    with settings(hide(*HIDDEN_ALL), warn_only=True):
        with_malicious = join(path, 'with-malicious', 'motes')
        without_malicious = join(path, 'without-malicious', 'motes')
        contiki = join(with_malicious, 'contiki')
        contiki_rpl = join(contiki, 'core', 'net', 'rpl')
        with lcd(with_malicious):
            malicious = 'malicious.{}'.format(params["malicious_target"])
            croot, csensor = 'root.{}'.format(params["target"]), 'sensor.{}'.format(params["target"])
            # handle the malicious mote recompilation
            copy_folder(CONTIKI_FOLDER, with_malicious, includes=get_contiki_includes(params["malicious_target"]))
            if ext_lib is not None:
                remove_folder(contiki_rpl)
                copy_folder(ext_lib, contiki_rpl)
            apply_replacements(contiki_rpl, replacements)
            logger.debug(" > Making '{}'...".format(malicious))
            stderr(local)("make malicious{} CONTIKI={}"
                          .format(['', '.upload'][build], contiki), capture=True)
            if build:
                build = get_path(path, 'build', create=True)
                move_files(with_malicious, build, 'tmpimage.ihex')
                copy_files(with_malicious, build, malicious)
            move_files(with_malicious, without_malicious, malicious)
            local('make clean')
            remove_files(with_malicious, 'malicious.c')
            move_files(without_malicious, with_malicious, malicious)
            copy_files(without_malicious, with_malicious, croot, csensor)
            remove_folder(contiki)
コード例 #22
0
def render_templates(path, only_malicious=False, **params):
    """
    This function is aimed to adapt and render the base templates dictionary with provided parameters.

    :param path: experiment folder path
    :param only_malicious: flag to indicate if all the templates have to be deployed or only malicious' one
    :param params: dictionary with all the parameters for the experiment
    :return: eventual replacements to be made in ContikiRPL files
    """
    templates = deepcopy(TEMPLATES)
    env = Environment(loader=FileSystemLoader(join(path, 'templates')))
    # fill in the different templates with input parameters
    constants, replacements = get_constants_and_replacements(params["blocks"])
    templates["motes/malicious.c"]["constants"] = "\n".join(
        ["#define {} {}".format(*c) for c in constants.items()])
    if only_malicious:
        template_malicious = "motes/malicious.c"
        write_template(join(path, "with-malicious"), env, template_malicious,
                       **templates[template_malicious])
        return replacements
    # generate the list of motes (first one is the root, last one is the malicious mote)
    motes = params['motes'] or eval(params["wsn_gen_algo"])(defaults=DEFAULTS,
                                                            **params)
    # fill in simulation file templates
    templates["report.md"] = deepcopy(params)
    templates["motes/Makefile"]["target"] = params["target"]
    # important note: timeout is milliseconds in the simulation script
    templates["script.js"]["timeout"] = 1000 * params["duration"]
    # important note: sampling period is relative to the measured time in the simulation, which is in microseconds ;
    #                  the '10 * ' thus means that we take 100 measures regardless the duration of the simulation
    templates["script.js"][
        "sampling_period"] = templates["script.js"]["timeout"] * 10
    templates["simulation.csc"][
        "title"] = params["title"] + ' (with the malicious mote)'
    templates["simulation.csc"]["goal"] = params["goal"]
    templates["simulation.csc"]["notes"] = params["notes"]
    templates["simulation.csc"]["interference_range"] = params["int_range"]
    templates["simulation.csc"]["transmitting_range"] = params["tx_range"]
    templates["simulation.csc"]["target"] = params["target"]
    templates["simulation.csc"]["target_capitalized"] = params[
        "target"].capitalize()
    templates["simulation.csc"]["malicious_target"] = params[
        "malicious_target"]
    templates["simulation.csc"]["malicious_target_capitalized"] = params[
        "malicious_target"].capitalize()
    logger.debug(" > Motes: {}".format(motes))
    templates["simulation.csc"]["motes"] = motes
    for mote_type in templates["simulation.csc"]["mote_types"]:
        mote_type["target"] = params["target"] if mote_type[
            "name"] != "malicious" else params["malicious_target"]
    # write to folder: render the templates for the simulation with the malicious mote
    for name, kwargs in templates.items():
        write_template(join(path, 'with-malicious'), env, name, **kwargs)
    # now, adapt the title and mote source template
    del templates["motes/Makefile"]
    del templates["motes/root.c"]
    del templates["motes/sensor.c"]
    del templates["motes/malicious.c"]
    templates["simulation.csc"][
        "title"] = params["title"] + ' (without the malicious mote)'
    templates["simulation.csc"]["motes"] = motes[:-1]
    del templates["simulation.csc"]["mote_types"][-1]
    # render the templates for the simulation without the malicious mote
    for name, kwargs in templates.items():
        write_template(join(path, 'without-malicious'), env, name, **kwargs)
    return replacements
コード例 #23
0
ファイル: behaviors.py プロジェクト: dhondta/rpl-attacks
 def __set_info(self, status, result=None, expires=True):
     if status != 'PENDING':
         logger.debug(' > Process {} is over.'.format(self))
     self.tasklist[self].update({'status': status, 'result': result or self.tasklist[self]['result']})
     if expires:
         self.tasklist[self]['expires'] = datetime.now() + timedelta(seconds=TASK_EXPIRATION)
コード例 #24
0
def __make(name, ask=True, **kwargs):
    """
    Make a new experiment.

    :param name: experiment name (or path to the experiment, if expanded in the 'command' decorator)
    :param ask: ask confirmation
    :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand'
    :param kwargs: simulation keyword arguments (see the documentation for more information)
    """
    global reuse_bin_path
    set_logging(kwargs.get('loglevel'))
    path = kwargs['path']
    logger.debug(" > Validating parameters...")
    params = validated_parameters(kwargs)
    ext_lib = params.get("ext_lib")
    if ext_lib and not exists(ext_lib):
        logger.error("External library does not exist !")
        logger.critical("Make aborded.")
        return False
    logger.debug(" > Creating simulation...")
    # create experiment's directories
    check_structure(path, create=True, remove=True)
    templates = get_path(path, 'templates', create=True)
    get_path(templates, 'motes', create=True)
    # select the right malicious mote template and duplicate the simulation file
    copy_files(
        (TEMPLATES_FOLDER, 'experiment'), templates,
        ('motes/{}.c'.format(params["mtype_root"]), 'motes/root.c'),
        ('motes/{}.c'.format(params["mtype_sensor"]), 'motes/sensor.c'),
        ('motes/{}.c'.format(params["mtype_malicious"]), 'motes/malicious.c'),
        'motes/Makefile', 'Makefile', 'simulation.csc', 'script.js')
    # create experiment's files from templates then clean the templates folder
    replacements = render_templates(path, **params)
    remove_folder(templates)
    # now, write the config file without the list of motes
    del params['motes']
    write_config(path, params)
    # now compile
    with settings(hide(*HIDDEN_ALL), warn_only=True):
        with_malicious = join(path, 'with-malicious', 'motes')
        without_malicious = join(path, 'without-malicious', 'motes')
        contiki = join(with_malicious, split(CONTIKI_FOLDER)[-1])
        contiki_rpl = join(contiki, 'core', 'net', 'rpl')
        # copy a reduced version of Contiki where the debug flags can be set for RPL files set in DEBUG_FILES
        copy_folder(CONTIKI_FOLDER,
                    with_malicious,
                    includes=get_contiki_includes(params["target"],
                                                  params["malicious_target"]))
        apply_debug_flags(contiki_rpl,
                          debug=['NONE', 'PRINT'][params["debug"]])
        with lcd(with_malicious):
            # first, compile root and sensor mote types
            croot, csensor = 'root.{}'.format(
                params["target"]), 'sensor.{}'.format(params["target"])
            if reuse_bin_path is None or reuse_bin_path == with_malicious:
                logger.debug(" > Making '{}'...".format(croot))
                stderr(local)("make root CONTIKI={}".format(contiki),
                              capture=True)
                logger.debug(" > Making '{}'...".format(csensor))
                stderr(local)("make sensor CONTIKI={}".format(contiki),
                              capture=True)
                # here, files are moved ; otherwise, 'make clean' would also remove *.z1
                move_files(with_malicious, without_malicious, croot, csensor)
                # after compiling, clean artifacts
                local('make clean')
                remove_files(with_malicious, 'root.c', 'sensor.c')
            else:
                copy_files(reuse_bin_path, without_malicious, croot, csensor)
            # second, handle the malicious mote compilation
            malicious = 'malicious.{}'.format(params["malicious_target"])
            if ext_lib is not None:
                remove_folder(contiki_rpl)
                copy_folder(ext_lib, contiki_rpl)
            apply_replacements(contiki_rpl, replacements)
            logger.debug(" > Making '{}'...".format(malicious))
            stderr(local)("make malicious CONTIKI={} TARGET={}".format(
                contiki, params["malicious_target"]),
                          capture=True)
            # temporary move compiled malicious mote, clean the compilation artifacts, move the malicious mote back
            #  from the temporary location and copy compiled root and sensor motes
            move_files(with_malicious, without_malicious, malicious)
            local('make clean')
            move_files(without_malicious, with_malicious, malicious)
            copy_files(without_malicious, with_malicious, croot, csensor)
            # finally, remove compilation sources
            remove_files(with_malicious, 'malicious.c')
            remove_folder(contiki)
コード例 #25
0
ファイル: commands.py プロジェクト: bahmadh/rpl-attacks
def setup(silent=False, **kwargs):
    """
    Setup the framework.
    """
    recompile = False
    # install Cooja modifications
    if not check_cooja(COOJA_FOLDER):
        logger.debug(" > Installing Cooja add-ons...")
        # modify Cooja.java and adapt build.xml and ~/.cooja.user.properties
        modify_cooja(COOJA_FOLDER)
        update_cooja_build(COOJA_FOLDER)
        update_cooja_user_properties()
        recompile = True
    # install VisualizerScreenshot plugin in Cooja
    visualizer = join(COOJA_FOLDER, 'apps', 'visualizer_screenshot')
    if not exists(visualizer):
        logger.debug(" > Installing VisualizerScreenshot Cooja plugin...")
        copy_folder('src/visualizer_screenshot', visualizer)
        recompile = True
    # recompile Cooja for making the changes take effect
    if recompile:
        with lcd(COOJA_FOLDER):
            logger.debug(" > Recompiling Cooja...")
            with settings(warn_only=True):
                local("ant clean")
                local("ant jar")
    else:
        logger.debug(" > Cooja is up-to-date")
    # install imagemagick
    with hide(*HIDDEN_ALL):
        imagemagick_apt_output = local('apt-cache policy imagemagick',
                                       capture=True)
        if 'Unable to locate package' in imagemagick_apt_output:
            logger.debug(" > Installing imagemagick package...")
            sudo("apt-get install imagemagick -y &")
        else:
            logger.debug(" > Imagemagick is installed")
    # install msp430 (GCC) upgrade
    with hide(*HIDDEN_ALL):
        msp430_version_output = local('msp430-gcc --version', capture=True)
    if 'msp430-gcc (GCC) 4.7.0 20120322' not in msp430_version_output:
        txt = "In order to extend msp430x memory support, it is necessary to upgrade msp430-gcc.\n" \
              "Would you like to upgrade it now ? (yes|no) [default: no] "
        answer = std_input(txt, 'yellow')
        if answer == "yes":
            logger.debug(
                " > Upgrading msp430-gcc from version 4.6.3 to 4.7.0...")
            logger.warning(
                "If you encounter problems with this upgrade, please refer to:\n"
                "https://github.com/contiki-os/contiki/wiki/MSP430X")
            with lcd('src/'):
                logger.warning(
                    " > Upgrade now starts, this may take up to 30 minutes...")
                sudo('./upgrade-msp430.sh')
                sudo('rm -r tmp/')
                local('export PATH=/usr/local/msp430/bin:$PATH')
                register_new_path_in_profile()
        else:
            logger.warning("Upgrade of library msp430-gcc aborted")
            logger.warning(
                "You may experience problems of mote memory size at compilation"
            )
    else:
        logger.debug(" > Library msp430-gcc is up-to-date (version 4.7.0)")
コード例 #26
0
def __remake(name, build=False, **kwargs):
    """
    Remake the malicious mote of an experiment.
     (meaning that it lets all simulation's files unchanged except ./motes/malicious.[target])

    :param name: experiment name
    :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand'
    """
    set_logging(kwargs.get('loglevel'))
    path = kwargs['path']
    logger.debug(" > Retrieving parameters...")
    params = read_config(path)
    ext_lib = params.get("ext_lib")
    if ext_lib and not exists(ext_lib):
        logger.error("External library does not exist !")
        logger.critical("Make aborted.")
        return False
    logger.debug(" > Recompiling malicious mote...")
    # remove former compiled malicious mote and prepare the template
    templates = get_path(path, 'templates', create=True)
    get_path(templates, 'motes', create=True)
    copy_files(
        (TEMPLATES_FOLDER, 'experiment'), templates,
        ('motes/{}.c'.format(params["mtype_malicious"]), 'motes/malicious.c'))
    # recreate malicious C file from template and clean the temporary template
    replacements = render_templates(path, only_malicious=True, **params)
    # then clean the temporary folder with templates
    remove_folder(templates)
    # now recompile
    with settings(hide(*HIDDEN_ALL), warn_only=True):
        with_malicious = join(path, 'with-malicious', 'motes')
        without_malicious = join(path, 'without-malicious', 'motes')
        contiki = join(with_malicious, split(CONTIKI_FOLDER)[-1])
        contiki_rpl = join(contiki, 'core', 'net', 'rpl')
        with lcd(with_malicious):
            malicious = 'malicious.{}'.format(params["malicious_target"])
            croot, csensor = 'root.{}'.format(
                params["target"]), 'sensor.{}'.format(params["target"])
            # handle the malicious mote recompilation
            copy_folder(CONTIKI_FOLDER,
                        with_malicious,
                        includes=get_contiki_includes(
                            params["malicious_target"]))
            if ext_lib is not None:
                remove_folder(contiki_rpl)
                copy_folder(ext_lib, contiki_rpl)
            apply_replacements(contiki_rpl, replacements)
            if build:
                logger.debug(" > Building '{}'...".format(malicious))
                stderr(local)(
                    "sudo make malicious.upload CONTIKI={} TARGET={}".format(
                        contiki, params["malicious_target"]))
                build = get_path(path, 'build', create=True)
                move_files(with_malicious, build, 'tmpimage.ihex')
                copy_files(with_malicious, build, malicious)
            else:
                logger.debug(" > Making '{}'...".format(malicious))
                stderr(local)("make malicious CONTIKI={} TARGET={}".format(
                    contiki, params["malicious_target"]),
                              capture=True)
            move_files(with_malicious, without_malicious, malicious)
            local('make clean')
            remove_files(with_malicious, 'malicious.c')
            move_files(without_malicious, with_malicious, malicious)
            copy_files(without_malicious, with_malicious, croot, csensor)
            remove_folder(contiki)
コード例 #27
0
def __run(name, **kwargs):
    """
    Run an experiment.

    :param name: experiment name
    :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand'
    """
    set_logging(kwargs.get('loglevel'))
    path = kwargs['path']
    check_structure(path, remove=True)
    with settings(hide(*HIDDEN_ALL), warn_only=True):
        for sim in ["without", "with"]:
            sim_path = join(path, "{}-malicious".format(sim))
            data, results = join(sim_path, 'data'), join(sim_path, 'results')
            # the Makefile is at experiment's root ('path')
            logger.debug(
                " > Running simulation {} the malicious mote...".format(sim))
            with lcd(sim_path):
                output = local("make run TASK={}".format(kwargs['task']),
                               capture=True)
            remove_files(sim_path, '.{}'.format(kwargs['task']))
            error, interrupt, error_buffer = False, False, []
            for line in output.split('\n'):
                if line.strip().startswith("FATAL") or line.strip().startswith(
                        "ERROR"):
                    error, interrupt = True, True
                elif line.strip().startswith("INFO"):
                    error = False
                    if len(error_buffer) > 0:
                        logger.error('Cooja error:\n' +
                                     '\n'.join(error_buffer))
                        error_buffer = []
                if error:
                    error_buffer.append(line)
            if interrupt:
                logger.warn(
                    "Cooja failed to execute ; 'run' interrupted (no parsing done)"
                )
                raise Exception("Cooja failed to execute")
            # once the execution is over, gather the screenshots into a single GIF and keep the first and
            #  the last screenshots ; move these to the results folder
            logger.debug(" > Gathering screenshots in an animated GIF...")
            with lcd(data):
                local(
                    'convert -delay 10 -loop 0 network*.png wsn-{}-malicious.gif'
                    .format(sim),
                    capture=True)
            network_images = {
                int(fn.split('.')[0].split('_')[-1]): fn
                for fn in listdir(data) if fn.startswith('network_')
            }
            move_files(data, results, 'wsn-{}-malicious.gif'.format(sim))
            net_start_old = network_images[min(network_images.keys())]
            net_start, ext = splitext(net_start_old)
            net_start_new = 'wsn-{}-malicious_start{}'.format(sim, ext)
            net_end_old = network_images[max(network_images.keys())]
            net_end, ext = splitext(net_end_old)
            net_end_new = 'wsn-{}-malicious_end{}'.format(sim, ext)
            move_files(data, results, (net_start_old, net_start_new),
                       (net_end_old, net_end_new))
            remove_files(data, *network_images.values())
            # then start the parsing functions to derive more results
            logger.debug(" > Parsing simulation results...")
            parsing_chain(sim_path)
            move_files(sim_path, results, 'COOJA.log')
コード例 #28
0
def setup(silent=False, **kwargs):
    """
    Setup the framework.
    """
    recompile = False
    # adapt IPv6 debug mode
    modify_ipv6_debug(CONTIKI_FOLDER)
    # install Cooja modifications
    if not check_cooja(COOJA_FOLDER):
        logger.debug(" > Installing Cooja add-ons...")
        # modify Cooja.java and adapt build.xml and ~/.cooja.user.properties
        modify_cooja(COOJA_FOLDER)
        update_cooja_build(COOJA_FOLDER)
        update_cooja_user_properties()
        recompile = True
    # install VisualizerScreenshot plugin in Cooja
    visualizer = join(COOJA_FOLDER, 'apps', 'visualizer_screenshot')
    if not exists(visualizer):
        logger.debug(" > Installing VisualizerScreenshot Cooja plugin...")
        copy_folder('src/visualizer_screenshot', visualizer)
        recompile = True
    # recompile Cooja for making the changes take effect
    if recompile:
        with lcd(CONTIKI_FOLDER):
            local('git submodule update --init')
        with lcd(COOJA_FOLDER):
            logger.debug(" > Recompiling Cooja...")
            with hide(*HIDDEN_ALL):
                for cmd in ["clean", "jar"]:
                    output = local("ant {}".format(cmd), capture=True)
                    info, error = False, False
                    for line in output.split('\n'):
                        if line.strip() == "":
                            info, error = False, False
                        elif line.startswith("BUILD"):
                            info, error = "SUCCESSFUL" in line, "FAILED" in line
                        if info or error:
                            getattr(
                                logger, "debug" if info else
                                "error" if error else "warn")(line)
    else:
        logger.debug(" > Cooja is up-to-date")
    # install imagemagick
    with hide(*HIDDEN_ALL):
        imagemagick_apt_output = local('apt-cache policy imagemagick',
                                       capture=True)
        if 'Unable to locate package' in imagemagick_apt_output:
            logger.debug(" > Installing imagemagick package...")
            local('sudo apt-get install imagemagick -y &')
        else:
            logger.debug(" > Imagemagick is installed")
    # install msp430 (GCC) upgrade
    with hide(*HIDDEN_ALL):
        msp430_version_output = local('msp430-gcc --version', capture=True)
    if 'msp430-gcc (GCC) 4.7.0 20120322' not in msp430_version_output:
        txt = "In order to extend msp430x memory support, it is necessary to upgrade msp430-gcc.\n" \
              "Would you like to upgrade it now ? (yes|no) [default: no] "
        if silent or std_input(txt, 'yellow') == "yes":
            logger.debug(
                " > Upgrading msp430-gcc from version 4.6.3 to 4.7.0...")
            logger.warning(
                "If you encounter problems with this upgrade, please refer to:\n"
                "https://github.com/contiki-os/contiki/wiki/MSP430X")
            with lcd('src/'):
                logger.warning(
                    " > Upgrade now starts, this may take up to 30 minutes...")
                local('sudo ./upgrade-msp430.sh')
                local('sudo rm -r tmp/')
                local('export PATH=/usr/local/msp430/bin:$PATH')
                register_new_path_in_profile()
        else:
            logger.warning("Upgrade of library msp430-gcc aborted")
            logger.warning(
                "You may experience problems of mote memory size at compilation"
            )
    else:
        logger.debug(" > Library msp430-gcc is up-to-date (version 4.7.0)")
    # create a new desktop shortcut for the framework
    desktop = expanduser('~/Desktop')
    shortcut = join(desktop, 'rpl-attacks-framework.desktop')
    if not exists(desktop):
        makedirs(desktop)
    if not exists(shortcut):
        with hide(*HIDDEN_ALL):
            local('sudo cp {} /usr/share/icons/hicolor/scalable/apps/'.format(
                join(FRAMEWORK_FOLDER, 'src/rpla-icon.svg')))
            local('sudo gtk-update-icon-cache /usr/share/icons/hicolor')
        with open(shortcut, 'w+') as f:
            f.write(SHORTCUT.format(path=FRAMEWORK_FOLDER))
        chmod(shortcut, int('775', 8))
        logger.debug(" > Desktop shortcut created")
    else:
        logger.debug(" > Desktop shortcut already exists")
コード例 #29
0
ファイル: commands.py プロジェクト: bahmadh/rpl-attacks
def __make(name, ask=True, **kwargs):
    """
    Make a new experiment.

    :param name: experiment name (or path to the experiment, if expanded in the 'command' decorator)
    :param ask: ask confirmation
    :param path: expanded path of the experiment (dynamically filled in through 'command' decorator with 'expand'
    :param kwargs: simulation keyword arguments (see the documentation for more information)
    """
    global reuse_bin_path
    path = kwargs['path']
    logger.debug(" > Validating parameters...")
    params = validated_parameters(kwargs)
    ext_lib = params.get("ext_lib")
    if ext_lib and not exists(ext_lib):
        logger.error("External library does not exist !")
        logger.critical("Make aborded.")
        return False
    logger.debug(" > Creating simulation...")
    # create experiment's directories
    check_structure(path, create=True, remove=True)
    templates = get_path(path, 'templates', create=True)
    get_path(templates, 'motes', create=True)
    # select the right malicious mote template and duplicate the simulation file
    copy_files((TEMPLATES_FOLDER, 'experiment'), templates,
               ('motes/{}.c'.format(params["mtype_root"]), 'motes/root.c'),
               ('motes/{}.c'.format(params["mtype_sensor"]), 'motes/sensor.c'),
               ('motes/{}.c'.format(params["mtype_malicious"]), 'motes/malicious.c'),
               'motes/Makefile', 'Makefile', 'simulation.csc', 'script.js')
    # create experiment's files from templates then clean the templates folder
    replacements = render_templates(path, **params)
    remove_folder(templates)
    # now, write the config file without the list of motes
    del params['motes']
    write_config(path, params)
    # now compile
    with settings(hide(*HIDDEN_ALL), warn_only=True):
        with_malicious = join(path, 'with-malicious', 'motes')
        without_malicious = join(path, 'without-malicious', 'motes')
        contiki = join(with_malicious, 'contiki')
        contiki_rpl = join(contiki, 'core', 'net', 'rpl')
        # copy a reduced version of Contiki where the debug flags can be set for RPL files set in DEBUG_FILES
        copy_folder(CONTIKI_FOLDER, with_malicious,
                    includes=get_contiki_includes(params["target"], params["malicious_target"]))
        apply_debug_flags(contiki_rpl, debug=['NONE', 'PRINT'][params["debug"]])
        with lcd(with_malicious):
            # first, compile root and sensor mote types
            croot, csensor = 'root.{}'.format(params["target"]), 'sensor.{}'.format(params["target"])
            if reuse_bin_path is None or reuse_bin_path == with_malicious:
                logger.debug(" > Making '{}'...".format(croot))
                stderr(local)("make root CONTIKI={}".format(contiki), capture=True)
                logger.debug(" > Making '{}'...".format(csensor))
                stderr(local)("make sensor CONTIKI={}".format(contiki), capture=True)
                # here, files are moved ; otherwise, 'make clean' would also remove *.z1
                move_files(with_malicious, without_malicious, croot, csensor)
                # after compiling, clean artifacts
                local('make clean')
                remove_files(with_malicious, 'root.c', 'sensor.c')
            else:
                copy_files(reuse_bin_path, without_malicious, croot, csensor)
            # second, handle the malicious mote compilation
            malicious = 'malicious.{}'.format(params["malicious_target"])
            if ext_lib is not None:
                remove_folder(contiki_rpl)
                copy_folder(ext_lib, contiki_rpl)
            apply_replacements(contiki_rpl, replacements)
            logger.debug(" > Making '{}'...".format(malicious))
            stderr(local)("make malicious CONTIKI={} TARGET={}"
                          .format(contiki, params["malicious_target"]), capture=True)
            # temporary move compiled malicious mote, clean the compilation artifacts, move the malicious mote back
            #  from the temporary location and copy compiled root and sensor motes
            move_files(with_malicious, without_malicious, malicious)
            local('make clean')
            move_files(without_malicious, with_malicious, malicious)
            copy_files(without_malicious, with_malicious, croot, csensor)
            # finally, remove compilation sources
            remove_files(with_malicious, 'malicious.c')
            remove_folder(contiki)
コード例 #30
0
ファイル: commands.py プロジェクト: bahmadh/rpl-attacks
def setup(silent=False, **kwargs):
    """
    Setup the framework.
    """
    recompile = False
    # install Cooja modifications
    if not check_cooja(COOJA_FOLDER):
        logger.debug(" > Installing Cooja add-ons...")
        # modify Cooja.java and adapt build.xml and ~/.cooja.user.properties
        modify_cooja(COOJA_FOLDER)
        update_cooja_build(COOJA_FOLDER)
        update_cooja_user_properties()
        recompile = True
    # install VisualizerScreenshot plugin in Cooja
    visualizer = join(COOJA_FOLDER, 'apps', 'visualizer_screenshot')
    if not exists(visualizer):
        logger.debug(" > Installing VisualizerScreenshot Cooja plugin...")
        copy_folder('src/visualizer_screenshot', visualizer)
        recompile = True
    # recompile Cooja for making the changes take effect
    if recompile:
        with lcd(COOJA_FOLDER):
            logger.debug(" > Recompiling Cooja...")
            with settings(warn_only=True):
                local("ant clean")
                local("ant jar")
    else:
        logger.debug(" > Cooja is up-to-date")
    # install imagemagick
    with hide(*HIDDEN_ALL):
        imagemagick_apt_output = local('apt-cache policy imagemagick', capture=True)
        if 'Unable to locate package' in imagemagick_apt_output:
            logger.debug(" > Installing imagemagick package...")
            sudo("apt-get install imagemagick -y &")
        else:
            logger.debug(" > Imagemagick is installed")
    # install msp430 (GCC) upgrade
    with hide(*HIDDEN_ALL):
        msp430_version_output = local('msp430-gcc --version', capture=True)
    if 'msp430-gcc (GCC) 4.7.0 20120322' not in msp430_version_output:
        txt = "In order to extend msp430x memory support, it is necessary to upgrade msp430-gcc.\n" \
              "Would you like to upgrade it now ? (yes|no) [default: no] "
        answer = std_input(txt, 'yellow')
        if answer == "yes":
            logger.debug(" > Upgrading msp430-gcc from version 4.6.3 to 4.7.0...")
            logger.warning("If you encounter problems with this upgrade, please refer to:\n"
                           "https://github.com/contiki-os/contiki/wiki/MSP430X")
            with lcd('src/'):
                logger.warning(" > Upgrade now starts, this may take up to 30 minutes...")
                sudo('./upgrade-msp430.sh')
                sudo('rm -r tmp/')
                local('export PATH=/usr/local/msp430/bin:$PATH')
                register_new_path_in_profile()
        else:
            logger.warning("Upgrade of library msp430-gcc aborted")
            logger.warning("You may experience problems of mote memory size at compilation")
    else:
        logger.debug(" > Library msp430-gcc is up-to-date (version 4.7.0)")