广播网络实验

实验内容:

1、实现节点广播的broadcast_packet函数

2、验证广播网络能够正常运行:从一个端节点ping另一个端节点

3、验证广播网络的效率:在three_nodes_bw.py进行iperf测量。 两种场景: H1: iperf client; H2, H3: servers H1: iperf server; H2, H3: clients

4、验证环形拓扑下节点广播会产生数据包环路。

本人的实验环境:

在Windows10物理机上装VirtualBox虚拟机,Ubuntu系统是22.04.3 LTS,python版本是2.7.18。

实验过程:

1、实现节点广播的broadcast_packet函数:
1
2
3
4
5
6
7
8
9
10
11
12
void broadcast_packet(iface_info_t *iface, const char *packet, int len)
{
// TODO: broadcast packet
fprintf(stdout, "TODO: broadcast packet.\n");
// 新增
iface_info_t *ifa;
list_for_each_entry(ifa, &instance->iface_list, list) {
if (ifa != iface) {
iface_send_packet(ifa, packet, len);
}
}
}

这里使用了 list_for_each_entry 函数来遍历接口链表,对于每个接口,如果它不是接收接口iface,则调用iface_send_packet函数将数据包发送到该接口。

2、验证广播网络能够正常运行:从一个端节点ping另一个端节点

首先安装安装mininet,使用第二个命令(python版本是2.7.18):

1
sudo apt install mininet

但是显示未找到mininet.topo,这里再使用命令:sudo python -m pip install mininet来安装mininet相关模块及其所有依赖项。

然后安装cmake和xterm:

1
2
sudo apt-get install xterm
sudo apt-get install cmake

在项目的根目录下运行make命令,生成一个hub执行文件:

img

接着运行three_nodes_bw.py文件,这里的python版本是2.7.18, 然后用命令xterm b1打开b1节点的终端:

img

在b1的终端输入./hub命令来执行hub文件:

img

然后回到Mininet终端,输入ping相关命令来测试三个主机之间是否能ping通,结果是ping通的:

h1 ping h2:

img

h2 ping h1:

img

h2 ping h3:

img

h3 ping h2:

img

h3 ping h1:

img

h1 ping h3:

img

3、验证广播网络的效率:在three_nodes_bw.py进行iperf测量。

两种场景: H1: iperf client; H2, H3: servers H1: iperf server; H2, H3: clients

先用xterm打开h1、h2、h3节点的终端。同时也要打开b1节点的终端,同样在b1节点上运行hub文件。然后在h1,h2,h3的终端上进行下面操作。

场景1:将h1作为客户端,h2和h3作为server端,测试带宽利用率

在h2和h3终端上输入iperf -s命令,这将在 h2 和 h3 节点上启动 iperf 服务器,等待客户端的连接。

img

img

然后在h1终端上分别输入:iperf -c 10.0.0.2 -t 60 和iperf -c 10.0.0.3 -t 60

表示在 h1 节点上运行 iperf 客户端,分别连接到 IP 地址为 10.0.0.2(也就是h2)的 iperf 服务器和 IP 地址为 10.0.0.3(也就是h3)的 iperf 服务器并进行为期一分钟的性能测试。在测试结束后,iperf 将输出带宽、延迟等性能信息。

连接h2服务器:

img

img

由图可知,带宽利用率大概为8.21/10*100% = 82.1%

连接h3服务器:

img

img

由图可知,带宽利用率大概为8.13/10*100% = 81.3%

场景2:将h1作为server端,h2和h3作为客户端,测试带宽利用率

在h1节点的终端输入命令:iperf -s,来启动 iperf 服务器,等待客户端的连接。

img

然后分别在h2和h3节点的终端输入命令iperf -c 10.0.0.1 -t 60,用于与h1的server端进行连接。

h2客户端连接h1 server端:

img

img

由图可知,带宽利用率大概为7.36/10*100% = 73.6%

h3客户端连接h1 server端:

img

img

由图可知,带宽利用率大概为7.55/10*100% = 75.5%

4、验证环形拓扑下节点广播会产生数据包环路。

创建如下环形网络拓扑:

三个Hub节点,b1, b2, b3,两两互联

两个主机节点,h1连接到b1,h2连接到b2

img

创建ring_topo.py文件,核心代码如下:

