mininet(三)简单的NAT实验
mininet(一)实验环境搭建
mininet(二)简单的路由实验
mininet(三)简单的NAT实验
本次实验拓扑图如下:
假设 Openvswitch switch1是一个带有NAT功能的路由器,H1 的IP地址为 192.168.1.10,MAC地址为:00:00:00:00:00:01, H2 的IP地址为 10.0.0.1 MAC 地址为 00:00:00:00:00:02。私有网络的默认网关为: 192.168.1.1。公网默认网关为: 10.0.0.2。 在H1发送IP报文给H2的时候首先会发送ARP报文查询192.168.1.1的MAC地址,需要OpenVswitch发送 ARP回复报文给H1,H1收到网关的MAC后会将报文发送给switch。
nat.py
#!/usr/bin/python
from mininet.net import Mininet
from mininet.node import Controller, RemoteController, OVSKernelSwitch
from mininet.link import Link, TCLink
from mininet.cli import CLI
from mininet.log import setLogLevel
def topology():
net = Mininet( controller=RemoteController, link=TCLink, switch=OVSKernelSwitch )
print "*** Creating nodes"
h1 = net.addHost( 'h1', mac='00:00:00:00:00:01', ip='192.168.1.10/24' )
h2 = net.addHost( 'h2', mac='00:00:00:00:00:02', ip='10.0.0.1/24' )
s1 = net.addSwitch( 's1', protocols='OpenFlow10', listenPort=6673)
c1 = net.addController( 'c1', ip='127.0.0.1', port=6633 )
print "*** Creating links"
net.addLink(h1, s1)
net.addLink(h2, s1)
print "*** Starting network"
net.build()
c1.start()
s1.start( [c1] )
print "*** Running CLI"
h1.cmd("ip route add default via 192.168.1.1 dev h1-eth0")
h2.cmd("ip route add default via 10.0.0.2 dev h2-eth0")
CLI( net )
print "*** Stopping network"
net.stop()
if __name__ == '__main__':
setLogLevel( 'info' )
topology()
mypox.py
#!/usr/bin/python
from pox.core import core
from pox.lib.addresses import IPAddr
from pox.lib.addresses import EthAddr
import pox.openflow.libopenflow_01 as of
from pox.lib.util import dpid_to_str, str_to_bool
from pox.lib.packet.arp import arp
from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST
log = core.getLogger()
#flow2:
switch2 = 0000000000000001
flow2msg = of.ofp_flow_mod(command=0) #add flow rules
flow2msg.cookie = 0
flow2msg.match.in_port = 1 # match in port,the index of the switch
flow2msg.match.dl_type = 0x0800 # match ipv4 protcol
flow2msg.match.nw_src = IPAddr("192.168.1.10") # match src ip 192.168.1.10
# ACTIONS---------------------------------
flow2out = of.ofp_action_output (port = 2)
flow2srcIP = of.ofp_action_nw_addr.set_src(IPAddr("10.0.0.2")) # set src ip to 10.0.0.2
flow2srcMAC = of.ofp_action_dl_addr.set_src(EthAddr("00:00:00:00:00:04")) # set src mac 00.**.04
flow2dstMAC = of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:02")) # set dst mac 00.**.01 host2
flow2msg.actions = [flow2srcIP, flow2srcMAC, flow2dstMAC, flow2out]
#flow3:
switch3 = 0000000000000001
flow3msg = of.ofp_flow_mod(command=0)#add flow rules
flow3msg.cookie = 0
flow3msg.match.in_port = 2 # match in port,the index of the switch
flow3msg.match.dl_type = 0x0800
flow3msg.match.nw_dst = IPAddr("10.0.0.2") # match dst ip 10.0.0.2
# ACTIONS---------------------------------
flow3out = of.ofp_action_output (port = 1)
flow3dstIP = of.ofp_action_nw_addr.set_dst(IPAddr("192.168.1.10")) # set dst ip to 192.168.1.10
flow3srcMAC = of.ofp_action_dl_addr.set_src(EthAddr("00:00:00:00:00:03")) # #set src mac to 00.**.03
flow3dstMAC = of.ofp_action_dl_addr.set_dst(EthAddr("00:00:00:00:00:01")) # set dst mac to 00.**.01
flow3msg.actions = [flow3dstIP, flow3srcMAC, flow3dstMAC, flow3out]
def install_flows():
log.info(" *** Installing static flows... ***")
# Push flows to switches
core.openflow.sendToDPID(switch2, flow2msg)
core.openflow.sendToDPID(switch3, flow3msg)
log.info(" *** Static flows installed. ***")
def _handle_ConnectionUp (event):
log.info("*** install flows ***")
install_flows()
def _handle_PacketIn (event):
#log.info("*** _handle_PacketIn... ***")
dpid = event.connection.dpid
inport = event.port
packet = event.parsed
if not packet.parsed:
log.warning("%i %i ignoring unparsed packet", dpid, inport)
return
a = packet.find('arp')
if not a: return
log.info("%s ARP %s %s => %s", dpid_to_str(dpid),
{arp.REQUEST:"request",arp.REPLY:"reply"}.get(a.opcode,
'op:%i' % (a.opcode,)), str(a.protosrc), str(a.protodst))
if a.prototype == arp.PROTO_TYPE_IP and a.hwtype == arp.HW_TYPE_ETHERNET and a.opcode == arp.REQUEST:
r = arp()
r.hwtype = a.hwtype
r.prototype = a.prototype
r.hwlen = a.hwlen
r.protolen = a.protolen
r.opcode = arp.REPLY
r.hwdst = a.hwsrc
r.protodst = a.protosrc
r.protosrc = a.protodst
if str(a.protodst)=="192.168.1.1":
r.hwsrc = EthAddr("00:00:00:00:00:03")
if str(a.protodst)=="10.0.0.2":
r.hwsrc = EthAddr("00:00:00:00:00:04")
e = ethernet(type=packet.type, src=r.hwsrc,
dst=a.hwsrc)
e.payload = r
log.info("%s answering ARP for %s" % (dpid_to_str(dpid),
str(r.protosrc)))
msg = of.ofp_packet_out()
msg.data = e.pack()
msg.actions.append(of.ofp_action_output(port = of.OFPP_IN_PORT))
msg.in_port = inport
event.connection.send(msg)
def launch ():
log.info("*** Starting... ***")
log.info("*** Waiting for switches to connect.. ***")
core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp)
core.openflow.addListenerByName("PacketIn", _handle_PacketIn)
两条规则说明
1、从交换机1口进,并且源ip为 192.168.1.10,将报文的源ip修改为10.0.0.2,源mac修改为00:00:00:00:00:04,修改目的为00:00:00:00:00:02(主机h2的mac)
2、从交换机2口进,并且目的ip为10.0.0.2,将报文的目的ip修改为192.168.1.10,源mac修改为00:00:00:00:00:03,修改目的为00:00:00:00:00:01(主机h1的mac)
实验结果:
mininet@mininet-vm:~/pox$ ./pox.py mypox
POX 0.2.0 (carp) / Copyright 2011-2013 James McCauley, et al.
INFO:mypox:*** Starting... ***
INFO:mypox:*** Waiting for switches to connect.. ***
INFO:core:POX 0.2.0 (carp) is up.
INFO:openflow.of_01:[None 1] closed
INFO:openflow.of_01:[00-00-00-00-00-01 2] connected
INFO:mypox:*** install flows ***
INFO:mypox: *** Installing static flows... ***
INFO:mypox: *** Static flows installed. ***
INFO:openflow.of_01:[00-00-00-00-00-02 3] connected
INFO:mypox:*** install flows ***
INFO:mypox: *** Installing static flows... ***
INFO:mypox: *** Static flows installed. ***
INFO:mypox:00-00-00-00-00-01 ARP request 192.168.1.10 => 192.168.1.1
INFO:mypox:00-00-00-00-00-01 answering ARP for 192.168.1.1
INFO:mypox:00-00-00-00-00-01 ARP request 10.0.0.1 => 10.0.0.2
INFO:mypox:00-00-00-00-00-01 answering ARP for 10.0.0.2
mininet@mininet-vm:~$ sudo python nat.py
*** Creating nodes
*** Creating links
*** Starting network
*** Configuring hosts
h1 h2
*** Running CLI
*** Starting CLI:
mininet> h1 ping h2 -c 4
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=39.6 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.082 ms
64 bytes from 10.0.0.1: icmp_seq=3 ttl=64 time=0.063 ms
64 bytes from 10.0.0.1: icmp_seq=4 ttl=64 time=0.055 ms
--- 10.0.0.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3074ms
rtt min/avg/max/mdev = 0.055/9.960/39.643/17.137 ms
在h1上面抓包可以看到的是192.168.1.10 -> 10.0.0.1
在h2上面抓包可以看到的是 10.0.0.2 -> 10.0.0.1
mininet(三)简单的NAT实验的更多相关文章
- mininet(二)简单的路由实验
mininet(一)实验环境搭建 mininet(二)简单的路由实验 mininet(三)简单的NAT实验 在网上找了 好几个代码都是不能直接复现成功,这里把自己实现成功的代码给大家演示一下. 实验的 ...
- JSP学习笔记(三):简单的Tomcat Web服务器
注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...
- MySQL之单表查询 一 单表查询的语法 二 关键字的执行优先级(重点) 三 简单查询 四 WHERE约束 五 分组查询:GROUP BY 六 HAVING过滤 七 查询排序:ORDER BY 八 限制查询的记录数:LIMIT 九 使用正则表达式查询
MySQL之单表查询 阅读目录 一 单表查询的语法 二 关键字的执行优先级(重点) 三 简单查询 四 WHERE约束 五 分组查询:GROUP BY 六 HAVING过滤 七 查询排序:ORDER B ...
- BeagleBone Black板第四课:简单LED控制实验
BBB板第四课:简单LED控制实验 学习BBB板的终于目的是想像单片机一样做控制,但控制思路全然不一样(Linux下控制硬件设备实质就是对相关设备虚拟文件的读写).研究了几天头都大了还是没有进展,网上 ...
- JAVA WEB学习笔记(三):简单的基于Tomcat的Web页面
注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...
- grpc使用记录(三)简单异步服务实例
目录 grpc使用记录(三)简单异步服务实例 1.编写proto文件,定义服务 2.编译proto文件,生成代码 3.编写服务端代码 async_service.cpp async_service2. ...
- Java实验项目三——简单工厂模式
Program: 请采用采用简单工厂设计模式,为某个汽车销售店设计汽车销售系统,接口car至少有方法print(), 三个汽车类:宝马.奥迪.大众 (属性:品牌,价格),在测试类中根据客户要求购买的汽 ...
- Mininet系列实验(六):Mininet动态改变转发规则实验
一. 实验目的 熟悉Mininet自定义拓扑脚本的编写:熟悉编写POX脚本动态改变转发规则 二.实验原理 在SDN环境中,控制器可以通过对交换机下发流表操作来控制交换机的转发行为.在本实验中,基于Mi ...
- CCNP第三天 EIGRP综合实验
实验题如图所示:其中R2连R3 R5为快速以太网线,其他均为串线,帧中继默认是富曼斯(全连网状结构),即所有接入的路由之间的PVC都已经打通,所有 要关闭R5和R8的逆向arp功能,来手工配置R5到 ...
随机推荐
- 今天做一个项目的时候,要在一个编辑的jsp页面的textarea标签设置value属性,结果发现他没有value属性,但是是编辑页面又必须要回显要修改的内容,所以在参考了w3cschool之后很轻松的解决了这个问题。
今天做一个项目的时候,要在一个编辑的jsp页面的textarea标签设置value属性,结果发现他没有value属性,但是是编辑页面又必须要回显要修改的内容,所以在参考了w3cschool之后很轻松的 ...
- pat 1120 Friend Numbers(20 分)
1120 Friend Numbers(20 分) Two integers are called "friend numbers" if they share the same ...
- go中的关键字-defer
1. defer的使用 defer 延迟调用.我们先来看一下,有defer关键字的代码执行顺序: func main() { defer func() { fmt.Println("1号输出 ...
- SIGCHLD waitpid, 小心子进程结束事件被偷了
原本项目中依赖子进程执行的地方,都使用jni调用java层的ProcessManager,换了c++ACE框架后,发现这些任务都很慢,调试才发现所有子进程执行的任务都必须等待到reactor超时才返回 ...
- PostGIS 安装教程(Linux)(二)
##接上篇,上篇讲述了Postgresql的安装,此篇介绍postgis的安装 ##附上上篇链接:https://www.cnblogs.com/giser-s/p/11195419.html 二.安 ...
- 扛把子组2018092609-2 选题 Scrum立会报告+燃尽图 06
此作业的要求参见[https://edu.cnblogs.com/campus/nenu/2019fall/homework/8681] 一.小组情况组长:迟俊文组员:宋晓丽 梁梦瑶 韩昊 刘信鹏队名 ...
- vscode + platformIO开发stm32f4
我的电脑环境 win10 vscode 1.36.1 vscode安装插件 安装完这个插件后会提示你安装 platformIOCore,按照提示安装即可.安装过程可能比较缓慢, 可能需要翻墙. 新建项 ...
- 【日常错误】Could not initialize class org.hibernate.validator.internal.engine.ConfigurationImpl
最近在用spring-boot编写一个Lucene项目,中间用到了redis,引用了spring-boot-starter-data-redis,在eclipse中用外部Tomcat启动项目一切正常, ...
- php 开山篇
由韩顺平老师讲解的 php课程体系 初级课程只能是静态页面开发,不能动态的使用,只是一个界面 学完之后脑海中 应该有的体系~
- 爬虫框架Scrapy入门——爬取acg12某页面
1.安装1.1自行安装python3环境1.2ide使用pycharm1.3安装scrapy框架2.入门案例2.1新建项目工程2.2配置settings文件2.3新建爬虫app新建app将start_ ...