CORE Python API

原文链接:Python API


1. 概述

编写您自己的 Python 脚本提供了一个丰富的编程环境,可以完全控制仿真的所有方面。

脚本需要以 root 权限运行,因为它们会创建新的网络命名空间。通常,CORE Python 脚本不会连接到 CORE 守护程序,实际上,core-daemon 只是另一个使用 CORE Python 模块并与 GUI 交换消息的 Python 脚本。

2. 例子

2.1. 节点模型

创建 core.nodes.base.CoreNode 类型的节点时,这些是默认模型和它们映射到的服务。

  • mdr
    • zebra, OSPFv3MDR, IPForward
  • PC
    • DefaultRoute
  • router
    • zebra, OSPFv2, OSPFv3, IPForward
  • host
    • DefaultRoute, SSH

2.2. 接口助手

在为节点创建接口数据时,可以利用一个接口助手类来方便。或者,可以使用适当的信息手动创建 core.emulator.data.InterfaceData 类。

手动创建接口数据:

from core.emulator.data import InterfaceData
# id is optional and will set to the next available id
# name is optional and will default to eth<id>
# mac is optional and will result in a randomly generated mac
iface_data = InterfaceData(
    id=0,
    name="eth0",
    ip4="10.0.0.1",
    ip4_mask=24,
    ip6="2001::",
    ip6_mask=64,
)

利用接口前缀帮助器类:

from core.emulator.data import IpPrefixes

ip_prefixes = IpPrefixes(ip4_prefix="10.0.0.0/24", ip6_prefix="2001::/64")
# 2. node is used to get an ip4/ip6 address indexed from within the above prefixes
# 3. name is optional and would default to eth<id>
# 4. mac is optional and will result in a randomly generated mac
iface_data = ip_prefixes.create_iface(
    node=node, name="eth0", mac="00:00:00:00:aa:00"
)

2.3. 监听事件

可以监听会话中可能发生的各种事件。

事件类型:

  • session - 会话状态和移动性开始/停止/暂停变化的事件
  • node - 节点移动和图标更改的事件
  • link - 链接配置更改和无线链接添加/删除的事件
  • config - 旧版 gui 加入会话时的配置事件
  • exception - 警报/错误事件
  • file - 旧版 gui 加入会话时的文件事件
def event_listener(event):
    print(event)

# add an event listener to event type you want to listen to
# each handler will receive an object unique to that type
session.event_handlers.append(event_listener)
session.exception_handlers.append(event_listener)
session.node_handlers.append(event_listener)
session.link_handlers.append(event_listener)
session.file_handlers.append(event_listener)
session.config_handlers.append(event_listener)

2.4. 配置链接

链接可以在创建时或运行时进行配置。

当前支持的配置选项:

  • bandwidth (bps)
  • delay (us)
  • dup (%)
  • jitter (us)
  • loss (%)
from core.emulator.data import LinkOptions

# configuring when creating a link
options = LinkOptions(
    bandwidth=54_000_000,
    delay=5000,
    dup=5,
    loss=5.5,
    jitter=0,
)
session.add_link(n1_id, n2_id, iface1_data, iface2_data, options)

# configuring during runtime
session.update_link(n1_id, n2_id, iface1_id, iface2_id, options)

2.5. 点对点示例

# required imports
from core.emulator.coreemu import CoreEmu
from core.emulator.data import IpPrefixes, NodeOptions
from core.emulator.enumerations import EventTypes
from core.nodes.base import CoreNode

# ip nerator for example
ip_prefixes = IpPrefixes(ip4_prefix="10.0.0.0/24")

# create emulator instance for creating sessions and utility methods
coreemu = CoreEmu()
session = coreemu.create_session()

# must be in configuration state for nodes to start, when using "node_add" below
session.set_state(EventTypes.CONFIGURATION_STATE)

# create nodes
options = NodeOptions(x=100, y=100)
n1 = session.add_node(CoreNode, options=options)
options = NodeOptions(x=300, y=100)
n2 = session.add_node(CoreNode, options=options)