这里一开始注释写的中文,但由于这里我的ubuntu没有配ASCII相关环境,运行不了,所以这里没写中文注释。

ring_topo.py如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#!/usr/bin/python

from __future__ import print_function

import os
import sys
import glob

from mininet.topo import Topo
from mininet.net import Mininet
from mininet.link import TCLink
from mininet.cli import CLI

script_deps = [ 'ethtool' ]

def check_scripts():
dir = os.path.abspath(os.path.dirname(sys.argv[0]))

for fname in glob.glob(dir + '/' + 'scripts/*.sh'):
if not os.access(fname, os.X_OK):
print('%s should be set executable by using `chmod +x $script_name`' % (fname))
sys.exit(1)

for program in script_deps:
found = False
for path in os.environ['PATH'].split(os.pathsep):
exe_file = os.path.join(path, program)
if os.path.isfile(exe_file) and os.access(exe_file, os.X_OK):
found = True
break
if not found:
print('`%s` is required but missing. which could be installed via `apt` or `aptitude`' % (program))
sys.exit(2)

# Mininet will assign an IP address for each interface of a node
# automatically, but hub or switch does not need IP address.
def clearIP(n):
for iface in n.intfList():
n.cmd('ifconfig %s 0.0.0.0' % (iface))

class BroadcastTopo(Topo):
def build(self):
# add three hubs (b1, b2, b3)
b1 = self.addHost('b1')
b2 = self.addHost('b2')
b3 = self.addHost('b3')

# add two hosts (h1, h2)
h1 = self.addHost('h1')
h2 = self.addHost('h2')

# create a circular link
self.addLink(b1, b2, bw=10)
self.addLink(b2, b3, bw=10)
self.addLink(b3, b1, bw=10)

# link hosts to switches
self.addLink(h1, b1, bw=10)
self.addLink(h2, b2, bw=10)

if __name__ == '__main__':
check_scripts()

topo = BroadcastTopo()
net = Mininet(topo = topo, link = TCLink, controller = None)

h1, h2, b1, b2, b3 = net.get('h1', 'h2', 'b1', 'b2', 'b3')
h1.cmd('ifconfig h1-eth0 10.0.0.1/8')
h2.cmd('ifconfig h2-eth0 10.0.0.2/8')
clearIP(b1)
clearIP(b2)
clearIP(b3)

for h in [h1, h2, b1, b2, b3]:
h.cmd('./scripts/disable_offloading.sh')
h.cmd('./scripts/disable_ipv6.sh')

net.start()
CLI(net)
net.stop()

运行xterm h1 h2 b1 b2 b3命令打开它们的终端。

然后在b1,b2,b3上运行./hub文件,也就是将其设置为集线器。

img

然后在h1的终端上ping h2,命令为:ping 10.0.0.2 -c 4(或者ping -c 4 10.0.0.2),则b1 b2 b3的终端下面会不断地出现brodacast packet的提示。说明b1、b2、b3已经形成了一个环路并且环路已经打通。 (-c 4:这个选项表示发送4个ICMP请求消息。ping命令将发送4个请求到10.0.0.2,然后等待响应。)

img

h1显示结果:

img

另外:

可以用Wireshark工具来进行抓包,在商店安装Wireshark之后,需要在终端输入命令:sudo dpkg-reconfigure wireshark-common这是允许普通用户使用 Wireshark 使用和捕获数据包。

同样的操作,在h1终端输入命令:sudo wireshark 会打开Wireshark操作页面,在 Wireshark 界面的过滤器框中输入以下过滤器,以仅显示 ICMP 流量,然后回车,此时Wireshark就等待抓包了。

img

img

但是在终端中使用 sudo wireshark 启动 Wireshark 时,Wireshark 将在前台运行,并终端将被锁定,直到手动终止 Wireshark 或者按下 ctrl+c 中断。因此,一旦你启动 Wireshark,终端将被占用,也就是不能接着在这个h1终端输入ping命令了,需要另外打开一个终端窗口来执行其他命令。这时回到mininet终端再输入xterm h1,再打开另一个h1终端,用来输入ping 10.0.0.2 -c 4,这时Wireshark就会显示抓到的包了。可以看到⼀个ICMP数据包不断被转发。

img