# link nodes together
iface1 = ip_prefixes.create_iface(n1)
iface2 = ip_prefixes.create_iface(n2)
session.add_link(n1.id, n2.id, iface1, iface2)

# start session
session.instantiate()

# do whatever you like here
input("press enter to shutdown")

# stop session
session.shutdown()

2.6. Switch/Hub 例子

# required imports
from core.emulator.coreemu import CoreEmu
from core.emulator.data import IpPrefixes, NodeOptions
from core.emulator.enumerations import EventTypes
from core.nodes.base import CoreNode
from core.nodes.network import SwitchNode

# ip nerator for example
ip_prefixes = IpPrefixes(ip4_prefix="10.0.0.0/24")

# create emulator instance for creating sessions and utility methods
coreemu = CoreEmu()
session = coreemu.create_session()

# must be in configuration state for nodes to start, when using "node_add" below
session.set_state(EventTypes.CONFIGURATION_STATE)

# create switch
options = NodeOptions(x=200, y=200)
switch = session.add_node(SwitchNode, options=options)

# create nodes
options = NodeOptions(x=100, y=100)
n1 = session.add_node(CoreNode, options=options)
options = NodeOptions(x=300, y=100)
n2 = session.add_node(CoreNode, options=options)

# link nodes to switch
iface1 = ip_prefixes.create_iface(n1)
session.add_link(n1.id, switch.id, iface1)
iface1 = ip_prefixes.create_iface(n2)
session.add_link(n2.id, switch.id, iface1)

# start session
session.instantiate()

# do whatever you like here
input("press enter to shutdown")

# stop session
session.shutdown()

2.7. WLAN 例子

# required imports
from core.emulator.coreemu import CoreEmu
from core.emulator.data import IpPrefixes, NodeOptions
from core.emulator.enumerations import EventTypes
from core.location.mobility import BasicRangeModel
from core.nodes.base import CoreNode
from core.nodes.network import WlanNode

# ip nerator for example
ip_prefixes = IpPrefixes(ip4_prefix="10.0.0.0/24")

# create emulator instance for creating sessions and utility methods
coreemu = CoreEmu()
session = coreemu.create_session()

# must be in configuration state for nodes to start, when using "node_add" below
session.set_state(EventTypes.CONFIGURATION_STATE)

# create wlan
options = NodeOptions(x=200, y=200)
wlan = session.add_node(WlanNode, options=options)

# create nodes
options = NodeOptions(model="mdr", x=100, y=100)
n1 = session.add_node(CoreNode, options=options)
options = NodeOptions(model="mdr", x=300, y=100)
n2 = session.add_node(CoreNode, options=options)

# configuring wlan
session.mobility.set_model_config(wlan.id, BasicRangeModel.name, {
    "range": "280",
    "bandwidth": "55000000",
    "delay": "6000",
    "jitter": "5",
    "error": "5",
})

# link nodes to wlan
iface1 = ip_prefixes.create_iface(n1)
session.add_link(n1.id, wlan.id, iface1)
iface1 = ip_prefixes.create_iface(n2)
session.add_link(n2.id, wlan.id, iface1)

# start session
session.instantiate()

# do whatever you like here
input("press enter to shutdown")

# stop session
session.shutdown()

2.8. EMANE 例子

对于 EMANE,您可以导入和使用现有模型之一,并使用其名称进行配置。

当前模型:

  • core.emane.ieee80211abg.EmaneIeee80211abgModel
  • core.emane.rfpipe.EmaneRfPipeModel
  • core.emane.tdma.EmaneTdmaModel
  • core.emane.bypass.EmaneBypassModel

它们的配置选项是从已安装的 EMANE 版本中解析的 EMANE 清单文件动态驱动的。

选项及其用途可以在 EMANE Wiki 中找到。

如果配置 EMANE 全局设置或模型 mac/phy 特定设置,任何未提供的值将使用默认值。当不使用配置时,使用默认值。

# required imports
from core.emane.ieee80211abg import EmaneIeee80211abgModel
from core.emane.nodes import EmaneNet
from core.emulator.coreemu import CoreEmu
from core.emulator.data import IpPrefixes, NodeOptions
from core.emulator.enumerations import EventTypes
from core.nodes.base import CoreNode

# ip nerator for example
ip_prefixes = IpPrefixes(ip4_prefix="10.0.0.0/24")

# create emulator instance for creating sessions and utility methods
coreemu = CoreEmu()
session = coreemu.create_session()

# location information is required to be set for emane
session.location.setrefgeo(47.57917, -122.13232, 2.0)
session.location.refscale = 150.0

# must be in configuration state for nodes to start, when using "node_add" below
session.set_state(EventTypes.CONFIGURATION_STATE)

# create emane
options = NodeOptions(x=200, y=200, emane=EmaneIeee80211abgModel.name)
emane = session.add_node(EmaneNet, options=options)

# create nodes
options = NodeOptions(model="mdr", x=100, y=100)
n1 = session.add_node(CoreNode, options=options)
options = NodeOptions(model="mdr", x=300, y=100)
n2 = session.add_node(CoreNode, options=options)

# configure general emane settings
config = session.emane.get_configs()
config.update({
    "eventservicettl": "2"
})

# configure emane model settings
# using a dict mapping currently support values as strings
session.emane.set_model_config(emane.id, EmaneIeee80211abgModel.name, {
    "unicastrate": "3",
})

# link nodes to emane
iface1 = ip_prefixes.create_iface(n1)
session.add_link(n1.id, emane.id, iface1)
iface1 = ip_prefixes.create_iface(n2)
session.add_link(n2.id, emane.id, iface1)

# start session
session.instantiate()

# do whatever you like here
input("press enter to shutdown")

# stop session
session.shutdown()

2.9. EMANE 模型配置

from core import utils

# emane network specific config
session.emane.set_model_config(emane.id, EmaneIeee80211abgModel.name, {
    "unicastrate": "3",
})

# node specific config
session.emane.set_model_config(node.id, EmaneIeee80211abgModel.name, {
    "unicastrate": "3",
})

# node interface specific config
config_id = utils.iface_config_id(node.id, iface_id)
session.emane.set_model_config(config_id, EmaneIeee80211abgModel.name, {
    "unicastrate": "3",
})

3. 配置一个服务

服务有助于在节点上生成和运行 bash 脚本以达到特定目的。

配置服务的文件会导致生成特定的硬编码脚本,而不是默认脚本,这可能会利用动态生成。

可以为服务配置以下功能:

  • configs - 将生成的文件
  • dirs - 将安装到节点唯一的目录
  • startup - 运行启动服务的命令
  • validate - 运行以验证服务的命令
    shutdown - 运行以停止服务的命令

编辑服务属性:

# configure a service, for a node, for a given session
session.services.set_service(node_id, service_name)
service = session.services.get_service(node_id, service_name)
service.configs = ("file1.sh", "file2.sh")
service.dirs = ("/etc/node",)
service.startup = ("bash file1.sh",)
service.validate = ()
service.shutdown = ()

编辑服务文件时,它必须是服务将生成的配置文件的名称。

编辑服务文件:

# to edit the contents of a generated file you can specify
# the service, the file name, and its contents
session.services.set_service_file(
    node_id,
    service_name,
    file_name,
    "echo hello",
)

4. 文件例子

可以在此处找到网络示例的文件版本。文件例子

5. 从 GUI 执行脚本

要从 GUI 执行 python 脚本,您需要具备以下条件。

此处的内置名称检查以了解它是从 GUI 执行的,如果您的脚本不使用名称检查,则可以避免这种情况。

if __name__ in ["__main__", "__builtin__"]:
    main()

脚本可以向 CORE 守护进程添加会话。全局 coreemu 变量暴露给指向 CoreEmu 对象的脚本。

下面的例子有一个新的 CoreEmu 对象的回退,如果你想在 CORE 守护程序之外独立运行脚本。

coreemu = globals().get("coreemu", CoreEmu())
session = coreemu.create_session()
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